<?php


namespace common\services;

use common\components\AjaxException;
use common\models\BaseRole;
use common\models\BaseRoleClientRules;
use common\models\BaseRoleMenu;
use common\models\BaseRoleServerRules;
use Throwable;
use yii\base\InvalidConfigException;
use yii\db\ActiveQuery;
use yii\db\StaleObjectException;

class RoleService
{
    /**
     * @param $id
     * @return BaseRole
     * @throws AjaxException
     */
    public static function getRoleById($id): BaseRole
    {
        /** @var BaseRole $BaseRole */
        $BaseRole = self::getQuery()->andWhere(["id" => $id])->one();
        if (!$BaseRole) {
            throw new AjaxException("该角色不存在！");
        }
        return $BaseRole;
    }

    /**
     * @return ActiveQuery
     */
    public static function getQuery(): ActiveQuery
    {
        return BaseRole::find();
    }

    /**
     * @return void
     * @throws AjaxException
     */
    protected static function validateRoleRules(): void
    {
        if (!isset($_GET['role_rules'])) {
            throw new AjaxException("权限为空！");
        }
        if (!is_array($_GET['role_rules'])) {
            throw new AjaxException("权限不合法！");
        }
    }

    /**
     * @param $name
     * @param $code
     * @param $status
     * @return void
     * @throws AjaxException
     */
    public static function add($name, $code, $status): void
    {
        //验证数据
        self::validateRoleRules();
        //角色查重
        $info = self::getQuery()->andWhere(['name' => $name])->one();
        if ($info) {
            throw new AjaxException("{$name}已存在！");
        }
        //插入
        $time = strtotime('now');
        $roleParams = [
            'name' => $name,
            'code' => $code,
            'status' => $status,
            'create_time' => date('Y-m-d H:i:s', $time),
            'update_time' => date('Y-m-d H:i:s', $time),
        ];
        $insertInfo = new BaseRole($roleParams);
        $insertInfo->save();
        $newId = $insertInfo->id;
        // 插入权限
        self::saveClientAndServerRules($newId, $_GET["role_rules"]);
    }

    /**
     * @return void
     * @throws AjaxException
     * @throws InvalidConfigException
     */
    public static function update(): void
    {
        //验证数据
        self::validateRoleRules();
        //验证id
        if (!isset($_GET['id'])) {
            throw new AjaxException("id不存在！");
        }
        $roleId = $_GET["id"];
        $role = self::getRoleById($roleId);
        //角色查重
        $info = self::getQuery()
            ->andWhere(['name' => $_GET['name']])
            ->andWhere(["<>", "id", $roleId])
            ->one();
        if ($info) {
            throw new AjaxException("{$_GET['name']}已存在！");
        }
        //修改
        ActiveRecordService::getInstance()->setAttributeFromGetAndPost($role);
        if (!$role->save()) {
            throw new AjaxException("角色更新失败！");
        }
        // 删除之前的角色客户端权限
        BaseRoleMenu::deleteAll(['role_id' => $roleId]);
        // 插入权限
        self::saveClientAndServerRules($roleId, $_GET["role_rules"], true);
    }

    /**
     * @param $id
     * @return void
     * @throws StaleObjectException
     * @throws Throwable
     */
    public static function delete($id): void
    {
        $role = self::getRoleById($id);
        $role->delete();
        BaseRoleServerRules::deleteAll(['role_id' => $id]);
        BaseRoleClientRules::deleteAll(['role_id' => $id]);
    }

    /**
     * @param $id
     * @return string|null
     * @throws AjaxException
     */
    public static function getRoleNameById($id): ?string
    {
        $role = self::getRoleById($id);
        return $role->name;
    }

    /**
     * @param $roleId
     * @param $roleRules
     * @param bool $isUpdate
     * @return void
     */
    protected static function saveClientAndServerRules($roleId, $roleRules, bool $isUpdate = false): void
    {
        $menuUrlList = [];
        $serverUrlList = [];
        foreach ($roleRules as $oneRule) {
            //如果$oneRule不是以@开头，则放进服务器权限列表
            if (!str_starts_with($oneRule, "@")) {
                $serverUrlList[] = $oneRule;
            } else {
                $menuUrlList[] = $oneRule;
            }
        }
        $RoleServerRules = null;
        $RoleClientRules = null;
        if ($isUpdate) {
            $RoleServerRules = BaseRoleServerRules::findOne(["role_id" => $roleId]);
            $RoleClientRules = BaseRoleClientRules::findOne(["role_id" => $roleId]);
        }
        //保存服务端角色权限
        if (!$RoleServerRules) {
            $RoleServerRules = new BaseRoleServerRules();
        }
        $RoleServerRules->role_id = $roleId;
        $RoleServerRules->rules = json_encode(array_values($serverUrlList));
        $RoleServerRules->save();
        //保存客户端角色权限
        if (!$RoleClientRules) {
            $RoleClientRules = new BaseRoleClientRules();
        }
        $RoleClientRules->role_id = $roleId;
        $RoleClientRules->rules = json_encode(array_values($menuUrlList));
        $RoleClientRules->save();
    }
}