<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;
use yii\web\UploadedFile;
use yii\behaviors\TimestampBehavior;

/**
 * Class EmployeeProfile
 * @package app\models
 * 
 * @property int $id
 * @property int $user_id
 * @property string|null $photo
 * @property string|null $birth_date
 * @property string|null $gender
 * @property string|null $citizenship
 * @property string|null $passport_series
 * @property string|null $passport_number
 * @property string|null $passport_issued_by
 * @property string|null $passport_issue_date
 * @property string|null $passport_registration
 * @property string|null $passport_scan
 * @property string|null $marital_status
 * @property string|null $education
 * @property string|null $education_organization
 * @property string|null $specialty
 * @property string|null $qualification
 * @property string|null $diploma_number
 * @property string|null $diploma_scan
 * @property string|null $workplace
 * @property string|null $position
 * @property int|null $experience
 * @property string|null $snils
 * @property string|null $snils_scan
 * @property string|null $health_status
 * @property string|null $additional_info
 * @property string $status
 * @property int|null $reviewed_by
 * @property int|null $reviewed_at
 * @property string|null $review_comment
 * @property string $created_at
 * @property string $updated_at
 * 
 * @property User $user
 */
class EmployeeProfile extends ActiveRecord
{
    const STATUS_NEW = 'new';
    const STATUS_IN_REVIEW = 'in_review';
    const STATUS_ACCEPTED = 'accepted';
    
    const GENDER_MALE = 'male';
    const GENDER_FEMALE = 'female';
    
    const EDUCATION_BASIC = 'basic';
    const EDUCATION_SECONDARY = 'secondary';
    const EDUCATION_VOCATIONAL = 'vocational';
    const EDUCATION_HIGHER = 'higher';
    
    const MARITAL_SINGLE = 'single';
    const MARITAL_MARRIED = 'married';
    const MARITAL_DIVORCED = 'divorced';
    const MARITAL_WIDOWED = 'widowed';
    
