<?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\Admin;
use app\adminapi\model\auth\AdminRole;
use app\adminapi\model\auth\SystemRole;
use app\dict\sys\AppTypeDict;
use core\base\BaseService;
use core\exception\ServerException;
use core\util\TokenAuth;
use think\facade\Db;

class AdminService extends BaseService
{
    protected $model = null;

    public function __construct()
    {
        parent::__construct();
        $this->model = new Admin();
    }

    public function add($params)
    {
        //todo 七牛云存储未对接
        $avatar = !empty($params['avatar']) ? $params['avatar'] : config('project.default_image.admin_avatar');
        Db::startTrans();
        try {
            $this->model->save([
                'name' => $params['name'],
                'avatar' => $avatar,
                'account' => $params['account'],
                'password' => create_password($params['password']),
                'disable' => $params['disable'],
                'create_time' => time(),
                'is_admin' => $data[ 'is_admin' ]??0,
            ]);
            AdminRole::insertAdminRole($this->model->id, $params['role_id']);
            // 提交事务
            Db::commit();
            return true;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }
    }

    public function edit($params)
    {
        //todo 七牛云存储未对接
        $avatar = !empty($params['avatar']) ? $params['avatar'] : config('project.default_image.admin_avatar');
        $adminObj = $this->model->find($params['id']);
        if (!$adminObj) {
            self::setError('管理员不存在');
            return false;
        }
        if ($adminObj['is_admin'] == 1 && isset($params['disable']) && $params['disable'] == 1) {
            self::setError('系统管理员不能被禁用');
            return false;
        }

        Db::startTrans();
        try {
            // 基础信息（不包含id）
            $data = [
                'name' => $params['name'],
                'account' => $params['account'],
                'avatar' => $avatar,
            ];

            // 禁用状态（可选）
            if (isset($params['disable'])) {
                $data['disable'] = $params['disable'];
            }

            // 密码（可选）
            if (!empty($params['password'])) {
                $data['password'] = create_password($params['password']);
            }

            // 禁用或更换角色后.设置token过期
            $editRole = false;
            if ($adminObj['is_admin'] == 1 && !empty($params['role_id'])) {
                $roleId = (new AdminRole())->where('admin_id', $params['id'])->column('role_id');
                if (!empty(array_diff_assoc($roleId, $params['role_id']))) {
                    $editRole = true;
                }
            }

            if ($params['disable'] == 1 || $editRole) {
                TokenAuth::clearToken($params['id'],AppTypeDict::ADMIN ,'');
            }
            // 使用 update 方法更新指定 id 的记录
            $this->model->where('id', $params['id'])->update($data);

            // 更新角色（如果提供了role_id）
            if ($adminObj['is_admin'] == 1 && !empty($params['role_id'])) {
                AdminRole::deleteAdminRole($params['id']);
                AdminRole::insertAdminRole($params['id'], $params['role_id']);
            }

            // 提交事务
            Db::commit();
            return true;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }
    }

    public function profile($params)
    {
        $admin = $this->model->find($this->request->adminId);
        if (!$admin) {
            self::setError('管理员不存在');
            return false;
        }
        //todo 七牛云存储未对接
        $avatar = !empty($params['avatar']) ? $params['avatar'] : $admin->getData('avatar');

        Db::startTrans();
        try {
            // 基础信息（不包含id）
            $data = [
                'name' => $params['name'],
                'account' => $params['account'],
                'avatar' => $avatar,
            ];

            // 密码（可选）
            if (!empty($params['password'])) {
                // 如果填写了密码，则必须验证旧密码
                if (isset($params['password_old'])) {
                    if (!check_password($params['password_old'], $admin['password'])) {
                        throw new \Exception('旧密码错误');
                    }
                }
                $data['password'] = create_password($params['password']);
            }

            // 使用 save 方法更新，触发修改器
            $admin->save($data);

            // 提交事务
            Db::commit();
            return true;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }
    }

    public function disable($params)
    {
        $admin = $this->model->find($params['id']);
        if (!$admin) {
            self::setError('管理员不存在');
            return false;
        }
        if ($admin['is_admin'] == 1) {
            self::setError('系统管理员不能被禁用');
            return false;
        }

        try {
            $admin->save([
                'disable' => $params['disable']
            ]);

            if ($params['disable'] == 1) {
                TokenAuth::clearToken($params['id'], AppTypeDict::ADMIN, '');
            }
            return true;
        } catch (\Exception $e) {
            self::setError($e->getMessage());
            return false;
        }
    }



