"""
基础处理器接口模块

定义所有处理器的基类，提供统一的处理接口
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, Optional, List
from pathlib import Path
import logging
import pandas as pd

from app.core.utils.log_utils import get_logger

logger = get_logger(__name__)


class BaseProcessor(ABC):
    """基础处理器接口 - 所有处理器的基类
    
    采用策略模式设计，每个处理器负责特定类型的文件处理
    """
    
    def __init__(self, config: Dict[str, Any]):
        """初始化处理器
        
        Args:
            config: 处理器配置字典
        """
        self.config = config
        self.name = self.__class__.__name__
        self.description = ""
        self._setup_logging()
    
    def _setup_logging(self):
        """设置处理器日志"""
        self.logger = logging.getLogger(f"{__name__}.{self.name}")
    
    @abstractmethod
    def can_process(self, file_path: Path) -> bool:
        """判断是否能处理该文件
        
        Args:
            file_path: 文件路径
            
        Returns:
            是否能处理该文件
        """
        pass
    
    @abstractmethod
    def process(self, input_file: Path, output_dir: Path) -> Optional[Path]:
        """处理文件，返回输出文件路径
        
        Args:
            input_file: 输入文件路径
            output_dir: 输出目录路径
            
        Returns:
            输出文件路径，处理失败返回None
        """
        pass
    
    @abstractmethod
    def get_required_columns(self) -> List[str]:
        """返回需要的列名列表
        
        Returns:
            列名列表
        """
        pass
    
    def validate_input(self, file_path: Path) -> bool:
        """验证输入文件有效性
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件是否有效
        """
        try:
            if not file_path.exists():
                self.logger.warning(f"文件不存在: {file_path}")
                return False
            
            if not file_path.is_file():
                self.logger.warning(f"不是文件: {file_path}")
                return False
            
            supported_extensions = self.get_supported_extensions()
            if supported_extensions and file_path.suffix.lower() not in supported_extensions:
                self.logger.warning(f"不支持的文件类型: {file_path.suffix}, 支持的类型: {supported_extensions}")
                return False
            
            return True
            
        except Exception as e:
            self.logger.error(f"验证文件时出错: {e}")
            return False
    
    def get_supported_extensions(self) -> List[str]:
        """获取支持的文件扩展名
        
        Returns:
            支持的扩展名列表，空列表表示支持所有类型
        """
        return []
    
    def get_output_filename(self, input_file: Path, suffix: str = "_processed") -> str:
        """生成输出文件名

        Args:
            input_file: 输入文件路径
            suffix: 文件名后缀

        Returns:
            输出文件名
        """
        return f"{input_file.stem}{suffix}{input_file.suffix}"

    def _read_excel_safely(self, file_path: Path, **kwargs) -> pd.DataFrame:
        """根据扩展名选择合适的读取引擎

        Args:
            file_path: 文件路径
            **kwargs: 传递给 pd.read_excel 的参数

        Returns:
            DataFrame

        Raises:
            Exception: 读取失败时抛出
        """
        suffix = file_path.suffix.lower()
        if suffix == '.xlsx':
            return pd.read_excel(file_path, engine='openpyxl', **kwargs)
        elif suffix == '.xls':
            try:
                return pd.read_excel(file_path, engine='xlrd', **kwargs)
            except Exception as e:
                self.logger.warning(f"读取xls失败，可能缺少xlrd: {e}")
                raise
        else:
            return pd.read_excel(file_path, **kwargs)
    
    def log_processing_start(self, input_file: Path):
        """记录处理开始日志"""
        self.logger.info(f"开始处理文件: {input_file}")
        self.logger.info(f"处理器: {self.name} - {self.description}")
    
    def log_processing_end(self, input_file: Path, output_file: Optional[Path] = None, success: bool = True):
        """记录处理结束日志"""
        if success:
            self.logger.info(f"处理完成: {input_file}")
            if output_file:
                self.logger.info(f"输出文件: {output_file}")
        else:
            self.logger.error(f"处理失败: {input_file}")
    
    def __str__(self) -> str:
        """字符串表示"""
        return f"{self.name}({self.description})"
    
    def __repr__(self) -> str:
        """详细字符串表示"""
        return f"{self.__class__.__module__}.{self.__class__.__name__}(name='{self.name}', description='{self.description}')"