<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

/**
 * Class Application
 * @package app\models
 *
 * @property int $id
 * @property int $user_id
 * @property string $date
 * @property string $category
 * @property float $previous_readings
 * @property float $current_readings
 * @property float $consumption
 * @property float $tariff
 * @property float $amount
 * @property string $status
 * @property string $created_at
 * @property string $updated_at
 *
 * @property User $user
 */
class Application extends ActiveRecord
{
    const CATEGORY_ELECTRICITY = 'electricity';
    const CATEGORY_GAS = 'gas';
    const CATEGORY_WATER = 'water';

    const STATUS_NEW = 'new';
    const STATUS_ACCEPTED = 'accepted';
    const STATUS_ERROR = 'error';
    const STATUS_PENDING = 'pending';
    const STATUS_APPROVED = 'approved';
    const STATUS_REJECTED = 'rejected';

    public static function tableName()
    {
        return '{{%application}}';
    }

    public function rules()
    {
        return [
            [['user_id', 'date', 'category', 'previous_readings', 'current_readings'], 'required'],
            [['user_id'], 'integer'],
            [['date', 'created_at', 'updated_at'], 'safe'],
            [['previous_readings', 'current_readings', 'consumption', 'tariff', 'amount'], 'number'],
            [['category', 'status'], 'string', 'max' => 255],
            ['category', 'in', 'range' => [self::CATEGORY_ELECTRICITY, self::CATEGORY_GAS, self::CATEGORY_WATER]],
            ['status', 'in', 'range' => [self::STATUS_PENDING, self::STATUS_APPROVED, self::STATUS_REJECTED]],
            ['status', 'default', 'value' => self::STATUS_PENDING],
            [['current_readings'], 'validateReadings'],
        ];
    }

    public function validateReadings($attribute, $params)
    {
        if ($this->current_readings <= $this->previous_readings) {
            $this->addError($attribute, 'Текущие показания должны быть больше предыдущих.');
        }
    }

    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'user_id' => 'Пользователь',
            'date' => 'Дата передачи показаний',
            'category' => 'Категория услуг',
            'previous_readings' => 'Предыдущие показания',
            'current_readings' => 'Текущие показания',
            'consumption' => 'Расход',
            'tariff' => 'Тариф',
            'amount' => 'Сумма к оплате',
            'status' => 'Статус',
            'created_at' => 'Дата создания',
            'updated_at' => 'Дата обновления',
        ];
    }

    public function getUser()
    {
        return $this->hasOne(User::class, ['id' => 'user_id']);
    }

    public function getCategoryName()
    {
        $categories = self::getCategories();
        return $categories[$this->category] ?? $this->category;
    }

    public function getStatusName()
    {
        $statuses = self::getStatuses() + self::getAdminStatuses();
        return $statuses[$this->status] ?? $this->status;
    }

    public static function getCategories()
    {
        return [
            self::CATEGORY_ELECTRICITY => 'Электричество',
            self::CATEGORY_GAS => 'Газ',
            self::CATEGORY_WATER => 'Вода',
        ];
    }

    public static function getStatuses()
    {
        return [
            self::STATUS_PENDING => 'На рассмотрении',
            self::STATUS_APPROVED => 'Подтверждена',
            self::STATUS_REJECTED => 'Отклонена',
        ];
    }

    public static function getAdminStatuses()
    {
        return [
            self::STATUS_NEW => 'Новая',
            self::STATUS_ACCEPTED => 'Показания приняты',
            self::STATUS_ERROR => 'Ошибка в переданных показаниях',
        ];
    }

    public static function getTariff($category)
    {
        $tariffs = [
            self::CATEGORY_ELECTRICITY => 5.03,
            self::CATEGORY_GAS => 7.39,
            self::CATEGORY_WATER => 48.24,
        ];
        return $tariffs[$category] ?? 0;
    }

    public function calculate()
    {
        $this->consumption = $this->current_readings - $this->previous_readings;
        $this->tariff = self::getTariff($this->category);
        $this->amount = round($this->consumption * $this->tariff, 2);
    }

    public static function getLastReadings($userId, $category)
    {
        $lastApplication = self::find()
            ->where(['user_id' => $userId, 'category' => $category])
            ->orderBy(['date' => SORT_DESC])
            ->one();

        return $lastApplication ? $lastApplication->current_readings : 0;
    }

    public function getStatusClass()
    {
        $classes = [
            self::STATUS_NEW => 'bg-primary',
            self::STATUS_ACCEPTED => 'bg-success',
            self::STATUS_ERROR => 'bg-danger',
            self::STATUS_PENDING => 'bg-warning',
            self::STATUS_APPROVED => 'bg-success',
            self::STATUS_REJECTED => 'bg-danger',
        ];
        return $classes[$this->status] ?? 'bg-secondary';
    }
}
