#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
统一文档结构定义

整合一/二/三级分类结果，提供标准化的文档数据结构
"""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Dict, List, Optional


@dataclass
class OutlineItem:
    """大纲单项（一级+二级结构）"""
    first_seq: int
    first_code: str
    first_name: str
    second_seq: int
    second_code: str
    second_name: str

    # 可选：原始标题（来自文档目录）
    raw_title: str = ""

    # 可选：页码信息
    page: int = 0


@dataclass
class Outline:
    """文档大纲结构"""
    # 扁平化大纲列表（按顺序）
    items: List[OutlineItem] = field(default_factory=list)

    # 按一级分类分组的大纲
    @property
    def grouped_by_first(self) -> Dict[str, List[OutlineItem]]:
        """按一级分类代码分组"""
        result: Dict[str, List[OutlineItem]] = {}
        for item in self.items:
            if item.first_code not in result:
                result[item.first_code] = []
            result[item.first_code].append(item)
        return result

    def to_dict(self) -> List[Dict[str, Any]]:
        """转换为字典列表"""
        return [
            {
                "first_seq": item.first_seq,
                "first_code": item.first_code,
                "first_name": item.first_name,
                "second_seq": item.second_seq,
                "second_code": item.second_code,
                "second_name": item.second_name,
                "raw_title": item.raw_title,
                "page": item.page
            }
            for item in self.items
        ]

    @classmethod
    def from_dict(cls, data: List[Dict[str, Any]]) -> "Outline":
        """从字典列表创建"""
        items = [
            OutlineItem(
                first_seq=item.get("first_seq", 0),
                first_code=item.get("first_code", ""),
                first_name=item.get("first_name", ""),
                second_seq=item.get("second_seq", 0),
                second_code=item.get("second_code", ""),
                second_name=item.get("second_name", ""),
                raw_title=item.get("raw_title", ""),
                page=item.get("page", 0)
            )
            for item in data
        ]
        return cls(items=items)


@dataclass
class PrimaryClassification:
    """一级分类结果"""
    first_seq: int
    first_code: str
    first_name: str
    page: int
    level2_count: int
    level2_titles: List[str] = field(default_factory=list)
    confidence: float = 0.0


@dataclass
class SecondaryClassification:
    """二级分类结果（包含正文内容）"""
    # 一级分类信息
    first_seq: int
    first_code: str
    first_name: str

    # 二级分类信息
    second_seq: int
    second_code: str
    second_name: str

    # 正文内容
    second_content: str = ""

    # 位置信息
    page_start: int = 0
    page_end: int = 0
    line_start: int = 0
    line_end: int = 0

    # 章节标签（用于分组和展示）
    section_label: str = ""  # 如 "第一章编制依据->一、法律法规"

    # 附加元数据
    metadata: Dict[str, Any] = field(default_factory=dict)


@dataclass
class TertiaryItem:
    """三级分类单项"""
    third_seq: int
    third_code: str
    third_name: str

    # 在二级内容中的行号范围
    line_start: int
    line_end: int

    # 匹配到的正文内容
    content: str = ""

    # 匹配置信度
    confidence: float = 0.0


@dataclass
class TertiaryClassification:
    """三级分类结果（基于二级分类的再细分）"""
    # 继承的二级分类信息
    first_seq: int
    first_code: str
    first_name: str
    second_seq: int
    second_code: str
    second_name: str

    # 该二级分类下的所有三级分类
    third_items: List[TertiaryItem] = field(default_factory=list)

    # 分类统计
    total_lines: int = 0
    classified_lines: int = 0

    @property
    def coverage_rate(self) -> float:
        """分类覆盖率"""
        if self.total_lines == 0:
            return 0.0
        return self.classified_lines / self.total_lines


@dataclass
class UnifiedDocumentStructure:
    """
    统一文档结构

    整合文档处理全流程的数据：
    - 一级分类：章级目录分类
    - 二级分类：节级目录分类 + 正文内容
    - 三级分类：标准细项分类
    """

    # ========== 文档元信息 ==========
    document_id: str = ""
    document_name: str = ""
    total_pages: int = 0
    total_lines: int = 0
    processing_timestamp: str = field(default_factory=lambda: datetime.now().isoformat())

    # ========== 三级分类结果 ==========
    primary_classifications: List[PrimaryClassification] = field(default_factory=list)
    secondary_classifications: List[SecondaryClassification] = field(default_factory=list)
    tertiary_classifications: List[TertiaryClassification] = field(default_factory=list)

    # ========== 文档大纲 ==========
    outline: Outline = field(default_factory=Outline)

    # ========== 原始数据（可选） ==========
    raw_metadata: Dict[str, Any] = field(default_factory=dict)

    # ========== 便捷方法 ==========

    def get_secondary_by_code(self, second_code: str) -> Optional[SecondaryClassification]:
        """根据二级代码获取分类"""
        for sec in self.secondary_classifications:
            if sec.second_code == second_code:
                return sec
        return None

    def get_tertiary_by_secondary(self, second_code: str) -> Optional[TertiaryClassification]:
        """根据二级代码获取对应的三级分类"""
        for ter in self.tertiary_classifications:
            if ter.second_code == second_code:
                return ter
        return None

    def get_secondary_by_first(self, first_code: str) -> List[SecondaryClassification]:
        """获取指定一级分类下的所有二级分类"""
        return [sec for sec in self.secondary_classifications if sec.first_code == first_code]

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "document_id": self.document_id,
            "document_name": self.document_name,
            "total_pages": self.total_pages,
            "total_lines": self.total_lines,
            "processing_timestamp": self.processing_timestamp,
            "primary_classifications": [
                {
                    "first_seq": p.first_seq,
                    "first_code": p.first_code,
                    "first_name": p.first_name,
                    "page": p.page,
                    "level2_count": p.level2_count,
                    "level2_titles": p.level2_titles,
                    "confidence": p.confidence
                }
                for p in self.primary_classifications
            ],
            "secondary_classifications": [
                {
                    "first_seq": s.first_seq,
                    "first_code": s.first_code,
                    "first_name": s.first_name,
                    "second_seq": s.second_seq,
                    "second_code": s.second_code,
                    "second_name": s.second_name,
                    "second_content": s.second_content,
                    "page_start": s.page_start,
                    "page_end": s.page_end,
                    "line_start": s.line_start,
                    "line_end": s.line_end,
                    "section_label": s.section_label,
                    "metadata": s.metadata
                }
                for s in self.secondary_classifications
            ],
            "tertiary_classifications": [
                {
                    "first_seq": t.first_seq,
                    "first_code": t.first_code,
                    "first_name": t.first_name,
                    "second_seq": t.second_seq,
                    "second_code": t.second_code,
                    "second_name": t.second_name,
                    "third_items": [
                        {
                            "third_seq": item.third_seq,
                            "third_code": item.third_code,
                            "third_name": item.third_name,
                            "line_start": item.line_start,
                            "line_end": item.line_end,
                            "content": item.content,
                            "confidence": item.confidence
                        }
                        for item in t.third_items
                    ],
                    "total_lines": t.total_lines,
                    "classified_lines": t.classified_lines,
                    "coverage_rate": t.coverage_rate
                }
                for t in self.tertiary_classifications
            ],
            "outline": self.outline.to_dict()
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "UnifiedDocumentStructure":
        """从字典创建实例"""
        return cls(
            document_id=data.get("document_id", ""),
            document_name=data.get("document_name", ""),
            total_pages=data.get("total_pages", 0),
            total_lines=data.get("total_lines", 0),
            processing_timestamp=data.get("processing_timestamp", datetime.now().isoformat()),
            primary_classifications=[
                PrimaryClassification(
                    first_seq=p["first_seq"],
                    first_code=p["first_code"],
                    first_name=p["first_name"],
                    page=p["page"],
                    level2_count=p["level2_count"],
                    level2_titles=p.get("level2_titles", []),
                    confidence=p.get("confidence", 0.0)
                )
                for p in data.get("primary_classifications", [])
            ],
            secondary_classifications=[
                SecondaryClassification(
                    first_seq=s["first_seq"],
                    first_code=s["first_code"],
                    first_name=s["first_name"],
                    second_seq=s["second_seq"],
                    second_code=s["second_code"],
                    second_name=s["second_name"],
                    second_content=s.get("second_content", ""),
                    page_start=s.get("page_start", 0),
                    page_end=s.get("page_end", 0),
                    line_start=s.get("line_start", 0),
                    line_end=s.get("line_end", 0),
                    section_label=s.get("section_label", ""),
                    metadata=s.get("metadata", {})
                )
                for s in data.get("secondary_classifications", [])
            ],
            tertiary_classifications=[
                TertiaryClassification(
                    first_seq=t["first_seq"],
                    first_code=t["first_code"],
                    first_name=t["first_name"],
                    second_seq=t["second_seq"],
                    second_code=t["second_code"],
                    second_name=t["second_name"],
                    third_items=[
                        TertiaryItem(
                            third_seq=item["third_seq"],
                            third_code=item["third_code"],
                            third_name=item["third_name"],
                            line_start=item["line_start"],
                            line_end=item["line_end"],
                            content=item.get("content", ""),
                            confidence=item.get("confidence", 0.0)
                        )
                        for item in t.get("third_items", [])
                    ],
                    total_lines=t.get("total_lines", 0),
                    classified_lines=t.get("classified_lines", 0)
                )
                for t in data.get("tertiary_classifications", [])
            ],
            outline=Outline.from_dict(data.get("outline", [])),
            raw_metadata=data.get("raw_metadata", {})
        )

    # ========== 统计信息 ==========

    @property
    def primary_count(self) -> int:
        """一级分类数量"""
        return len(self.primary_classifications)

    @property
    def secondary_count(self) -> int:
        """二级分类数量"""
        return len(self.secondary_classifications)

    @property
    def tertiary_count(self) -> int:
        """三级分类总数"""
        return sum(len(t.third_items) for t in self.tertiary_classifications)

    def get_summary(self) -> Dict[str, Any]:
        """获取处理摘要"""
        return {
            "document_name": self.document_name,
            "total_pages": self.total_pages,
            "primary_count": self.primary_count,
            "secondary_count": self.secondary_count,
            "tertiary_count": self.tertiary_count,
            "processing_timestamp": self.processing_timestamp
        }

    def to_legacy_dict(self) -> Dict[str, Any]:
        """
        转换为旧版字典格式（兼容 AI 审查工作流）

        Returns:
            Dict[str, Any]: 旧版格式的字典，包含 chunks, outline, document_name 等字段
        """
        # 构建三级分类查找映射 (first_code, second_code) -> [TertiaryItem]
        tertiary_map: Dict[tuple, List[TertiaryItem]] = {}
        for tert in self.tertiary_classifications:
            key = (tert.first_code, tert.second_code)
            tertiary_map[key] = tert.third_items

        # 构建 chunks 列表（从 secondary_classifications 转换）
        chunks = []
        for sec in self.secondary_classifications:
            # 获取对应的三级分类详情
            key = (sec.first_code, sec.second_code)
            third_items = tertiary_map.get(key, [])

            # 构建三级分类详情列表
            tertiary_details = []
            for item in third_items:
                tertiary_details.append({
                    "third_category_code": item.third_code,
                    "third_category_name": item.third_name,
                    "start_line": item.line_start,
                    "end_line": item.line_end,
                    "content": item.content,
                })

            chunk = {
                "chunk_id": f"{sec.first_code}_{sec.second_code}",
                "chapter_classification": sec.first_code,
                "secondary_category_code": sec.second_code,
                "section_label": sec.section_label,
                "content": sec.second_content,
                "review_chunk_content": sec.second_content,
                "page": sec.page_start,
                "page_start": sec.page_start,
                "page_end": sec.page_end,
                "line_start": sec.line_start,
                "line_end": sec.line_end,
                "first_name": sec.first_name,
                "second_name": sec.second_name,
                "metadata": sec.metadata,
                "tertiary_classification_details": tertiary_details,
            }
            # 向后兼容：如果只有一个三级分类，设置为主分类
            if len(tertiary_details) == 1:
                chunk["tertiary_category_code"] = tertiary_details[0]["third_category_code"]
                chunk["tertiary_category_cn"] = tertiary_details[0]["third_category_name"]
            chunks.append(chunk)

        # 构建 outline 结构（兼容旧格式）
        outline_chapters = []
        for item in self.outline.items:
            outline_chapters.append({
                "original": item.raw_title or f"{item.first_name}->{item.second_name}",
                "chapter": item.first_name,
                "subsections": []
            })

        return {
            "document_id": self.document_id,
            "document_name": self.document_name,
            "total_pages": self.total_pages,
            "total_lines": self.total_lines,
            "total_chunks": len(chunks),
            "processing_timestamp": self.processing_timestamp,
            "chunks": chunks,
            "outline": {"chapters": outline_chapters},
            "primary_classifications": self.to_dict().get("primary_classifications", []),
            "secondary_classifications": self.to_dict().get("secondary_classifications", []),
            "tertiary_classifications": self.to_dict().get("tertiary_classifications", []),
            "metadata": {
                "primary_count": self.primary_count,
                "secondary_count": self.secondary_count,
                "tertiary_count": self.tertiary_count,
            }
        }