    public $photoFile;
    public $passportScanFile;
    public $diplomaScanFile;
    public $snilsScanFile;

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%employee_profile}}';
    }

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            [
                'class' => TimestampBehavior::class,
                'createdAtAttribute' => 'created_at',
                'updatedAtAttribute' => 'updated_at',
                'value' => function() {
                    return date('Y-m-d H:i:s');
                },
            ],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['user_id'], 'required'],
            
            // Личные данные
            [['birth_date'], 'date', 'format' => 'php:Y-m-d'],
            ['gender', 'in', 'range' => [self::GENDER_MALE, self::GENDER_FEMALE]],
            ['citizenship', 'string', 'max' => 100],
            
            // Паспорт
            ['passport_series', 'string', 'max' => 10],
            ['passport_number', 'string', 'max' => 20],
            ['passport_issued_by', 'string', 'max' => 255],
            ['passport_issue_date', 'date', 'format' => 'php:Y-m-d'],
            ['passport_registration', 'string'],
            ['marital_status', 'in', 'range' => [self::MARITAL_SINGLE, self::MARITAL_MARRIED, self::MARITAL_DIVORCED, self::MARITAL_WIDOWED]],
            
            // Образование
            ['education', 'in', 'range' => [self::EDUCATION_BASIC, self::EDUCATION_SECONDARY, self::EDUCATION_VOCATIONAL, self::EDUCATION_HIGHER]],
            ['education_organization', 'string', 'max' => 255],
            ['specialty', 'string', 'max' => 255],
            ['qualification', 'string', 'max' => 255],
            ['diploma_number', 'string', 'max' => 100],
            
            // Работа
            ['workplace', 'string', 'max' => 255],
            ['position', 'string', 'max' => 255],
            ['experience', 'integer', 'min' => 0],
            
            // Прочие
            ['snils', 'string', 'max' => 20],
            ['health_status', 'string'],
            ['additional_info', 'string'],
            
            // Файлы
            [['photoFile'], 'file', 'skipOnEmpty' => true, 'extensions' => 'jpg, jpeg, png, pdf', 'maxSize' => 10*1024*1024],
            [['passportScanFile', 'diplomaScanFile'], 'file', 'skipOnEmpty' => true, 'extensions' => 'jpg, jpeg, png, pdf', 'maxSize' => 20*1024*1024],
            [['snilsScanFile'], 'file', 'skipOnEmpty' => true, 'extensions' => 'jpg, jpeg, png, pdf', 'maxSize' => 10*1024*1024],
            
            // Статус
            ['status', 'default', 'value' => self::STATUS_NEW],
            ['status', 'in', 'range' => [self::STATUS_NEW, self::STATUS_IN_REVIEW, self::STATUS_ACCEPTED]],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'user_id' => 'Пользователь',
            'photo' => 'Фото',
            'birth_date' => 'Дата рождения',
            'gender' => 'Пол',
            'citizenship' => 'Гражданство',
            'passport_series' => 'Серия паспорта',
            'passport_number' => 'Номер паспорта',
            'passport_issued_by' => 'Кем выдан',
            'passport_issue_date' => 'Дата выдачи',
            'passport_registration' => 'Адрес регистрации',
            'passport_scan' => 'Скан паспорта',
            'marital_status' => 'Семейное положение',
            'education' => 'Образование',
            'education_organization' => 'Образовательное учреждение',
            'specialty' => 'Специальность',
            'qualification' => 'Квалификация',
            'diploma_number' => 'Номер диплома',
            'diploma_scan' => 'Скан диплома',
            'workplace' => 'Место работы',
            'position' => 'Должность',
            'experience' => 'Стаж работы (месяцев)',
            'snils' => 'СНИЛС',
            'snils_scan' => 'Скан СНИЛС',
            'health_status' => 'Состояние здоровья',
            'additional_info' => 'Дополнительная информация',
            'status' => 'Статус',
            'reviewed_by' => 'Проверено',
            'reviewed_at' => 'Дата проверки',
            'review_comment' => 'Комментарий проверки',
            'created_at' => 'Создано',
            'updated_at' => 'Обновлено',
            
            // Файлы
            'photoFile' => 'Фото сотрудника',
            'passportScanFile' => 'Скан паспорта',
            'diplomaScanFile' => 'Скан диплома',
            'snilsScanFile' => 'Скан СНИЛС',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getUser()
    {
        return $this->hasOne(User::class, ['id' => 'user_id']);
    }

    /**
     * Загрузка файлов
     * @return bool
     */
    public function upload()
    {
        $basePath = Yii::getAlias('@webroot/uploads/');
        if (!file_exists($basePath)) {
            mkdir($basePath, 0777, true);
            mkdir($basePath . 'photos/', 0777, true);
            mkdir($basePath . 'passports/', 0777, true);
            mkdir($basePath . 'diplomas/', 0777, true);
            mkdir($basePath . 'snils/', 0777, true);
        }

        $saved = true;
        $userId = $this->user_id;
        
        if ($this->photoFile) {
            $fileName = 'photo_' . $userId . '_' . time() . '.' . $this->photoFile->extension;
            if ($this->photoFile->saveAs($basePath . 'photos/' . $fileName)) {
                $this->photo = 'photos/' . $fileName;
            } else {
                $saved = false;
            }
        }

        if ($this->passportScanFile) {
            $fileName = 'passport_' . $userId . '_' . time() . '.' . $this->passportScanFile->extension;
            if ($this->passportScanFile->saveAs($basePath . 'passports/' . $fileName)) {
                $this->passport_scan = 'passports/' . $fileName;
            } else {
                $saved = false;
            }
        }

        if ($this->diplomaScanFile) {
            $fileName = 'diploma_' . $userId . '_' . time() . '.' . $this->diplomaScanFile->extension;
            if ($this->diplomaScanFile->saveAs($basePath . 'diplomas/' . $fileName)) {
                $this->diploma_scan = 'diplomas/' . $fileName;
            } else {
                $saved = false;
            }
        }

        if ($this->snilsScanFile) {
            $fileName = 'snils_' . $userId . '_' . time() . '.' . $this->snilsScanFile->extension;
            if ($this->snilsScanFile->saveAs($basePath . 'snils/' . $fileName)) {
                $this->snils_scan = 'snils/' . $fileName;
            } else {
                $saved = false;
            }
        }

        return $saved;
    }

    /**
     * Получение списка статусов
     * @return array
     */
    public static function getStatusList()
    {
        return [
            self::STATUS_NEW => 'Новая',
            self::STATUS_IN_REVIEW => 'Идет проверка',
            self::STATUS_ACCEPTED => 'Принята',
        ];
    }

    /**
     * Получение названия статуса
     * @return string
     */
    public function getStatusName()
    {
        $list = self::getStatusList();
        return $list[$this->status] ?? $this->status;
    }

    /**
     * Получение списка полов
     * @return array
     */
    public static function getGenderList()
    {
        return [
            self::GENDER_MALE => 'Мужской',
            self::GENDER_FEMALE => 'Женский',
        ];
    }

    /**
     * Получение названия пола
     * @return string
     */
    public function getGenderName()
    {
        $list = self::getGenderList();
        return $list[$this->gender] ?? $this->gender;
    }

    /**
     * Получение списка образования
     * @return array
     */
    public static function getEducationList()
    {
        return [
            self::EDUCATION_BASIC => 'Основное общее',
            self::EDUCATION_SECONDARY => 'Среднее общее',
            self::EDUCATION_VOCATIONAL => 'Среднее профессиональное',
            self::EDUCATION_HIGHER => 'Высшее',
        ];
    }

    /**
     * Получение названия образования
     * @return string
     */
    public function getEducationName()
    {
        $list = self::getEducationList();
        return $list[$this->education] ?? $this->education;
    }

    /**
     * Получение списка семейных положений
     * @return array
     */
    public static function getMaritalStatusList()
    {
        return [
            self::MARITAL_SINGLE => 'Холост/Не замужем',
            self::MARITAL_MARRIED => 'Женат/Замужем',
            self::MARITAL_DIVORCED => 'Разведен(а)',
            self::MARITAL_WIDOWED => 'Вдовец/Вдова',
        ];
    }

    /**
     * Получение названия семейного положения
     * @return string
     */
    public function getMaritalStatusName()
    {
        $list = self::getMaritalStatusList();
        return $list[$this->marital_status] ?? $this->marital_status;
    }

    /**
     * Получение ссылки на файл
     * @param string $attribute
     * @return string|null
     */
    public function getFileUrl($attribute)
    {
        if ($this->$attribute) {
            return Yii::$app->request->baseUrl . '/uploads/' . $this->$attribute;
        }
        return null;
    }

    /**
     * Получение стажа в годах/месяцах
     * @return string
     */
    public function getExperienceFormatted()
    {
        if (!$this->experience) {
            return 'Не указано';
        }
        
        $years = floor($this->experience / 12);
        $months = $this->experience % 12;
        
        $result = [];
        if ($years > 0) {
            $result[] = $years . ' ' . $this->getNoun($years, ['год', 'года', 'лет']);
        }
        if ($months > 0) {
            $result[] = $months . ' ' . $this->getNoun($months, ['месяц', 'месяца', 'месяцев']);
        }
        
        return implode(' ', $result);
    }

    /**
     * Склонение существительных
     * @param int $number
     * @param array $titles
     * @return string
     */
    private function getNoun($number, $titles)
    {
        $cases = [2, 0, 1, 1, 1, 2];
        return $titles[($number % 100 > 4 && $number % 100 < 20) ? 2 : $cases[min($number % 10, 5)]];
    }
}