<?php
// +----------------------------------------------------------------------
// | 麦沃德科技赋能开发者，助力中小企业发展 
// +----------------------------------------------------------------------
// | Copyright (c) 2017～2024  www.wdadmin.cn    All rights reserved.
// +----------------------------------------------------------------------
// | Wdadmin系统产品软件并不是自由软件，不加密，并不代表开源，未经许可不可自由转售和商用
// +----------------------------------------------------------------------
// | Author: MY WORLD Team <bd@maiwd.cn>   www.wdadmin.cn
// +----------------------------------------------------------------------
namespace app\adminapi\service\auth;

use app\adminapi\model\auth\SystemRole;
use app\adminapi\model\auth\SystemRoleMenu;
use app\adminapi\model\auth\AdminRole;
use app\common\cache\AdminAuthCache;
use core\base\BaseService;

class RoleService extends BaseService
{
    protected $model = null;

    public function __construct()
    {
        parent::__construct();
        $this->model = new SystemRole();
    }
    public function add($params)
    {
        try {
            $this->model->save([
                'name' => $params['name'],
                'desc' => $params['desc'] ?? '',
                'sort' => $params['sort'] ?? 0,
            ]);

            $menuId = !empty($params['menu_id']) ? $params['menu_id'] : [];
            $insertData = [];
            foreach ($menuId as $item) {
                if (empty($item)) {
                    continue;
                }
                $insertData[] = [
                    'role_id' => $this->model->id,
                    'menu_id' => $item,
                ];
            }
            (new SystemRoleMenu)->insertAll($insertData);

        } catch (\Exception $e) {
            throw new \core\exception\ServerException($e->getMessage());
        }

    }

    /**
     * 编辑角色
     * @param array $params
     */
    public function edit($params)
    {
        $role = $this->model->find($params['id']);
        if (!$role) {
            throw new \core\exception\ServerException('角色不存在');
        }

        try {
            // 检查角色名称唯一性（排除自身）
            if (isset($params['name'])) {
                $exists = $this->model->where('name', $params['name'])
                    ->where('id', '<>', $params['id'])
                    ->find();
                if ($exists) {
                    throw new \core\exception\ServerException('角色名称已存在');
                }
            }

            $role->save([
                'name' => $params['name'] ?? $role->name,
                'desc' => $params['desc'] ?? $role->desc,
                'sort' => $params['sort'] ?? $role->sort,
            ]);

            $menuId = !empty($params['menu_id']) ? $params['menu_id'] : [];
            if (!empty($menuId)) {
                (new SystemRoleMenu())->where(['role_id' => $params['id']])->delete();
                $data = [];
                foreach ($menuId as $item) {
                    $data[] = [
                        'role_id' => $params['id'],
                        'menu_id' => $item,
                    ];
                }
                (new SystemRoleMenu)->insertAll($data);

                // 清除相关管理员的权限缓存
                $adminIds = (new AdminRole())->where('role_id', $params['id'])->column('admin_id');
                if (!empty($adminIds)) {
                    $adminAuthCache = new AdminAuthCache();
                    foreach ($adminIds as $adminId) {
                        $adminAuthCache->deleteAdminAuth($adminId);
                    }
                }
            }
        } catch (\Exception $e) {
            throw new \core\exception\ServerException($e->getMessage());
        }


    }

    /**
     * 删除角色
     * @param mixed $ids 角色ID或ID数组
     * @throws \core\exception\ServerException
     */
    public function delete($id)
    {
        $ids = is_array($id) ? $id : [$id];
        if (empty($ids)) {
            throw new \core\exception\ServerException('删除的角色不能为空');
        }

        // 检查是否有角色被管理员使用
        $adminRoleModel = new AdminRole();
        $usedRoles = [];
        
        foreach ($ids as $id) {
            $adminCount = $adminRoleModel->where('role_id', $id)->count();
            if ($adminCount > 0) {
                $roleName = $this->model->where('id', $id)->value('name');
                if (count($ids) === 1) {
                    throw new \core\exception\ServerException("该角色[{$roleName}]已被 {$adminCount} 个管理员使用，无法删除");
                }
                $usedRoles[] = $roleName . '(被' . $adminCount . '个管理员使用)';
            }
        }

        if (!empty($usedRoles)) {
            throw new \core\exception\ServerException('以下角色正在使用中，无法删除：' . implode('、', $usedRoles));
        }

        try {
            // 开启事务
            $this->model->startTrans();
            
            // 获取关联的管理员ID（用于清理权限缓存）
            $adminIds = (new AdminRole())->whereIn('role_id', $ids)->column('admin_id');
            
            // 批量删除角色菜单关联
            (new SystemRoleMenu())->whereIn('role_id', $ids)->delete();

            // 批量删除角色（使用destroy触发软删除）
            SystemRole::destroy($ids);
            
            // 清除相关管理员的权限缓存
            if (!empty($adminIds)) {
                $adminAuthCache = new AdminAuthCache();
                foreach ($adminIds as $adminId) {
                    $adminAuthCache->deleteAdminAuth($adminId);
                }
            }
            
            // 提交事务
            $this->model->commit();
            
            return count($ids);
        } catch (\Exception $e) {
            // 回滚事务
            $this->model->rollback();
            throw new \core\exception\ServerException('删除失败：' . $e->getMessage());
        }
    }

    public function getPage(array $where = [])
    {
        $field = 'id,name,desc,sort,create_time';
        $order = 'sort desc,id desc';

        $search_model = $this->model
            ->withSearch(["id","name"], $where)
            ->with(['role_menu_index'])
            ->field($field)
            ->order($order);
        $list = $this->pageQuery($search_model);
        foreach ($list['data'] as $key => $role) {
            $menuId = array_column($role['role_menu_index'], 'menu_id');
            $list['data'][$key]['menu_id'] = $menuId;
            unset($list['data'][$key]['role_menu_index']);
        }
        return $list;
    }

    public function getAllRoleIdAndName()
    {
        $field = 'id,name';
        $order = 'sort desc,id desc';
        $lists = $this->model
            ->field($field)
            ->order($order)
            ->select()
            ->toArray();
        return $lists;
    }
}