"""
错误识别审查器
直接使用提示词与文本块调用一次 LLM API。
"""

import ast
import json
import re
from pathlib import Path
from typing import Any, Dict, Optional

from detect.core.llm_client import LLMClient
from .prompt_builder import WordsPromptBuilder


class WordsErrorReviewer:
    """错别字/重复字审查器（单次 LLM 调用）"""

    def __init__(
        self,
        template_path: Optional[str] = None,
        config_path: Optional[str] = None,
    ):
        """
        初始化审查器

        Args:
            template_path: 提示词模板路径，默认使用 words_detect/错误识别.yaml
            config_path: LLM 配置路径，默认使用 words_detect/config/config.yaml
        """
        if template_path is None:
            template_path = Path(__file__).parent.parent / "错误识别.yaml"
        if config_path is None:
            config_path = Path(__file__).parent.parent / "config" / "config.yaml"

        self.prompt_builder = WordsPromptBuilder(template_path)
        self.llm_client = LLMClient(config_path)

    def review(self, content: str) -> Dict[str, Any]:
        """
        执行文本错误审查（单次 API 调用）

        Args:
            content: 待检查文本块

        Returns:
            {
              "prompt": 构建的提示词,
              "result": LLM 原始返回文本,
              "parsed_result": 解析得到的 JSON（若解析失败则为 None）
            }
        """
        prompt = self.prompt_builder.build_prompt(content)
        result_text = self.llm_client.review(prompt)
        parsed = self._extract_json_from_text(result_text)

        return {
            "prompt": prompt,
            "result": result_text,
            "parsed_result": parsed,
        }

    def _extract_json_from_text(self, text: str) -> Optional[Any]:
        """
        从 LLM 返回文本中提取 JSON 对象
        """
        if not text:
            return None

        candidates = []

        # 1) 直接尝试整体解析
        stripped = text.strip()
        candidates.append(stripped)

        # 2) ```json ... ``` 代码块
        fence_pattern = r"```(?:json)?\s*(\{[\s\S]*?\})\s*```"
        match = re.search(fence_pattern, text, re.DOTALL)
        if match:
            candidates.append(match.group(1))

        # 3) 最外层花括号或方括号截取（支持列表/对象）
        container_pattern = r"(\{[\s\S]*\}|\[[\s\S]*\])"
        match = re.search(container_pattern, text)
        if match:
            candidates.append(match.group(1))

        for candidate in candidates:
            try:
                return json.loads(candidate)
            except json.JSONDecodeError:
                # 兼容 Python 字面量格式 (列表/元组)
                try:
                    return ast.literal_eval(candidate)
                except Exception:
                    continue
        return None

