<?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\config\AllowUrlConfig;
use app\adminapi\model\auth\AdminRole;
use app\adminapi\model\auth\SystemMenu;
use app\adminapi\model\auth\SystemRoleMenu;
use app\common\cache\AdminAuthCache;
use app\Request;
use core\base\BaseService;
use core\exception\AuthException;

class AuthService extends BaseService
{
    public function checkRole(Request $request)
    {
        // 当前访问的 pathinfo，例如：adminapi/auth.admin/lists
        $path = $request->pathinfo();
        $accessUri = strtolower(preg_replace('#^adminapi/#', '', $path));

        // 白名单检查（使用统一配置）
        if (AllowUrlConfig::isAuthAllowed($accessUri)) {
            return true;
        }

        // 检查路由是否存在：如果控制器或方法不存在，直接放行让框架返回 404
        if (!$this->routeExists($accessUri)) {
            return true;
        }

        // 如果 adminInfo 为 null，说明未登录
        if (empty($request->adminInfo)) {
            throw new AuthException('请先登录', 401);
        }

        $getAllAuth = (new AdminAuthCache())->getAllUrl();

        //超级管理员跳过权限验证
        if ($request->adminInfo['is_admin'] === 1) {
            return true;
        }

        if (!in_array($accessUri, $getAllAuth)) {
            return true;
        }

        //获取当前用户权限
        $getAdminAuth = (new AdminAuthCache())->getAdminUrl($request->adminId);

        if (in_array($accessUri, $getAdminAuth)) {
            return true;
        }

        throw new AuthException('没有权限，请联系管理员');
    }

    public static function getAllAuth()
    {
        return SystemMenu::distinct(true)
            ->where([
                ['is_disable', '=', 0],
                ['perms', '<>', '']
            ])
            ->column('perms');
    }

    public static function getAdminAuth($adminId)
    {
        $roleIdArray = (new AdminRole())->where('admin_id', '=', $adminId)
            ->column('role_id');
        $menuIdArray = (new SystemRoleMenu())->whereIn('role_id', $roleIdArray)
            ->column('menu_id');
        return SystemMenu::distinct(true)
            ->where([
                ['is_disable', '=', 0],
                ['perms', '<>', '']
            ])
            ->whereIn('id', $menuIdArray)
            ->column('perms');
    }

    /**
     * @Desc 获取当前管理员拥有的按钮权限
     * @Create on 2025/12/16 上午11:19
     * @Create by woailuo
     */
    public function getBtnAuthByAdminId($adminArray): array
    {
        if ($adminArray['is_admin'] == 1) {
            return ['*'];
        }

        if (isset($adminArray['role_id']) && is_array($adminArray['role_id'])) {
            $roleIdArray = $adminArray['role_id'];
        } else {
            $roleIdArray = (new AdminRole())->where('admin_id', '=', $adminArray['id'])
                ->column('role_id');
        }

        $menuIdArray = (new SystemRoleMenu())->whereIn('role_id', $roleIdArray)
            ->column('menu_id');

        $where[] = ['is_disable', '=', 0];
        $where[] = ['perms', '<>', ''];

        $roleAuth = SystemMenu::distinct(true)
            ->where('id', 'in', $menuIdArray)
            ->where($where)
            ->column('perms');

        $allAuth = (new AdminAuthCache())->getAllUrl();

        $hasAllAuth = array_diff($allAuth, $roleAuth);
        if (empty($hasAllAuth)) {
            return ['*'];
        }

        return $roleAuth;

    }

    /**
     * 检查路由对应的控制器和方法是否存在
     * 
     * @param string $accessUri 访问的 URI，格式如 login.captcha/getcaptcha
     * @return bool
     */
    protected function routeExists(string $accessUri): bool
    {
        // 解析 URI：controller/action 或 dir.controller/action
        $parts = explode('/', $accessUri);
        if (count($parts) !== 2) {
            return false;
        }

        [$controllerPath, $action] = $parts;
        
        // 处理控制器路径，如 login.captcha -> login\CaptchaController
        $controllerParts = explode('.', $controllerPath);
        
        // 构建控制器类名
        $controllerClass = 'app\\adminapi\\controller\\';
        
        if (count($controllerParts) === 1) {
            // 直接在 controller 目录下，如 config -> ConfigController
            $controllerClass .= ucfirst($controllerParts[0]) . 'Controller';
        } else {
            // 在子目录下，如 login.captcha -> login\CaptchaController
            $subDir = array_slice($controllerParts, 0, -1);
            $controllerName = end($controllerParts);
            $controllerClass .= implode('\\', $subDir) . '\\' . ucfirst($controllerName) . 'Controller';
        }

        // 检查控制器类是否存在
        if (!class_exists($controllerClass)) {
            return false;
        }

        // 检查方法是否存在
        if (!method_exists($controllerClass, $action)) {
            return false;
        }

        return true;
    }

}