#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
敏感词检测工具模块
提供全局单例的敏感词检测功能，支持异步并发调用
"""

import os
import asyncio
from pathlib import Path
from typing import List, Dict, Any, Optional
from .ac_automaton import SensitiveWordDetector
from foundation.observability.logger.loggering import review_logger as logger


class SensitiveWordChecker:
    """敏感词检测器全局管理类（单例模式）"""
    
    _instance = None
    _initialized = False
    _detector = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        """初始化检测器（仅执行一次）"""
        if self._initialized:
            return
        
        self._detector = SensitiveWordDetector()
        self._initialized = True
    
    @classmethod
    def initialize(cls, words_dir: Optional[str] = None) -> Dict[str, Any]:
        """初始化敏感词库
        
        Args:
            words_dir: 敏感词文件目录，默认使用项目内置目录
            
        Returns:
            Dict: 初始化统计信息
        """
        instance = cls()
        
        if words_dir is None:
            current_dir = Path(__file__).parent.parent
            words_dir = current_dir / 'sensitive_words'
        
        words_dir = str(words_dir)
        logger.info(f"初始化敏感词检测器，词库目录: {words_dir}")
        
        stats = instance._detector.load_words_from_directory(words_dir)
        
        logger.info(f"敏感词检测器初始化完成: {stats}")
        return stats
    
    @classmethod
    def check_text(cls, text: str) -> List[Dict[str, Any]]:
        """检测文本中的敏感词（同步方法）
        
        Args:
            text: 待检测文本
            
        Returns:
            List[Dict]: 检测结果列表，每项包含：
                - word: 敏感词
                - position: 起始位置
                - end_position: 结束位置
                - source: 词源
        """
        instance = cls()
        if not instance._initialized or instance._detector is None:
            logger.warning("敏感词检测器未初始化，请先调用 initialize() 方法")
            return []
        
        return instance._detector.ac_automaton.search(text)
    
    @classmethod
    async def check_text_async(cls, text: str) -> List[Dict[str, Any]]:
        """检测文本中的敏感词（异步方法）
        
        Args:
            text: 待检测文本
            
        Returns:
            List[Dict]: 检测结果列表
        """
        loop = asyncio.get_event_loop()
        return await loop.run_in_executor(None, cls.check_text, text)
    
    @classmethod
    def is_initialized(cls) -> bool:
        """检查是否已初始化"""
        instance = cls()
        return instance._initialized and instance._detector is not None


def check_sensitive_words(text: str) -> List[Dict[str, Any]]:
    """检测文本中的敏感词（同步函数）
    
    这是一个便捷函数，直接调用全局检测器
    
    Args:
        text: 待检测文本
        
    Returns:
        List[Dict]: 检测结果列表，每项包含：
            - word: 敏感词
            - position: 起始位置
            - end_position: 结束位置
            - source: 词源
            
    Example:
        >>> results = check_sensitive_words("这是一段测试文本")
        >>> if results:
        >>>     for item in results:
        >>>         print(f"发现敏感词: {item['word']} 位置: {item['position']}")
    """
    return SensitiveWordChecker.check_text(text)


async def check_sensitive_words_async(text: str) -> List[Dict[str, Any]]:
    """检测文本中的敏感词（异步函数）
    
    这是一个便捷函数，支持异步并发调用
    
    Args:
        text: 待检测文本
        
    Returns:
        List[Dict]: 检测结果列表
        
    Example:
        >>> results = await check_sensitive_words_async("这是一段测试文本")
        >>> if results:
        >>>     for item in results:
        >>>         print(f"发现敏感词: {item['word']} 位置: {item['position']}")
    """
    return await SensitiveWordChecker.check_text_async(text)


def format_check_results(results: List[Dict[str, Any]], text: str = None) -> Dict[str, Any]:
    """格式化检测结果
    
    Args:
        results: 检测结果列表
        text: 原始文本（可选）
        
    Returns:
        Dict: 格式化后的结果
    """
    if not results:
        return {
            'has_sensitive': False,
            'count': 0,
            'details': []
        }
    
    details = []
    for item in results:
        detail = {
            'word': item['word'],
            'position': item['position'],
            'end_position': item['end_position'],
            'source': item['source']
        }
        
        if text:
            start = max(0, item['position'] - 10)
            end = min(len(text), item['end_position'] + 10)
            detail['context'] = text[start:end]
        
        details.append(detail)
    
    return {
        'has_sensitive': True,
        'count': len(results),
        'details': details
    }

