"""
本地智能分类器 - 用于快速分类和降级

提供基于规则和语义分析的本地分类，作为LLM分类的补充和降级方案。
"""
from __future__ import annotations

import re
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass

from foundation.observability.logger.loggering import review_logger as logger


@dataclass
class ClassificationRule:
    """分类规则"""
    pattern: str
    code: str
    confidence: float
    description: str


# 高置信度规则 (置信度 >= 0.9，可直接使用，跳过LLM)
HIGH_CONFIDENCE_RULES: List[ClassificationRule] = [
    # 编制依据
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*编制依据", "basis", 0.95, "编制依据章节"),
    ClassificationRule(r"^编制依据$", "basis", 0.95, "编制依据标题"),
    ClassificationRule(r"编制依据.*法律|编制依据.*法规|编制依据.*标准", "basis", 0.92, "编制依据含法规标准"),

    # 工程概况
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*工程概况", "overview", 0.95, "工程概况章节"),
    ClassificationRule(r"^工程概况$", "overview", 0.95, "工程概况标题"),
    ClassificationRule(r"工程概况.*地质|工程概况.*水文|工程概况.*周边", "overview", 0.92, "工程概况含地质水文"),

    # 施工计划
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*施工计划", "plan", 0.95, "施工计划章节"),
    ClassificationRule(r"^施工计划$", "plan", 0.95, "施工计划标题"),
    ClassificationRule(r"施工进度.*计划|施工.*进度计划", "plan", 0.92, "施工进度计划"),

    # 施工工艺技术
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*施工工艺技术", "technology", 0.95, "施工工艺技术章节"),
    ClassificationRule(r"^施工工艺技术$", "technology", 0.95, "施工工艺技术标题"),
    ClassificationRule(r"主要.*施工.*方法|施工.*工艺|施工.*技术", "technology", 0.90, "施工工艺技术相关"),

    # 安全保证措施
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*安全保证措施", "safety", 0.95, "安全保证措施章节"),
    ClassificationRule(r"^安全保证措施$", "safety", 0.95, "安全保证措施标题"),
    ClassificationRule(r"安全.*措施|安全.*保证|安全.*管理", "safety", 0.90, "安全措施相关"),
    ClassificationRule(r"危险源|风险辨识|应急预案", "safety", 0.92, "安全风险相关"),

    # 质量保证措施
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*质量保证措施", "quality", 0.95, "质量保证措施章节"),
    ClassificationRule(r"^质量保证措施$", "quality", 0.95, "质量保证措施标题"),
    ClassificationRule(r"质量.*措施|质量.*保证|质量.*管理", "quality", 0.90, "质量措施相关"),

    # 环境保证措施
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*环境保证措施", "environment", 0.95, "环境保证措施章节"),
    ClassificationRule(r"^环境保证措施$", "environment", 0.95, "环境保证措施标题"),
    ClassificationRule(r"环境.*保护|环保.*措施|文明施工|绿色施工", "environment", 0.92, "环境保护相关"),

    # 施工管理及作业人员配备与分工
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*施工管理.*人员.*分工", "management", 0.95, "施工管理人员分工章节"),
    ClassificationRule(r"^施工管理及作业人员配备与分工$", "management", 0.95, "施工管理人员分工标题"),
    ClassificationRule(r"施工管理.*人员|人员.*配备.*分工|组织.*保证|组织.*机构", "management", 0.90, "施工组织人员相关"),
    ClassificationRule(r"管理人员.*名单|专职.*安全员|特种.*作业.*人员", "management", 0.92, "人员配备相关"),

    # 验收要求
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*验收要求", "acceptance", 0.95, "验收要求章节"),
    ClassificationRule(r"^验收要求$", "acceptance", 0.95, "验收要求标题"),
    ClassificationRule(r"验收.*标准|验收.*程序|验收.*人员", "acceptance", 0.92, "验收相关"),

    # 其它资料
    ClassificationRule(r"第[一二三四五六七八九十百]+章\s*.*计算书", "other", 0.95, "计算书章节"),
    ClassificationRule(r"^计算书$", "other", 0.95, "计算书标题"),
    ClassificationRule(r"^图纸$|.*附图|.*附表", "other", 0.90, "图纸附图相关"),
]

