<?php


namespace common\services;


use common\components\AjaxException;
use common\models\BaseRoleServerRules;
use common\models\BaseUser;
use common\models\Staff;
use common\util\UserRoleAuth;
use Yii;
use yii\base\InvalidConfigException;
use yii\db\ActiveQuery;
use yii\db\Exception;

class UserService
{
    /**
     * @param $id
     * @return BaseUser
     * @throws AjaxException
     */
    public static function getBaseUserById($id): BaseUser
    {
        /** @var BaseUser $UserInfo */
        $UserInfo = self::getQuery()->andWhere(["id" => $id])->one();
        if (!$UserInfo) {
            throw new AjaxException("该用户不存在！");
        }
        return $UserInfo;
    }

    /**
     * @return ActiveQuery
     */
    public static function getQuery(): ActiveQuery
    {
        return BaseUser::find()->where([">=", "status", 0]);
    }

    /**
     * @return void
     * @throws \Throwable
     * @throws InvalidConfigException
     */
    public static function add(): void
    {
        //校验是否重名
        self::validateUserRepeat();
        //保存用户信息
        $userInfo = new BaseUser();
        //数据录入
        ActiveRecordService::getInstance()->setAttributeFromGetAndPost($userInfo);
        //处理数据
        //密码
        if ($userInfo->password) {
            $userInfo->password = md5($userInfo->password);
        } else {
            $userInfo->password = md5("admin123456");
        }
        //创建时间,更新时间
        $userInfo->create_time = date("Y-m-d H:i:s");
        $userInfo->update_time = date("Y-m-d H:i:s");

        //保存员工信息
        $staffInfo = new Staff();
        //数据录入
        $staffInfo->name = ActiveRecordService::getInstance()->getParams("name");
        $staffInfo->phone = ActiveRecordService::getInstance()->getParams("phone");
        $staffInfo->seniority = ActiveRecordService::getInstance()->getParams("seniority");
        $staffInfo->department = ActiveRecordService::getInstance()->getParams("department");
        $staffInfo->employment = ActiveRecordService::getInstance()->getParams("employment");
        //开启事务
        Yii::$app->db->transaction(function () use ($userInfo, $staffInfo) {
            //保存
            $userInfo->save();
            //处理数据
            $staffInfo->uid = $userInfo->id;
            //保存
            $staffInfo->save();
        });
    }

    /**
     * @param $id
     * @return void
     * @throws AjaxException
     * @throws InvalidConfigException
     * @throws \Throwable
     */
    public static function update($id): void
    {
        //校验是否重名
        self::validateUserRepeat(true);
        //修改用户信息
        $userInfo = UserService::getBaseUserById($id);
        ActiveRecordService::getInstance()->setAttributeFromGetAndPost($userInfo);
        if (isset($_GET['password'])) {
            $userInfo->password = md5($_GET['password']);
        }
        $userInfo->update_time = date("Y-m-d H:i:s");
        // 修改员工信息
        $staffInfo = Staff::findOne(["uid" => $userInfo->id]);
        if (!$staffInfo) {
            $staffInfo = new Staff();
            $staffInfo->uid = $userInfo->id;
        }
        //数据录入
        $staffInfo->name = ActiveRecordService::getInstance()->getParams("name");
        $staffInfo->phone = ActiveRecordService::getInstance()->getParams("phone");
        $staffInfo->seniority = ActiveRecordService::getInstance()->getParams("seniority");
        $staffInfo->department = ActiveRecordService::getInstance()->getParams("department");
        $staffInfo->employment = ActiveRecordService::getInstance()->getParams("employment");
        //开启事务
        Yii::$app->db->transaction(function () use ($userInfo, $staffInfo) {
            if (!$userInfo->save()) {
                throw new Exception($userInfo->getErrorSummary(true)[0]);
            }
            if (!$staffInfo->save()) {
                throw new Exception($staffInfo->getErrorSummary(true)[0]);
            }
        });
    }

