package com.mosquito.project.permission;

import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

/**
 * 权限码解析器 - 支持PRD四段式与冒号格式兼容
 *
 * PRD四段式格式: module.resource.operation.dataScope (如 activity.index.view.ALL)
 * 冒号格式: module:operation (如 activity:view)
 *
 * 兼容策略:
 * - 四段式为canonical格式
 * - 冒号格式为别名，自动映射到四段式
 */
@Component
public class PermissionCodeResolver {

    // 四段式正则: module.resource.operation.dataScope
    private static final Pattern PRD_PATTERN = Pattern.compile("^[a-z]+\\.[a-z]+\\.[a-z]+\\.[A-Z]+$");

    // 冒号正则: module:operation
    private static final Pattern LEGACY_PATTERN = Pattern.compile("^[a-z]+:[a-z]+$");

    // 权限码别名映射表 (别名 -> 规范四段式)
    private final Map<String, String> aliasMapping = new ConcurrentHashMap<>();

    // 数据权限默认值映射
    private static final Map<String, String> DEFAULT_DATA_SCOPE = Map.of(
            "ALL", "ALL",
            "DEPARTMENT", "DEPARTMENT",
            "OWN", "OWN"
    );

    public PermissionCodeResolver() {
        initDefaultMappings();
    }

    /**
     * 初始化默认别名映射
     */
    private void initDefaultMappings() {
        // 仪表盘模块
        addAlias("dashboard:view", "dashboard.index.view.ALL");
        addAlias("dashboard:export", "dashboard.index.export.ALL");

        // 活动管理模块
        addAlias("activity:view", "activity.index.view.ALL");
        addAlias("activity:create", "activity.index.create.ALL");
        addAlias("activity:update", "activity.index.update.ALL");
        addAlias("activity:delete", "activity.index.delete.ALL");
        addAlias("activity:publish", "activity.index.publish.ALL");
        addAlias("activity:pause", "activity.index.pause.ALL");
        addAlias("activity:resume", "activity.index.resume.ALL");
        addAlias("activity:end", "activity.index.end.ALL");
        addAlias("activity:export", "activity.index.export.ALL");

        // 用户管理模块
        addAlias("user:view", "user.index.view.ALL");
        addAlias("user:create", "user.index.create.ALL");
        addAlias("user:update", "user.index.update.ALL");
        addAlias("user:delete", "user.index.delete.ALL");
        addAlias("user:freeze", "user.index.freeze.ALL");
        addAlias("user:unfreeze", "user.index.unfreeze.ALL");
        addAlias("user:certify", "user.index.certify.ALL");
        addAlias("user:export", "user.index.export.ALL");

        // 奖励管理模块
        addAlias("reward:view", "reward.index.view.ALL");
        addAlias("reward:approve", "reward.index.approve.ALL");
        addAlias("reward:grant", "reward.index.grant.ALL");
        addAlias("reward:reject", "reward.index.reject.ALL");
        addAlias("reward:export", "reward.index.export.ALL");

        // 风险管理模块
        addAlias("risk:view", "risk.index.view.ALL");
        addAlias("risk:rule", "risk.rule.manage.ALL");
        addAlias("risk:audit", "risk.index.audit.ALL");
        addAlias("risk:blacklist", "risk.blacklist.manage.ALL");
        addAlias("risk:export", "risk.index.export.ALL");

        // 审批中心模块
        addAlias("approval:view", "approval.index.view.ALL");
        addAlias("approval:handle", "approval.index.handle.ALL");
        addAlias("approval:delegate", "approval.index.delegate.ALL");
        addAlias("approval:batch", "approval.index.batch.ALL");
        addAlias("approval:batch.handle", "approval.index.batch.handle.ALL");

        // PRD审批执行权限（approval.execute.*）
        addAlias("approval.execute.approve", "approval.execute.approve.ALL");
        addAlias("approval.execute.reject", "approval.execute.reject.ALL");
        addAlias("approval.execute.transfer", "approval.execute.transfer.ALL");

        // 审计日志模块
        addAlias("audit:view", "audit.index.view.ALL");
        addAlias("audit:export", "audit.index.export.ALL");

        // 系统配置模块
        addAlias("system:view", "system.index.view.ALL");
        addAlias("system:config", "system.config.manage.ALL");
        addAlias("system:cache", "system.cache.manage.ALL");

        // 权限管理模块
        addAlias("permission:view", "permission.index.view.ALL");
        addAlias("permission:manage", "permission.index.manage.ALL");
        addAlias("role:view", "role.index.view.ALL");
        addAlias("role:manage", "role.index.manage.ALL");
        addAlias("dept:view", "department.index.view.ALL");
        addAlias("dept:manage", "department.index.manage.ALL");

        // PRD用户权限管理（permission.user.*）
        addAlias("permission.user.assign", "permission.user.assign.ALL");
        addAlias("permission.user.revoke", "permission.user.revoke.ALL");

        // PRD数据权限配置（permission.data.*）
        addAlias("permission.data.config", "permission.data.config.ALL");

        // 通知管理模块
        addAlias("notification:view", "notification.index.view.ALL");
        addAlias("notification:manage", "notification.index.manage.ALL");

        // 敏感数据访问权限
        addAlias("sensitive:access", "system.sensitive.access.ALL");

        // 风控规则按钮级权限
        addAlias("risk.rule.create", "risk.rule.create.ALL");
        addAlias("risk.rule.edit", "risk.rule.edit.ALL");
        addAlias("risk.rule.delete", "risk.rule.delete.ALL");
        addAlias("risk.rule.enable", "risk.rule.enable.ALL");

        // 仪表盘监控权限
        addAlias("dashboard.monitor.view", "dashboard.monitor.view.ALL");
        addAlias("dashboard.chart.realtime", "dashboard.chart.realtime.ALL");
        addAlias("dashboard.chart.history", "dashboard.chart.history.ALL");
        addAlias("dashboard.kpi.config", "dashboard.kpi.config.ALL");

        // 风险拦截权限
        addAlias("risk.block.execute", "risk.block.execute.ALL");
        addAlias("risk.block.release", "risk.block.release.ALL");

        // 用户标签权限（规范化到四段式）
        addAlias("user.tag.add", "user.tag.add.ALL");
        addAlias("user.tag.view", "user.tag.view.ALL");

        // API Key细粒度权限（规范化到四段式）
        addAlias("system.api-key.create", "system.api-key.create.ALL");
        addAlias("system.api-key.view", "system.api-key.view.ALL");
        addAlias("system.api-key.enable", "system.api-key.enable.ALL");
        addAlias("system.api-key.disable", "system.api-key.disable.ALL");
        addAlias("system.api-key.delete", "system.api-key.delete.ALL");
        addAlias("system.api-key.reset", "system.api-key.reset.ALL");
        addAlias("system.api-key.manage", "system.api-key.manage.ALL");

        // 活动模板和配置权限
        addAlias("activity.template.view", "activity.template.view.ALL");
        addAlias("activity.config.edit", "activity.config.edit.ALL");

        // PRD细粒度权限点（第一批）
        addAlias("activity.participant.view", "activity.participant.view.ALL");
        addAlias("risk.detail.view", "risk.detail.view.ALL");
        addAlias("risk.alert.handle", "risk.alert.handle.ALL");

        // 审批意见独立权限
        addAlias("approval.comment.add", "approval.comment.add.ALL");
    }

