"""
Dify API客户端
"""
import httpx
import json
from typing import Dict, Any, Optional, List
from datetime import datetime
import logging

from ....core.config import settings
from ....core.exceptions import ExternalServiceError

logger = logging.getLogger(__name__)


class DifyClient:
    """Dify API客户端"""
    
    def __init__(self):
        self.api_base = settings.DIFY_API_BASE.rstrip('/')
        self.api_key = settings.DIFY_API_KEY
        self.timeout = settings.DIFY_TIMEOUT
        
        self.headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
    async def run_workflow(
        self,
        workflow_id: str,
        inputs: Dict[str, Any],
        user: str,
        conversation_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        运行Dify工作流
        
        Args:
            workflow_id: 工作流ID
            inputs: 输入参数
            user: 用户标识
            conversation_id: 会话ID（可选）
            
        Returns:
            工作流执行结果
        """
        url = f"{self.api_base}/workflows/run"
        
        payload = {
            "workflow_id": workflow_id,
            "inputs": inputs,
            "user": user,
            "response_mode": "blocking"  # 同步模式
        }
        
        if conversation_id:
            payload["conversation_id"] = conversation_id
            
        try:
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                response = await client.post(
                    url,
                    json=payload,
                    headers=self.headers
                )
                response.raise_for_status()
                return response.json()
                
        except httpx.TimeoutException:
            logger.error(f"Dify API timeout: workflow_id={workflow_id}")
            raise ExternalServiceError("Dify服务响应超时")
        except httpx.HTTPStatusError as e:
            logger.error(f"Dify API error: {e.response.status_code} - {e.response.text}")
            raise ExternalServiceError(f"Dify服务错误: {e.response.status_code}")
        except Exception as e:
            logger.error(f"Dify API unexpected error: {str(e)}")
            raise ExternalServiceError("Dify服务异常")
            
    async def generate_exam_questions(
        self,
        workflow_id: str,
        course_id: Optional[int],
        question_count: int,
        difficulty: Optional[int],
        knowledge_points: Optional[List[str]],
        question_types: Optional[List[str]]
    ) -> List[Dict[str, Any]]:
        """
        生成考试题目
        
        Args:
            workflow_id: 考试工作流ID
            course_id: 课程ID
            question_count: 题目数量
            difficulty: 难度等级
            knowledge_points: 知识点列表
            question_types: 题型列表
            
        Returns:
            题目列表
        """
        inputs = {
            "question_count": question_count,
            "difficulty": difficulty or 3,
            "knowledge_points": json.dumps(knowledge_points or [], ensure_ascii=False),
            "question_types": json.dumps(question_types or [], ensure_ascii=False)
        }
        
        if course_id:
            inputs["course_id"] = str(course_id)
            
        # 生成唯一用户标识
        user = f"exam_user_{datetime.utcnow().timestamp()}"
        
        result = await self.run_workflow(
            workflow_id=workflow_id,
            inputs=inputs,
            user=user
        )
        
        # 解析结果
        if "data" in result and "outputs" in result["data"]:
            outputs = result["data"]["outputs"]
            if "questions" in outputs:
                # 假设Dify返回的questions是JSON字符串
                try:
                    questions = json.loads(outputs["questions"])
                    return questions
                except json.JSONDecodeError:
                    logger.error("Failed to parse questions from Dify")
                    return []
                    
        return []
        
    async def evaluate_answer(
        self,
        workflow_id: str,
        question: str,
        answer: str,
        correct_answer: str,
        question_type: str
    ) -> Dict[str, Any]:
        """
        评估答案（主观题）
        
        Args:
            workflow_id: 评估工作流ID
            question: 题目
            answer: 用户答案
            correct_answer: 参考答案
            question_type: 题型
            
        Returns:
            评估结果
        """
        inputs = {
            "question": question,
            "user_answer": answer,
            "correct_answer": correct_answer,
            "question_type": question_type
        }
        
        user = f"eval_user_{datetime.utcnow().timestamp()}"
        
        result = await self.run_workflow(
            workflow_id=workflow_id,
            inputs=inputs,
            user=user
        )
        
        # 解析评估结果
        if "data" in result and "outputs" in result["data"]:
            outputs = result["data"]["outputs"]
            return {
                "score": outputs.get("score", 0),
                "feedback": outputs.get("feedback", ""),
                "is_correct": outputs.get("is_correct", False)
            }
            
        return {
            "score": 0,
            "feedback": "评估失败",
            "is_correct": False
        }
        
    async def generate_exam_report(
        self,
        workflow_id: str,
        exam_data: Dict[str, Any]
    ) -> str:
        """
        生成考试报告
        
        Args:
            workflow_id: 报告工作流ID
            exam_data: 考试数据
            
        Returns:
            考试报告文本
        """
        inputs = {
            "exam_data": json.dumps(exam_data, ensure_ascii=False)
        }
        
        user = f"report_user_{datetime.utcnow().timestamp()}"
        
        result = await self.run_workflow(
            workflow_id=workflow_id,
            inputs=inputs,
            user=user
        )
        
        if "data" in result and "outputs" in result["data"]:
            return result["data"]["outputs"].get("report", "报告生成失败")
            
        return "报告生成失败"
