"""Govdoc Bridge — 结果适配器。

将 govdoc_engine 原始结果对象 (AuditResult / Finding / SemanticEntity)
映射为 ORM 模型字段和前端 VO 字典。
"""

from __future__ import annotations

from typing import Any

from fastapi_modules.fastapi_leaudit.govdoc_engine.engine.result import AuditResult


class ResultAdapter:
    """Govdoc 引擎结果 → 平台数据模型适配器。

    负责将 govdoc_engine 的原始执行结果转换为：
      - GovdocRun 状态字段更新
      - GovdocRuleResult 列表
      - GovdocReportArtifact 清单
      - 前端 VO 字典
    """

    def AdaptRunSummary(
        self,
        EngineResult: AuditResult,
        Structure: list[dict[str, Any]] | None = None,
        Outline: list[dict[str, Any]] | None = None,
        Entities: list[dict[str, Any]] | None = None,
    ) -> dict[str, Any]:
        """从 AuditResult.summary 提取 run 汇总字段。

        同时接受已适配的 structure / outline 列表，一并序列化进
        resultSummaryJson，供前端 structure-panel / outline-panel 读取。
        """
        import json

        s = EngineResult.summary
        aux: dict[str, Any] = {}
        if Structure is not None:
            aux["structure"] = Structure
        if Outline is not None:
            aux["outline"] = Outline
        if Entities is not None:
            aux["entities"] = {
                entity["name"]: entity for entity in Entities if entity.get("name")
            }

        return {
            "totalScore": s.score,
            "passedCount": s.passed_count,
            "failedCount": s.failed_count,
            "skippedCount": s.skipped_count,
            "resultStatus": "pass" if s.failed_count == 0 else "fail" if s.passed_count == 0 else "partial",
            "resultSummaryJson": json.dumps(aux, ensure_ascii=False) if aux else None,
        }

    def AdaptRuleResults(self, EngineResult: AuditResult) -> list[dict[str, Any]]:
        """从 AuditResult.findings 提取规则执行明细列表。"""
        results: list[dict[str, Any]] = []
        for f in EngineResult.findings:
            results.append({
                "ruleId": f.rule_id,
                "ruleName": f.rule_name,
                "severity": f.severity,
                "category": f.category,
                "message": f.message,
                "suggestion": f.suggestion,
                "actual": f.actual,
                "expected": f.expected,
                "evidence": f.evidence,
                "paragraphIndex": f.location.paragraph_index if f.location else None,
                "paragraphText": f.location.context if f.location else None,
                "locationPath": f.location.role if f.location else None,
                "result": "fail",
                "score": None,
            })
        return results

    def AdaptCheckedRules(self, EngineResult: AuditResult) -> list[dict[str, Any]]:
        """从 AuditResult.checked_rules 提取规则检查状态列表。"""
        results: list[dict[str, Any]] = []
        for cr in EngineResult.checked_rules:
            results.append({
                "ruleId": cr.rule_id,
                "ruleName": cr.name,
                "severity": cr.severity,
                "category": cr.category,
                "result": cr.status,  # pass/fail/skipped
                "skipReason": cr.skip_reason,
                "score": None,
            })
        return results

    def AdaptEntities(self, EngineResult: AuditResult) -> list[dict[str, Any]]:
        """从 AuditResult.entities 提取实体识别结果。"""
        entities: list[dict[str, Any]] = []
        for name, entity in EngineResult.entities.items():
            if entity is None:
                continue
            entities.append({
                "name": entity.name,
                "text": entity.text,
                "paragraphIndices": entity.paragraph_indices,
                "primaryRole": entity.primary_role,
                "source": entity.source,
                "confidence": entity.confidence,
                "extra": entity.extra,
            })
        return entities

    def AdaptStructure(self, EngineResult: AuditResult) -> list[dict[str, Any]]:
        """从 AuditResult.structure 提取文档结构统计。"""
        results: list[dict[str, Any]] = []
        for s in EngineResult.structure:
            results.append({
                "role": s.role,
                "label": s.label,
                "count": s.count,
                "expected": s.expected,
                "paragraphIndices": s.paragraph_indices,
                "samples": s.samples,
                "charTotal": s.char_total,
                "dominantFont": s.dominant_font,
                "dominantSizePt": s.dominant_size_pt,
                "styleUniform": s.style_uniform,
            })
        return results

    def AdaptOutline(self, EngineResult: AuditResult) -> list[dict[str, Any]]:
        """从 AuditResult.outline 提取大纲树（递归）。"""

        def _node(n) -> dict[str, Any]:
            return {
                "paragraphIndex": n.paragraph_index,
                "level": n.level,
                "text": n.text,
                "children": [_node(c) for c in (n.children or [])],
            }

        return [_node(n) for n in EngineResult.outline]

    def AdaptArtifacts(self, _EngineResult: AuditResult, _RunId: int) -> list[dict[str, Any]]:
        """从引擎结果提取报告产物清单。

        报告文件由 reporter 模块生成后上传 OSS。
        当前返回空列表，待 report_adapter 实现后补齐。
        """
        return []

    def BuildDetailVO(
        self,
        Document: Any,
        Run: Any,
        RuleResults: list[dict[str, Any]],
        Entities: list[dict[str, Any]],
        Artifacts: list[dict[str, Any]],
    ) -> dict[str, Any]:
        """构建前端详情页 VO。"""
        return {
            "document": Document,
            "run": Run,
            "findings": RuleResults,
            "entities": Entities,
            "reports": Artifacts,
        }