    /**
     * 添加权限码别名映射
     */
    public void addAlias(String alias, String canonical) {
        aliasMapping.put(alias.toLowerCase(), canonical);
    }

    /**
     * 解析权限码 - 统一转换为规范格式
     * 支持四段式(保持不变)和冒号格式(转换为四段式)
     */
    public String resolve(String permissionCode) {
        if (permissionCode == null || permissionCode.isBlank()) {
            return null;
        }

        String normalized = permissionCode.trim();

        // 已经是四段式格式，直接返回
        if (isPrdFormat(normalized)) {
            return normalized;
        }

        // 尝试从别名映射表查找
        String aliasKey = normalized.toLowerCase();
        if (aliasMapping.containsKey(aliasKey)) {
            return aliasMapping.get(aliasKey);
        }

        // 无法解析，返回原值（让后续校验失败）
        return normalized;
    }

    /**
     * 检查权限码是否为PRD四段式格式
     */
    public boolean isPrdFormat(String permissionCode) {
        return PRD_PATTERN.matcher(permissionCode).matches();
    }

    /**
     * 检查是否为无scope的权限码（如 dashboard.chart.realtime）
     * 格式: module.resource.operation (三段式)
     */
    public boolean isScopeLessFormat(String permissionCode) {
        if (permissionCode == null) return false;
        String[] parts = permissionCode.split("\\.");
        return parts.length == 3 &&
               !parts[2].equals("ALL") &&
               !parts[2].equals("DEPARTMENT") &&
               !parts[2].equals("OWN");
    }

