"""
目录分类模块
使用正则表达式和关键词匹配对目录项进行分类
"""

import re

try:
    from ..config.config_loader import get_config
except ImportError:
    from config.config_loader import get_config


class LLMClassifier:
    """目录分类器（基于正则表达式和关键词匹配）"""
    
    def __init__(self, model_url=None, model_name=None, api_key=None):
        """
        初始化分类器
        
        参数:
            model_url: 模型API地址（已废弃，保留以兼容旧接口）
            model_name: 模型名称（已废弃，保留以兼容旧接口）
            api_key: API密钥（已废弃，保留以兼容旧接口）
        """
        self.config = get_config()
        self.category_mapping = self.config.category_mapping
        self.category_keywords = self.config.category_keywords
        
        # 预编译正则表达式模式以提高性能
        self._compile_patterns()
    
    def _compile_patterns(self):
        """预编译所有类别的正则表达式模式"""
        self.compiled_patterns = {}
        
        for category, rules in self.category_keywords.items():
            patterns = rules.get('patterns', [])
            compiled = []
            for pattern in patterns:
                try:
                    compiled.append(re.compile(pattern, re.IGNORECASE))
                except re.error as e:
                    print(f"  警告: 类别 '{category}' 的正则表达式 '{pattern}' 编译失败: {e}")
            self.compiled_patterns[category] = compiled
    
    def classify(self, toc_items, target_level=2):
        """
        对目录项进行智能分类（基于正则表达式和关键词匹配）
        
        参数:
            toc_items: 目录项列表
            target_level: 要分类的目标层级
            
        返回:
            dict: 分类结果
        """
        print(f"\n正在对{target_level}级目录进行智能分类...")
        
        # 筛选出指定层级的目录项
        filtered_items = [item for item in toc_items if item['level'] == target_level]
        
        if not filtered_items:
            print(f"  警告: 未找到{target_level}级目录项")
            return None
        
        print(f"  找到 {len(filtered_items)} 个{target_level}级目录项")
        print("  正在使用正则表达式和关键词进行匹配分类...")
        
        # 对每个目录项进行分类
        classified_items = []
        
        for item in filtered_items:
            title = item['title']
            category_cn = self._match_category(title)
            category_en = self.category_mapping.get(category_cn, "other")
            
            classified_items.append({
                'title': title,
                'page': item['page'],
                'level': item['level'],
                'category': category_cn,
                'category_code': category_en,
                'original': item.get('original', '')
            })
        
        print(f"  分类完成！共分类 {len(classified_items)} 个目录项")
        
        return {
            'items': classified_items,
            'total_count': len(classified_items),
            'target_level': target_level
        }
    
    def _match_category(self, title):
        """
        使用正则表达式和关键词匹配目录项标题，返回对应的类别
        
        参数:
            title: 目录项标题
            
        返回:
            str: 类别名称，如果未匹配到则返回"其它资料"
        """
        # 去掉开头的编号，便于匹配
        title_clean = self._remove_number_prefix(title)
        
        # 优先级1: 使用正则表达式匹配
        for category, patterns in self.compiled_patterns.items():
            for pattern in patterns:
                if pattern.search(title) or pattern.search(title_clean):
                    return category
        
        # 优先级2: 使用关键词匹配
        for category, rules in self.category_keywords.items():
            keywords = rules.get('keywords', [])
            for keyword in keywords:
                if keyword in title or keyword in title_clean:
                    return category
        
        # 默认返回"其它资料"
        return "其它资料"
    
    def _remove_number_prefix(self, title):
        """
        去掉标题开头的编号
        
        参数:
            title: 原始标题
            
        返回:
            str: 去掉编号后的标题
        """
        # 去掉开头的编号（如 "1 ", "1. ", "第一章 " 等）
        title_clean = re.sub(r'^[\d一二三四五六七八九十]+[、\.\s]+', '', title)
        title_clean = re.sub(r'^第[一二三四五六七八九十\d]+[章节条款]\s*', '', title_clean)
        title_clean = re.sub(r'^【\d+】\s*', '', title_clean)
        title_clean = re.sub(r'^〖\d+(?:\.\d+)*〗\s*', '', title_clean)
        return title_clean
    

