package com.infoepoch.pms.agent.platform.chat.application;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Locale;
import java.util.Set;

/**
 * 审批文本意图分类器。
 */
@Service
public class ApprovalIntentClassifier {

    /**
     * 明确同意/拒绝短语命中的高置信度阈值。
     */
    private static final double HIGH_CONFIDENCE = 0.98D;
    /**
     * 明确“修改”意图命中的置信度阈值。
     */
    private static final double EDIT_CONFIDENCE = 0.94D;
    /**
     * “修改 + 同意/拒绝”混合语义的置信度阈值。
     */
    private static final double MIXED_EDIT_CONFIDENCE = 0.92D;
    /**
     * 无法识别明确意图时的低置信度兜底值。
     */
    private static final double LOW_CONFIDENCE = 0.25D;

    private static final Set<String> APPROVE_PHRASES = Set.of(
            "同意",
            "批准",
            "通过",
            "approve",
            "yes",
            "ok",
            "确认提交"
    );

    private static final Set<String> REJECT_PHRASES = Set.of(
            "拒绝",
            "不通过",
            "取消提交",
            "reject",
            "no"
    );

    /**
     * 分类用户输入的审批意图。
     *
     * @param message 用户输入
     * @return 分类结果
     */
    public Result classify(String message) {
        String normalized = StringUtils.trimWhitespace(message);
        if (!StringUtils.hasText(normalized)) {
            return new Result(ApprovalIntent.NONE, LOW_CONFIDENCE);
        }

        String lowerCase = normalized.toLowerCase(Locale.ROOT);
        String canonical = canonicalize(normalized);
        boolean editIntent = containsEditKeyword(normalized, lowerCase);
        boolean approveIntent = isPureApprovePhrase(canonical);
        boolean rejectIntent = isPureRejectPhrase(canonical);

        if (editIntent && (rejectIntent || containsRejectKeyword(normalized, lowerCase)) && !approveIntent) {
            return new Result(ApprovalIntent.REJECT_AND_EDIT, MIXED_EDIT_CONFIDENCE);
        }
        if (editIntent && approveIntent && !rejectIntent) {
            return new Result(ApprovalIntent.EDIT, MIXED_EDIT_CONFIDENCE);
        }
        if (editIntent) {
            return new Result(ApprovalIntent.EDIT, EDIT_CONFIDENCE);
        }
        if (approveIntent && isPureCanonicalMatch(canonical, APPROVE_PHRASES)) {
            return new Result(ApprovalIntent.APPROVE, HIGH_CONFIDENCE);
        }
        if (rejectIntent && isPureCanonicalMatch(canonical, REJECT_PHRASES)) {
            return new Result(ApprovalIntent.REJECT, HIGH_CONFIDENCE);
        }
        return new Result(ApprovalIntent.NONE, LOW_CONFIDENCE);
    }

    /**
     * 判断文本中是否包含“修改类”关键词。
     *
     * @param normalized 原始文本（已 trim）
     * @param lowerCase  小写文本
     * @return true 表示命中修改意图关键词
     */
    private boolean containsEditKeyword(String normalized, String lowerCase) {
        return normalized.contains("修改")
                || normalized.contains("编辑")
                || normalized.contains("调整")
                || normalized.contains("改一下")
                || normalized.contains("改下")
                || normalized.contains("改成一下")
                || normalized.contains("改为一下")
                || normalized.contains("改成下")
                || normalized.contains("改为")
                || normalized.contains("改成")
                || normalized.contains("再改")
                || normalized.contains("重写")
                || normalized.contains("修正")
                || normalized.contains("变更")
                || normalized.contains("优化")
                || lowerCase.contains("edit")
                || lowerCase.contains("revise");
    }

    /**
     * 判断文本中是否包含“拒绝类”关键词。
     *
     * @param normalized 原始文本（已 trim）
     * @param lowerCase  小写文本
     * @return true 表示命中拒绝意图关键词
     */
    private boolean containsRejectKeyword(String normalized, String lowerCase) {
        return normalized.contains("拒绝")
                || normalized.contains("不通过")
                || normalized.contains("不同意")
                || normalized.contains("驳回")
                || normalized.contains("退回")
                || normalized.contains("取消提交")
                || lowerCase.contains("reject")
                || lowerCase.contains("decline");
    }

    /**
     * 判断是否为纯粹同意短语。
     *
     * @param canonical 规范化文本
     * @return true 表示匹配同意短语
     */
    private boolean isPureApprovePhrase(String canonical) {
        return APPROVE_PHRASES.contains(canonical);
    }

    /**
     * 判断是否为纯粹拒绝短语。
     *
     * @param canonical 规范化文本
     * @return true 表示匹配拒绝短语
     */
    private boolean isPureRejectPhrase(String canonical) {
        return REJECT_PHRASES.contains(canonical);
    }

    /**
     * 判断规范化文本是否完全匹配短语集合中的某一项。
     *
     * @param canonical 规范化文本
     * @param phrases   候选短语集合
     * @return true 表示完全匹配
     */
    private boolean isPureCanonicalMatch(String canonical, Set<String> phrases) {
        return phrases.contains(canonical);
    }

    /**
     * 对输入文本进行规范化，移除标点/符号/空白并转小写。
     *
     * @param value 原始文本
     * @return 规范化文本
     */
    private String canonicalize(String value) {
        return value.replaceAll("[\\p{P}\\p{S}\\s]+", "").toLowerCase(Locale.ROOT);
    }

    /**
     * 审批意图分类结果。
     *
     * @param intent     意图
     * @param confidence 置信度
     */
    public record Result(ApprovalIntent intent, double confidence) {
    }
}