    /**
     * 转换为带ALL的规范格式
     * 如 dashboard.chart.realtime -> dashboard.chart.realtime.ALL
     */
    public String toAllScopeFormat(String permissionCode) {
        if (permissionCode == null) return null;
        if (isPrdFormat(permissionCode)) {
            return permissionCode; // 已经是规范格式
        }
        if (isScopeLessFormat(permissionCode)) {
            return permissionCode + ".ALL";
        }
        // 尝试解析别名后再转换
        String resolved = resolve(permissionCode);
        if (resolved != null && isScopeLessFormat(resolved)) {
            return resolved + ".ALL";
        }
        return resolved;
    }

    /**
     * 转换为不带scope的格式
     * 如 dashboard.chart.realtime.ALL -> dashboard.chart.realtime
     */
    public String toScopeLessFormat(String permissionCode) {
        if (permissionCode == null) return null;
        String resolved = resolve(permissionCode);
        if (resolved == null) return null;

        // 如果已经是三段式，直接返回
        if (isScopeLessFormat(resolved)) {
            return resolved;
        }

        // 四段式且最后一段是ALL/DEPARTMENT/OWN，移除最后一段
        String[] parts = resolved.split("\\.");
        if (parts.length == 4) {
            String scope = parts[3].toUpperCase();
            if ("ALL".equals(scope) || "DEPARTMENT".equals(scope) || "OWN".equals(scope)) {
                return parts[0] + "." + parts[1] + "." + parts[2];
            }
        }
        return resolved;
    }

    /**
     * 检查权限码是否为冒号格式(旧格式)
     */
    public boolean isLegacyFormat(String permissionCode) {
        return LEGACY_PATTERN.matcher(permissionCode).matches();
    }

    /**
     * 批量解析权限码集合
     */
    public Set<String> resolveAll(Set<String> permissionCodes) {
        return permissionCodes.stream()
                .map(this::resolve)
                .filter(code -> code != null && !code.isBlank())
                .collect(java.util.stream.Collectors.toSet());
    }

    /**
     * 检查两个权限码是否匹配（考虑别名）
     */
    public boolean matches(String code1, String code2) {
        String resolved1 = resolve(code1);
        String resolved2 = resolve(code2);
        return resolved1 != null && resolved1.equals(resolved2);
    }

    /**
     * 获取数据权限范围
     * 从四段式格式中提取最后一段
     */
    public String extractDataScope(String permissionCode) {
        String resolved = resolve(permissionCode);
        if (resolved == null) {
            return "OWN"; // 默认个人权限
        }

        String[] parts = resolved.split("\\.");
        if (parts.length >= 4) {
            String scope = parts[3].toUpperCase();
            return DEFAULT_DATA_SCOPE.getOrDefault(scope, "OWN");
        }

        return "OWN";
    }
}
