<?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\middleware;

use app\adminapi\config\AllowUrlConfig;
use app\adminapi\model\auth\Admin;
use app\dict\sys\AppTypeDict;
use core\util\TokenAuth;

class AdminCheckToken
{
    public function handle($request, \Closure $next)
    {
        // 当前访问的 pathinfo，例如：adminapi/auth.admin/lists
        $path = $request->pathinfo();
        $accessUri = strtolower(preg_replace('#^adminapi/#', '', $path));

        // 白名单检查（使用统一配置）
        if (AllowUrlConfig::isTokenAllowed($accessUri)) {
            // 白名单请求也需要初始化，防止后续中间件访问 null
            $request->adminId = 0;
            $request->adminInfo = null;
            return $next($request);
        }

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

        $token = $request->header('Token');
        // 确保 token 为字符串，避免 null 导致 TypeError
        if (empty($token)) {
            $token = '';
        }
        $token = trim($token);

        $token_info = TokenAuth::parseToken($token, AppTypeDict::ADMIN);

        $request->adminId = $token_info['admin_id'] ?? 0;
        $request->adminInfo = (new Admin())->find($request->adminId);
        return $next($request);
    }

    /**
     * 检查路由对应的控制器和方法是否存在
     * 
     * @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;
    }
}