package com.xdap.self_development.intercept;

import com.xdap.runtime.service.RuntimeAppContextService;
import com.xdap.self_development.domain.enums.AuthorizationClassEnum;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Autowired
    private AuthService authService;

    @Autowired
    private RuntimeAppContextService runtimeAppContextService;

    private static final Set<String> WHITE_LIST = new HashSet<>(Arrays.asList(
            "/custom/activiti/getIsDirect",
            "/custom/engineParamDetailPojo/updateParamValue",
            "/custom/activiti/initiateApproval",
            "/custom/activiti/startActiviti",
            "/custom/activiti/directSendingApproval",
            "/custom/activiti/getApprovalUsers",
            "/custom/activiti/continueApproval",
            "/custom/activiti/handleApproval",
            "/custom/activiti/showActiviti",
            "/custom/permission/selectPersByUser",
            "/custom/approval/handleApproval",
            "/custom/approval/handleReturnToNode",
            "/custom/activiti/handleReturnToNode",
            "/custom/approval/handleReturn",
            "/custom/activiti/getReturnNodes",
            "/custom/approval/getReturnNodes",
            "/custom/engineParamDetailPojo/selectParamListAndModelForFilledBy",
            "/custom/engineParamDetailPojo/selectParamListAndModelForFilledByHistory",
            "/custom/YcTaskResult/getCompletedById",
            "/custom/YcTaskResult/getTodoById",
            "/custom/YcTaskResult/getInitiatorById"
    ));

    // 请求路径与权限枚举的映射关系
    private static final Map<String, AuthorizationClassEnum> PATH_PERMISSION_MAP = new HashMap<>();

    static {
        // 模板管理相关 - 对应参数模板管理权限
        PATH_PERMISSION_MAP.put("/custom/template/deleteTemplate", AuthorizationClassEnum.TEMPLATE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/template/insertTemplate", AuthorizationClassEnum.TEMPLATE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/template/import", AuthorizationClassEnum.TEMPLATE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/template/updateTemplate", AuthorizationClassEnum.TEMPLATE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/parameter/maintenanceParameters", AuthorizationClassEnum.TEMPLATE_EDIT);
        // 模板管理相关 - 对应审批管理权限
        PATH_PERMISSION_MAP.put("/custom/approval/startApproval", AuthorizationClassEnum.TEMPLATE_EDIT);
        // 模板审批流程查看
        PATH_PERMISSION_MAP.put("/custom/approval/getApprovalList", AuthorizationClassEnum.TEMPLATE_APPROVAL);
        
        // 发动机数据相关
        PATH_PERMISSION_MAP.put("/custom/dataEntryEngineModel/excelImport", AuthorizationClassEnum.ENGINE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/dataEntryEngineModel/synchronizeParams", AuthorizationClassEnum.ENGINE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/dataEntryEngineModel/insert", AuthorizationClassEnum.ENGINE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/dataEntryEngineModel/delete", AuthorizationClassEnum.ENGINE_EDIT);
        PATH_PERMISSION_MAP.put("/custom/engineParamDetailPojo/updateParamValue", AuthorizationClassEnum.ENGINE_EDIT);
        // 发动机数据相关 - 对应发动机数据权限
        PATH_PERMISSION_MAP.put("/custom/activiti", AuthorizationClassEnum.ENGINE_EDIT);
        // 发动机审批流程查看
        PATH_PERMISSION_MAP.put("/custom/activiti/showEngReview", AuthorizationClassEnum.ENGINE_APPROVAL);

        // 对标报告相关
        PATH_PERMISSION_MAP.put("/custom/benchmark/insertReport", AuthorizationClassEnum.REPORT_EDIT);
        PATH_PERMISSION_MAP.put("/custom/benchmark/startReportApproval", AuthorizationClassEnum.REPORT_EDIT);
        PATH_PERMISSION_MAP.put("/custom/benchmark/getReportAndTodoByCondition", AuthorizationClassEnum.REPORT_VIEW);
        PATH_PERMISSION_MAP.put("/custom/benchmark/getApprovalList", AuthorizationClassEnum.REPORT_APPROVAL);

        // 基础管理模块相关
        PATH_PERMISSION_MAP.put("/custom/responsible/import", AuthorizationClassEnum.BASIC_DATA_EDIT);
        PATH_PERMISSION_MAP.put("/custom/responsible/saveResponsiblePerson", AuthorizationClassEnum.BASIC_DATA_EDIT);
        PATH_PERMISSION_MAP.put("/custom/responsible/updateResponsiblePerson", AuthorizationClassEnum.BASIC_DATA_EDIT);
        PATH_PERMISSION_MAP.put("/custom/responsible/deleteResponsiblePerson", AuthorizationClassEnum.BASIC_DATA_EDIT);

        // 权限管理相关
        PATH_PERMISSION_MAP.put("/custom/permission", AuthorizationClassEnum.AUTH_EDIT);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String servletPath = request.getServletPath();
        String userId = runtimeAppContextService.getCurrentUserId();
        if (userId == null || userId.isEmpty()) {
            throw new CommonException("用户未登录或登录已过期");
        }
        
        if (WHITE_LIST.contains(servletPath)) {
            return true;
        }
        
        AuthorizationClassEnum requiredPermission = findRequiredPermission(servletPath);
        if (requiredPermission == null) {
            return true;
        }
        authService.checkUserAuthorization(userId, requiredPermission);
        return true;
    }

    /**
     * 根据请求路径查找所需的权限
     * 支持精确匹配和前缀匹配
     */
    private AuthorizationClassEnum findRequiredPermission(String path) {
        // 1. 精确匹配
        if (PATH_PERMISSION_MAP.containsKey(path)) {
            return PATH_PERMISSION_MAP.get(path);
        }
        
        // 2. 前缀匹配
        for (Map.Entry<String, AuthorizationClassEnum> entry : PATH_PERMISSION_MAP.entrySet()) {
            String prefix = entry.getKey();
            if (path.startsWith(prefix + "/") || path.equals(prefix)) {
                return entry.getValue();
            }
        }
        
        // 3. 特殊路径匹配
        if (path.endsWith("/")) {
            String normalizedPath = path.substring(0, path.length() - 1);
            return findRequiredPermission(normalizedPath);
        }
        
        return null;
    }
}
