from pathlib import Path
from typing import Optional, Dict, Any
from backend.integrations.dossierai_client import DossierAIClient
from backend.integrations.siliconflow_client import SiliconFlowClient


class InputHandler:
    """统一输入处理器 - 优先使用SiliconFlow转写，dossierai用于OCR和智能理解"""
    
    IMAGE_FORMATS = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'}
    AUDIO_FORMATS = {'.mp3', '.wav', '.m4a', '.ogg', '.flac', '.webm'}
    DOC_FORMATS = {'.pdf', '.docx', '.doc', '.txt', '.md'}
    DATA_FORMATS = {'.json', '.csv', '.xlsx', '.log'}
    
    def __init__(self, dossierai_client: DossierAIClient = None):
        self.dossierai = dossierai_client
        self.siliconflow = SiliconFlowClient()
    
    def detect_type(self, file_path: str) -> str:
        """检测输入类型"""
        ext = Path(file_path).suffix.lower()
        
        if ext in self.IMAGE_FORMATS:
            return 'image'
        elif ext in self.AUDIO_FORMATS:
            return 'audio'
        elif ext in self.DOC_FORMATS:
            return 'document'
        elif ext in self.DATA_FORMATS:
            return 'data'
        else:
            return 'unknown'
    
    async def process(self, file_path: str, question: Optional[str] = None) -> Dict[str, Any]:
        """统一处理入口"""
        input_type = self.detect_type(file_path)
        
        handlers = {
            'image': self._handle_image,
            'audio': self._handle_audio,
            'document': self._handle_document,
            'data': self._handle_data,
        }
        
        handler = handlers.get(input_type, self._handle_unknown)
        return await handler(file_path, question)
    
    async def process_text(self, text: str, question: Optional[str] = None) -> Dict[str, Any]:
        """处理纯文本输入"""
        content = text
        
        if question and self.dossierai:
            try:
                content = await self.dossierai.chat(question, text)
            except Exception:
                content = text
        
        return {
            'type': 'text',
            'content': content,
            'entities': await self._extract_entities(content)
        }
    
    async def _handle_image(self, file_path: str, question: Optional[str] = None) -> Dict[str, Any]:
        """处理图片 - 优先使用dossierai OCR，本地pytesseract fallback"""
        result = {}
        extracted_text = ""
        
        # 优先尝试dossierai
        if self.dossierai:
            try:
                result = await self.dossierai.parse_document(file_path)
                extracted_text = result.get('text', '')
            except Exception as e:
                print(f"DossierAI OCR失败: {e}")
                extracted_text = await self._local_ocr(file_path)
        else:
            # 没有dossierai，直接用本地OCR
            extracted_text = await self._local_ocr(file_path)
        
        content = extracted_text
        if question and self.dossierai:
            try:
                content = await self.dossierai.chat(question, extracted_text)
            except Exception:
                content = extracted_text
        
        return {
            'type': 'image',
            'file': file_path,
            'content': content,
            'extracted_text': extracted_text,
            'raw_result': result,
            'entities': await self._extract_entities(content)
        }
    
    async def _local_ocr(self, file_path: str) -> str:
        """本地OCR（pytesseract fallback）"""
        try:
            from PIL import Image
            import pytesseract
            image = Image.open(file_path)
            text = pytesseract.image_to_string(image, lang='chi_sim+eng')
            return text.strip()
        except ImportError:
            return "[图片OCR需要安装pytesseract: pip install pytesseract]"
        except Exception as e:
            return f"[图片OCR失败: {str(e)}]"
    
    async def _handle_audio(self, file_path: str, question: Optional[str] = None) -> Dict[str, Any]:
        """处理音频 - 优先使用SiliconFlow转写（中文效果好）"""
        result = {}
        transcript = ""
        
        # 1. 优先使用SiliconFlow语音转写（中文效果更好）
        try:
            transcript = await self.siliconflow.transcribe_audio(file_path)
            print(f"SiliconFlow转写成功: {len(transcript)} 字符")
        except Exception as e:
            print(f"SiliconFlow转写失败: {e}")
            transcript = f"[音频转写失败: {str(e)}]"
        
        content = transcript
        if question and self.dossierai:
            try:
                content = await self.dossierai.chat(question, transcript)
            except Exception:
                content = transcript
        
        return {
            'type': 'audio',
            'file': file_path,
            'transcript': transcript,
            'content': content,
            'raw_result': result,
            'entities': await self._extract_entities(content)
        }
    
    async def _handle_document(self, file_path: str, question: Optional[str] = None) -> Dict[str, Any]:
        """处理文档 - 调用dossierai解析"""
        if not self.dossierai:
            return {
                'type': 'document',
                'file': file_path,
                'content': '[需要dossierai服务支持文档解析]',
                'error': 'dossierai not available',
                'entities': {}
            }
        
        result = await self.dossierai.parse_document(file_path)
        
        text = result.get('text', '')
        
        if question:
            try:
                content = await self.dossierai.chat(question, text)
            except Exception:
                content = text[:2000]
        else:
            content = text[:2000]
        
        return {
            'type': 'document',
            'file': file_path,
            'content': content,
            'extracted_text': text,
            'raw_result': result,
            'entities': await self._extract_entities(content)
        }
    
    async def _handle_data(self, file_path: str, question: Optional[str] = None) -> Dict[str, Any]:
        """处理数据文件"""
        data = self._parse_data(file_path)
        
        content = str(data)[:1000]
        if question and self.dossierai:
            try:
                content = await self.dossierai.chat(question, str(data))
            except Exception:
                content = str(data)[:1000]
        
        return {
            'type': 'data',
            'file': file_path,
            'content': content,
            'data': data,
            'entities': await self._extract_entities(content)
        }
    
    async def _handle_unknown(self, file_path: str, question: Optional[str] = None) -> Dict[str, Any]:
        return {
            'type': 'unknown',
            'file': file_path,
            'error': '不支持的文件类型'
        }
    
    async def _extract_entities(self, text: str) -> Dict[str, Any]:
        """调用dossierai进行意图识别/实体提取"""
        if not self.dossierai:
            return {}
        try:
            result = await self.dossierai.recognize_intent(text)
            return result
        except Exception:
            return {}
    
    def _parse_data(self, file_path: str) -> Dict[str, Any]:
        """解析数据文件"""
        ext = Path(file_path).suffix.lower()
        
        if ext == '.json':
            import json
            return json.loads(Path(file_path).read_text(encoding='utf-8'))
        elif ext == '.csv':
            return {'csv': '需要CSV解析器'}
        
        return {}
