<?php

namespace common\models\forms;

use common\components\Model;
use common\helpers\Cache;
use common\helpers\Date;
use common\helpers\Form;
use common\helpers\LoggerTool;
use common\helpers\snowflake\PageSnowFake;
use common\helpers\Tool;
use common\libs\logging\operate\AdminOperate;
use common\models\Countries;
use common\models\Currency;
use common\models\CurrencyConversions;
use common\models\Instalment;
use common\models\Period;
use common\models\User;
use common\models\UserImmigrant;
use common\models\UserWallet;
use Yii;
use yii\base\Exception;

/**
 * Login form
 */
class UserBasicForm extends Model {
    public $userId;
    public $password;
    public $passwordType;

    //个人资料
    public $nation;
    public $realName;
    public $idCard;
    public $mobile;
    public $openBank;
    public $bankAddress;
    public $bankNo;
    public $country;
    public $language;

    public $status;

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

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['userId', 'password', 'passwordType','realName', 'mobile','openBank','bankAddress','bankNo','status'], 'trim'],
            [['userId'], 'required'],
            [[/*'idCard', */'allData'], 'required', 'on'=>['addWithUserName']],
            [['nation','realName', 'mobile', /*'idCard', */'openBank', 'bankAddress', 'bankNo', 'country', 'language'], 'required', 'on'=>'modifyProfile'],