    /**
     * @throws AjaxException
     */
    public static function getUserRoleAuth($userInfo): UserRoleAuth
    {

        $redis = Yii::$app->redis;
        $rulesString = $redis->get('rules_' . $userInfo->id);
        if (!$rulesString) {
            throw new AjaxException('用户身份失效,请先登录');
        }
        if ($rulesString == "*") {
            $rules = $rulesString;
        } else {
            $rules = json_decode($rulesString, true);
        }
        $userRoleAuth = new UserRoleAuth();
        self::setIsSuperAdmin($userRoleAuth, $rules);
        self::setCaseAuth($userRoleAuth, $rules);
        return $userRoleAuth;
    }

    public static function setIsSuperAdmin($userRoleAuth, $rules)
    {
        /** @var  $userRoleAuth UserRoleAuth */
        if ($rules == "*") {
            $userRoleAuth->isSuperAdmin = true;
        }
    }

    public static function getCanCheckList(): array
    {
        //找可以审核的人
        $serRules = BaseRoleServerRules::find()->all();
        $roleIds = [];
        foreach ($serRules as $serverRule) {
            /** @var  $serverRule BaseRoleServerRules */
            $serRuleArray = json_decode($serverRule->rules);
            if (self::checkCaseCheck($serRuleArray)) {
                $roleIds[] = $serverRule->role_id;
            }
        }
        if ($roleIds != []) {
            return BaseUser::find()
                ->alias("u")
                ->join('LEFT JOIN', 'staff s', 's.uid = u.id')
                ->where([">=", "u.status", 0])
                ->andWhere("u.id > 1")
                ->andWhere(["roles" => $roleIds])
                ->select(self::getUserSqlSelectInfo())
                ->all();
        }
        return [];
    }

    public static function getUserSqlSelectInfo(): string
    {
        return "u.id,username,s.name,department,employment,s.phone,seniority,email,roles,create_time,last_login_time,status,learning_duration,learning_duration_month";
    }


    public static function setCaseAuth($userRoleAuth, $rules)
    {
        /** @var  $userRoleAuth UserRoleAuth */
        if ($rules == "*") {
            $userRoleAuth->caseAdd = true;
            $userRoleAuth->caseCheck = true;
        } else {
            if (
                in_array("/accident-cases/add", $rules)
                && in_array("/accident-cases/commit", $rules)
                && in_array("/accident-cases/cancel", $rules)
                && in_array("/accident-cases/update", $rules)
                && in_array("/accident-cases/delete", $rules)
            ) {
                $userRoleAuth->caseAdd = true;
            }
            $userRoleAuth->caseCheck = self::checkCaseCheck($rules);

        }
    }

    public static function checkCaseCheck($rules)
    {
        if (
            in_array("/accident-cases/publish", $rules)
            && in_array("/accident-cases/revoke", $rules)
            && in_array("/accident-cases/refuse", $rules)
            && in_array("/accident-cases/pass", $rules)
        ) {
            return true;
        }
        return false;
    }

    /**
     * @param $userId
     * @return string|null
     */
    public static function getRealNameByUserId($userId): ?string
    {
        $staff = Staff::findOne(["uid" => $userId]);
        return $staff?->name; //等价于         return $staff ? $staff->name : null;
    }

    /**
     * @param bool $isUpdate
     * @return void
     * @throws AjaxException
     */
    protected static function validateUserRepeat(bool $isUpdate = false): void
    {
//        $query = UserService::getQuery()->andWhere(["or", ['username' => $_GET["username"]], ['phone' => $_GET["phone"]], ['email' => $_GET["email"]]]);
        $query = UserService::getQuery()->andWhere(['username' => $_GET["username"]]);
        if ($isUpdate) {
            $query->andWhere(['<>', 'id', $_GET["id"]]);
        }
        /** @var BaseUser $userInfo */
        $userInfo = $query->one();
        if ($userInfo) {
            if ($userInfo->username == $_GET["username"]) {
                throw new AjaxException("用户名已存在！");
            }
//            if ($userInfo->phone == $_GET["phone"]) {
//                throw new AjaxException("手机号码已存在！");
//            }
//            if ($userInfo->email == $_GET["email"]) {
//                throw new AjaxException("电子邮箱已存在！");
//            }
        }
    }
}