    public function detail($id)
    {
        $admin = $this->model
            ->where('id', $id)
            ->field('id,name,account,avatar,disable,is_admin')
            ->with(['admin_role_index'])
            ->find();
        if (!$admin) {
            self::setError('管理员不存在');
            return false;
        }

        $adminObj = $admin;

        $admin = $admin->toArray();
        $admin['role_id'] = array_column($admin['admin_role_index'], 'role_id');;
        unset($admin['admin_role_index']);

        $admin['role_name'] = $this->getRoleName($adminObj);
        return $admin;
    }

    public function delete($id)
    {
        $ids = is_array($id) ? $id : [$id];
        if (empty($ids)) {
            self::setError('请选择要删除的管理员');
            return false;
        }

        // Check if contains super admin
        $hasSuper = $this->model->whereIn('id', $ids)->where('is_admin', 1)->find();
        if ($hasSuper) {
            self::setError('选中项包含系统管理员，无法删除');
            return false;
        }

        Db::startTrans();
        try {
            $this->model->whereIn('id', $ids)->delete();
            AdminRole::whereIn('admin_id', $ids)->delete();

            // Clear tokens
            foreach ($ids as $uid) {
                TokenAuth::clearToken($uid, AppTypeDict::ADMIN, '');
            }

            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            self::setError($e->getMessage());
            return false;
        }
    }

    public function getPage(array $where = [])
    {
        $field = 'id,name,account,avatar,disable,is_admin,create_time,login_time,login_ip';
        $order = 'id desc';

        $search_model = $this->model
            ->withSearch(["name","account"], $where)
            ->with(['admin_role_index'])
            ->field($field)
            ->order($order);
        $list = $this->pageQuery($search_model);
        foreach ($list['data'] as $key => $adminObj) {
            $roleId = array_column($adminObj['admin_role_index'], 'role_id');
            $list['data'][$key]['role_id'] = $roleId;
            unset($list['data'][$key]['admin_role_index']);

            $list['data'][$key]['role_name'] = $this->getRoleName($adminObj);
            
        }
        return $list;
    }

    private function getRoleName($admin)
    {
        $roleName = '';
        if ($admin['is_admin'] == 1) {
            $roleName = '系统管理员';
        } else {
            $roleIds = AdminRole::where('admin_id', $admin['id'])->column('role_id');
            $roles = (new SystemRole())->whereIn('id', $roleIds)->select();
            foreach ($roles as $role) {
                $roleName .= '/' . $role['name'];
            }
        }

        return trim($roleName, '/');
    }

    public function byAccountGetAdminInfo($account)
    {
        $adminObj = $this->model
            ->where('account', $account)
            ->findOrEmpty();

        if (!$adminObj->isEmpty()) {
            $adminObj['role_name'] = $this->getRoleName($adminObj);
        }
        return $adminObj;
    }

    /**
     * @Desc 获取管理员详情及权限信息
     * @Create on 2025/12/16 上午11:30
     * @Create by woailuo
     */
    public function getAdminInfo($id): array
    {
        $adminObj = $this->model
            ->where('id', $id)
            ->field('id,name,account,avatar,disable,is_admin')
            ->with(['admin_role_index'])
            ->findOrEmpty();

        if ($adminObj->isEmpty()) {
            throw new ServerException('管理员不存在');
        }
        $adminArray = $adminObj->toArray();
        $adminArray['role_name'] = explode(',', $this->getRoleName($adminObj));

        //获取当前管理员信息
        $adminArray['role_id'] = array_column($adminArray['admin_role_index'], 'role_id');;
        unset($adminArray['admin_role_index']);
        $result['admin'] = $adminArray;

        //获取当前管理员拥有的菜单
        $result['menu'] = (new MenuService())->getMenuByAdminId($adminArray);

        //获取当前管理员拥有的按钮权限
        $result['permissions'] = (new AuthService())->getBtnAuthByAdminId($adminArray);
        return $result;
    }
}