//            [['mobile'], 'mobile'],
        ];
    }

    /**
     * 指定校验场景
     * @return array
     */
    public function scenarios() {
        $parentScenarios = parent::scenarios();
        $customScenarios = [
            'modifyPassword' => ['userId', 'password', 'passwordType'],
            'modifyProfile' => ['userId','realName',/*'idCard',*/'mobile','openBank','bankAddress','bankNo', 'country', 'language'],
            'modifyStatus' => ['userId','status'],
            'isModifyPasswordStatus' => ['userId','status'],
        ];
        return array_merge($parentScenarios, $customScenarios);
    }

    public function attributeLabels() {
        return [
            'ID' => 'ID',
            'password' => '密码',
            'passwordType' => '密码类型',
//            'nation' => '民族',
            'realName' => '真实姓名',
//            'idCard' => '身份证号',
            'mobile' => '手机号',
            'openBank' => '银行名称',
            'bankAddress' => '开户支行',
            'bankNo' => '银行账号',
            'status' => '状态',
            'country' => '国家',
            'language' => '语言',
        ];
    }

    public function beforeValidate() {
        return parent::beforeValidate();
    }

    /**
     * 编辑用户信息
     * @return null
     * @throws \yii\db\Exception
     */
    public function edit() {
        if (!$this->validate()) {
            return null;
        }
        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $userModel = User::findOne(['ID'=>$this->userId]);
            if( $this->passwordType === 'password' ) {
                $userModel->PASSWORD_HASH = \Yii::$app->security->generatePasswordHash($this->password);
            }else {
                $userModel->PAY_PASSWORD = \Yii::$app->security->generatePasswordHash($this->password);
            }

            if( !$userModel->save(false) ) {
                throw new Exception($userModel->getErrors());
            }

            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            return null;
        }

        return $userModel;

    }

    /**
     * 修改个人资料
     * @return User|null
     * @throws \yii\db\Exception
     * @throws Exception
     */
    public function modifyProfile(){
        if(!$this->validate()){
            return null;
        }

        // 会员信息
        $userModel = User::findOne(['ID' => $this->userId]);
        // 原国家
        $beforeCountry = $userModel->COUNTRY_ID;
        $beforeCurrencyId = Countries::getCurrency($beforeCountry);
        // 移民前汇率
        $beforeCurrencyRate = CurrencyConversions::getToUSDRate($beforeCurrencyId);
        // 移民后汇率
        $beforeCurrencyId = Countries::getCurrency($this->country);
        $afterCurrencyRate = CurrencyConversions::getToUSDRate($beforeCurrencyId);
        if (!$afterCurrencyRate) {
            throw new Exception(Yii::t('app', 'currencyDoesNotExist'));
        }
        // 如果移民,则需要进行移民条件检查
        if ($this->country != $beforeCountry) {
            // 1. 有现金余额不可以移民
            $userWallet = UserWallet::findOne(['USER_ID' => $this->userId]);
            if ($userWallet && $userWallet->CASH > 0) {
                throw new Exception(Yii::t('app', 'cashThanNotAllowModificationCountry'));
            }

            // 2.有进行中的分期订单不可以移民
            $instalmentOrder = Instalment::findOne(['USER_ID' => $this->userId]);
            // 订单分期总期数配置
            if ($instalmentOrder) {
                // 分期的总期数
                $instalment = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3);
                // 分期商品的期数不能大于总分期数限制
                if (intval($instalmentOrder['STAGE']) < $instalment) {
                    throw new Exception(Yii::t('app', 'instalmentOrderInProcess'));
                }
            }
        }

        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $this->adminOperateLogger->beforeUpdate($userModel);
            $userModel->REAL_NAME = $this->realName;
            $userModel->MOBILE = $this->mobile;
            $userModel->OPEN_BANK = $this->openBank;
            $userModel->BANK_NO = $this->bankNo;
            $userModel->BANK_ADDRESS = $this->bankAddress;
            $userModel->LANGUAGE_ID = $this->language;
            $userModel->COUNTRY_ID = $this->country;
            if( !$userModel->save(false) ) {
                $transaction->rollBack();
                throw new Exception($userModel->getErrors());
            }

            // 移民操作
            if ($this->country != $beforeCountry) {
                // 移民记录
                $model = new UserImmigrant();
                $model->ID = PageSnowFake::instance()->generateId();
                $model->user_id = $this->userId;
                $model->before_country_id = $beforeCountry;
                $model->after_country_id = $this->country;
                $model->period_num = Period::instance()->getNowPeriodNum();
                $model->created_by = \Yii::$app->user->id;
                if (!$model->save()) {
                    $transaction->rollBack();
                    throw new Exception(Form::formatErrorsForApi($model->getErrors()));
                }

                // 现金钱包余额转换
                $userWallet = UserWallet::findOne(['USER_ID' => $this->userId]);
                if ($userWallet && $userWallet->CASH > 0) {
                    $userWallet->CASH = Tool::convertAmount($userWallet->CASH, $beforeCurrencyRate, $afterCurrencyRate);
                    if (!$userWallet->save()) {
                        $transaction->rollBack();
                        throw new Exception($userModel->getErrors());
                    }
                }
            }

            $transaction->commit();

            $this->adminOperateLogger->afterUpdate($userModel)->clean()->save([
                'optType' => 'Modification of Member information', // 修改会员资料
                'userId' => $this->userId,
                'userName' => $userModel->USER_NAME,
                'realName' => $this->realName,
                'mobile' => $this->mobile,
                'openBank' => $this->openBank,
                'bankNo' => $this->bankNo,
                'bankAddress' => $this->bankAddress,
                'language' => $this->language,
                'country' => $this->country,
            ]);
        }catch (Exception $e) {
            $transaction->rollBack();
            throw new Exception($e->getFile() . ' ' . $e->getLine() . ' ' . $e->getMessage());
        }
        return $userModel;
    }


    /**
     * 修改会员状态
     * @return User|null
     * @throws \yii\db\Exception
     */
    public function modifyStatus(){
        if(!$this->validate()){
            return null;
        }
        $this->adminOperateLogger->beforeUpdate($this->userId, 'ID',['select'=>'ID,STATUS']);

        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $userModel = User::findOne(['ID' => $this->userId]);
            if($userModel->STATUS==$this->status){
                $statusName = ($userModel->STATUS == 1) ? 'activation' : 'lock'; // 激活 锁定
                throw new Exception('The current member status is【' . $statusName . '】，Do not need to set it again！'); // 当前会员状态已  无需重复设置
            }
            $userModel->STATUS = $this->status;
            $userModel->STATUS_AT = Date::nowTime();
            if( !$userModel->save(false) ) {
                throw new Exception($userModel->getErrors());
            }
            $transaction->commit();
        }catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('modifyStatus', $e->getMessage());
            return null;
        }
        $this->adminOperateLogger->afterUpdate($this->userId,'ID',['select'=>'ID,STATUS'])->clean()->save([
            'optType' => ($this->status == 1) ? 'Member activation' : 'Member of the lock', // 会员激活 会员锁定
        ]);
        return $userModel;
    }

    /**
     * @return User|null
     * @throws \yii\db\Exception
     */
    public function isModifyPasswordStatus(){
        if(!$this->validate()){
            return null;
        }
        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $userModel = User::findOne(['ID' => $this->userId]);
            if($userModel->IS_MODIFY_PASSWORD==$this->status){
                throw new Exception('The status has not changed, and do not need to set it again');// 状态没有发生改变，无需重复设置！
            }
            $userModel->IS_MODIFY_PASSWORD = $this->status;
            if( !$userModel->save(false) ) {
                throw new Exception($userModel->getErrors());
            }
            $transaction->commit();
        }catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('isModifyPasswordStatus', $e->getMessage());
            return null;
        }
        return $userModel;
    }

}
