import os
import sys
from typing import List, Dict, Any
from pathlib import Path

# 确保能导入 rules 模块
current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, current_dir)

from config import DocLintConfig
from rules.base import BaseRule, Diagnostic
from rules.static import *
from rules.llm.typo import LLMTypoRule


class DocLintEngine:
    """文档检测引擎"""

    # 规则注册表：rule_id -> Rule Class
    RULE_REGISTRY = {
        "paired-punctuation": PairedPunctuationRule,
        "no-trailing-whitespace": NoTrailingWhitespaceRule,
        "heading-space": HeadingSpaceRule,
        "relative-link-check": RelativeLinkRule,
        "llm-chinese-typo": LLMTypoRule
    }

    def __init__(self, config: DocLintConfig):
        """
        初始化检测引擎
        :param config: 配置管理器实例
        """
        self.config = config
        self.rules = self._load_rules()

    def _load_rules(self) -> List[BaseRule]:
        """
        根据配置加载启用的规则
        :return: 规则实例列表
        """
        rules = []
        enabled_rules = self.config.get_all_enabled_rules()

        for rule_id in enabled_rules:
            rule_class = self.RULE_REGISTRY.get(rule_id)
            if rule_class:
                rule_config = self.config.get_rule_config(rule_id)
                rule_instance = rule_class(config=rule_config)
                rules.append(rule_instance)
                print(f"[INFO] 加载规则：{rule_id}")
            else:
                print(f"[WARN] 未找到规则实现：{rule_id}")

        return rules

    def check_file(self, file_path: str) -> List[Diagnostic]:
        """
        检查单个文件
        :param file_path: 文件路径
        :return: 诊断结果列表
        """
        if self.config.should_ignore_file(file_path):
            print(f"[SKIP] 忽略文件：{file_path}")
            return []

        if not os.path.exists(file_path):
            print(f"[WARN] 文件不存在：{file_path}")
            return []

        diagnostics = []

        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
        except Exception as e:
            print(f"[ERROR] 读取文件失败 {file_path}: {e}")
            return []

        print(f"[CHECK] 检查文件：{file_path}")

        for rule in self.rules:
            try:
                rule_diagnostics = rule.check(file_path, content)
                diagnostics.extend(rule_diagnostics)
            except Exception as e:
                print(f"[ERROR] 规则 {rule.rule_id} 执行失败：{e}")

        return diagnostics

    def check_files(self, file_paths: List[str]) -> List[Diagnostic]:
        """
        批量检查文件
        :param file_paths: 文件路径列表
        :return: 诊断结果列表
        """
        all_diagnostics = []

        for file_path in file_paths:
            diagnostics = self.check_file(file_path)
            all_diagnostics.extend(diagnostics)

        return all_diagnostics

    def get_rule_stats(self) -> Dict[str, Any]:
        """获取规则统计信息"""
        return {
            "total_rules": len(self.rules),
            "enabled_rules": [r.rule_id for r in self.rules],
            "config": {
                "llm_model": self.config.llm_config.get("model"),
                "ignore_patterns": self.config.ignore_patterns
            }
        }