# 二级标题关键词映射（用于辅助判断一级分类）
SECTION_KEYWORDS_MAP: Dict[str, List[str]] = {
    "basis": ["法律法规", "标准规范", "文件制度", "编制原则", "编制范围", "国家标准", "行业标准", "地方标准"],
    "overview": ["工程简介", "技术标准", "工程地质", "水文气象", "周边环境", "位置关系", "结构尺寸", "临时设施", "施工平面", "工期目标", "质量目标", "安全目标", "环境目标", "危险源", "风险", "参建单位"],
    "plan": ["施工进度", "材料计划", "设备计划", "劳动力", "安全费用", "安全生产费用"],
    "technology": ["施工方法", "技术参数", "材料规格", "工艺流程", "施工工序", "操作要点", "检查要求"],
    "safety": ["安全目标", "危险源", "安全组织", "技术措施", "监测监控", "应急预案", "组织保证"],
    "quality": ["质量目标", "质量组织", "技术措施", "检查验收", "质量保修"],
    "environment": ["环保", "文明施工", "绿色施工", "环境保护", "节能减排"],
    "management": ["施工管理人员", "专职安全员", "特种作业人员", "其他作业人员", "岗位职责", "组织保证", "人员配备"],
    "acceptance": ["验收标准", "验收程序", "验收人员", "验收条件"],
    "other": ["计算", "验算", "图纸", "附图", "附表"],
}

# 简单关键词映射（低置信度）
SIMPLE_KEYWORDS: Dict[str, str] = {
    "编制依据": "basis",
    "工程概况": "overview",
    "施工计划": "plan",
    "施工工艺": "technology",
    "安全保证": "safety",
    "质量保证": "quality",
    "环境保证": "environment",
    "施工管理": "management",
    "人员配备": "management",
    "组织保证": "management",
    "验收要求": "acceptance",
    "计算书": "other",
}


class SmartLocalClassifier:
    """智能本地分类器"""

    # 高置信度阈值 - 达到此值可直接使用，跳过LLM
    HIGH_CONFIDENCE_THRESHOLD = 0.90

    @classmethod
    def classify(cls, chapter_title: str, section_titles: List[str] = None) -> Optional[Tuple[str, float]]:
        """
        使用本地智能规则分类

        返回: (分类代码, 置信度) 或 None（无法确定）
        """
        if not chapter_title:
            return None

        title = chapter_title.strip()

        # 1. 高置信度规则匹配
        for rule in HIGH_CONFIDENCE_RULES:
            if re.search(rule.pattern, title, re.IGNORECASE):
                logger.debug(f"[本地分类] '{title}' 匹配规则 '{rule.description}' -> {rule.code} (置信度 {rule.confidence})")
                return rule.code, rule.confidence

        # 2. 辅助判断：通过二级标题关键词
        if section_titles:
            result = cls._classify_by_section_keywords(title, section_titles)
            if result:
                return result

        # 3. 简单关键词匹配（低置信度）
        for keyword, code in SIMPLE_KEYWORDS.items():
            if keyword in title:
                logger.debug(f"[本地分类] '{title}' 简单关键词匹配 '{keyword}' -> {code} (置信度 0.75)")
                return code, 0.75

        return None

    @classmethod
    def _classify_by_section_keywords(cls, chapter_title: str, section_titles: List[str]) -> Optional[Tuple[str, float]]:
        """通过二级标题关键词辅助分类"""
        section_text = " ".join(section_titles)
        scores: Dict[str, float] = {}

        for code, keywords in SECTION_KEYWORDS_MAP.items():
            matched = sum(1 for kw in keywords if kw in section_text)
            if matched > 0:
                scores[code] = matched / len(keywords)  # 归一化得分

        if not scores:
            return None

        best_code = max(scores, key=scores.get)
        best_score = scores[best_code]

        if best_score < 0.2:  # 至少匹配20%的关键词
            return None

        confidence = min(0.85, 0.6 + best_score * 0.4)
        logger.debug(f"[本地分类] '{chapter_title}' 通过二级标题匹配 -> {best_code} (置信度 {confidence:.2f})")
        return best_code, confidence

    @classmethod
    def is_high_confidence(cls, confidence: float) -> bool:
        """判断是否是高置信度结果（可直接使用，跳过LLM）"""
        return confidence >= cls.HIGH_CONFIDENCE_THRESHOLD


# 便捷函数
def classify_local(chapter_title: str, section_titles: List[str] = None) -> Optional[Tuple[str, float]]:
    """本地分类便捷函数"""
    return SmartLocalClassifier.classify(chapter_title, section_titles)
