<?php
namespace common\models\forms;

use common\helpers\Date;
use common\components\Model;
use common\helpers\Form;
use common\helpers\user\Info;
use common\libs\logging\operate\AdminOperate;
use common\models\EmployLevel;
use common\models\HighestEmpLevelLog;
use common\models\Period;
use common\models\User;
use Yii;
use yii\base\Exception;

/**
 * Login form
 */
class HighestEmpLevelLogForm extends Model
{
    public $userName;
    public $levelId;
    public $periodNum;
    public $remark;
    private $_userId;
    private $_fromId;

    public function init() {
        parent::init();
        $this->adminOperateLogger = new AdminOperate([
            'fetchClass' => User::class,
        ]);
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['userName', 'levelId', 'periodNum', 'remark'], 'trim'],
            [['userName', 'levelId', 'periodNum'], 'required'],
            [['userName'], 'exist', 'targetClass' => User::class, 'targetAttribute' => 'USER_NAME'],
            [['levelId'], 'exist', 'targetClass' => EmployLevel::class, 'targetAttribute' => 'ID'],
            [['userName'], 'isUser'],
            [['levelId'], 'isLevel'],
            [['periodNum'], 'integer'],
        ];
    }

    public function attributeLabels()
    {
        return [
            'userName' => '会员编号',
            'levelId' => '级别',
            'periodNum' => '期数',
            'remark' => '备注',
        ];
    }

    /**
     * 指定校验场景
     * @return array
     */
    public function scenarios()
    {
        $parentScenarios =  parent::scenarios();
        $customScenarios = [
            'adminChange' => ['userName', 'levelId', 'remark'],
        ];
        return array_merge($parentScenarios, $customScenarios);
    }

    /**
     * 赋值UserId并校验会员是否存在
     * @param $attribute
     */
    public function isUser($attribute){
        $this->_userId = Info::getUserIdByUserName($this->userName);
        if(!$this->_userId){
            $this->addError($attribute, Yii::t('ctx', 'memberDoesNotExist'));
        }
    }

    /**
     * 查看级别是否有变化
     * @param $attribute
     * @throws \yii\db\Exception
     */
    public function isLevel($attribute){
        $this->_fromId = Info::getEmpLv($this->_userId);
        if ($this->levelId == $this->_fromId) {
            $this->addError($attribute, Yii::t('ctx', 'levelNoChange'));
        }
    }

    /**
     * 更改最高聘级.
     * @return HighestEmpLevelLog|null
     */
    public function adminChange()
    {
        if (!$this->validate()) {
            return null;
        }
        $this->adminOperateLogger->beforeUpdate($this->_userId,'ID',['select'=>'ID,EMP_LV']);

        $model = new HighestEmpLevelLog();

        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $period = Period::instance();
            // 新增数据
            $model->USER_ID = $this->_userId;
            $model->FROM_ID = $this->_fromId;
            $model->TO_ID = $this->levelId;
            $model->PERIOD_NUM = $period->getNowPeriodNum();
            $model->CALC_MONTH = $period->getYearMonth($period->getNowPeriodNum());
            $model->REMARK = $this->remark ?? '';
            $model->STATUS = 1;
            $model->ADMIN_ID = \Yii::$app->user->id;
            $model->CREATED_AT = Date::nowTime();
            if (!$model->save()) {
                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
            }

            // 修改最高聘级
            User::updateAll(['EMP_LV' => $this->levelId], 'ID=:USER_ID', [':USER_ID' => $this->_userId]);

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('adminChange', $e->getMessage());
            return null;
        }

        $this->adminOperateLogger->afterUpdate($this->_userId,'ID',['select'=>'ID,EMP_LV'])->clean()->save([
            'optType' => '调整会员最高聘级',
            'userId' => $this->_userId,
            'userName' => Info::getUserNameByUserId($this->_userId),
            'remark' => $this->remark
        ]);

        return $model;
    }
}
