"""
智能工牌能力分析与课程推荐服务 - Python 原生实现

功能：
- 分析员工与顾客的对话记录
- 评估多维度能力得分
- 基于能力短板推荐课程

提供稳定可靠的能力分析和课程推荐能力。
"""

import json
import logging
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional

from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.exceptions import ExternalServiceError

from .ai_service import AIService, AIResponse
from .llm_json_parser import parse_with_fallback, clean_llm_output
from .prompts.ability_analysis_prompts import (
    SYSTEM_PROMPT,
    USER_PROMPT,
    ABILITY_ANALYSIS_SCHEMA,
    ABILITY_DIMENSIONS,
)

logger = logging.getLogger(__name__)


# ==================== 数据结构 ====================

@dataclass
class AbilityDimension:
    """能力维度评分"""
    name: str
    score: float
    feedback: str


@dataclass
class CourseRecommendation:
    """课程推荐"""
    course_id: int
    course_name: str
    recommendation_reason: str
    priority: str  # high, medium, low
    match_score: float


@dataclass
class AbilityAnalysisResult:
    """能力分析结果"""
    success: bool
    total_score: float = 0.0
    ability_dimensions: List[AbilityDimension] = field(default_factory=list)
    course_recommendations: List[CourseRecommendation] = field(default_factory=list)
    ai_provider: str = ""
    ai_model: str = ""
    ai_tokens: int = 0
    ai_latency_ms: int = 0
    error: str = ""
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "success": self.success,
            "total_score": self.total_score,
            "ability_dimensions": [
                {"name": d.name, "score": d.score, "feedback": d.feedback}
                for d in self.ability_dimensions
            ],
            "course_recommendations": [
                {
                    "course_id": c.course_id,
                    "course_name": c.course_name,
                    "recommendation_reason": c.recommendation_reason,
                    "priority": c.priority,
                    "match_score": c.match_score,
                }
                for c in self.course_recommendations
            ],
            "ai_provider": self.ai_provider,
            "ai_model": self.ai_model,
            "ai_tokens": self.ai_tokens,
            "ai_latency_ms": self.ai_latency_ms,
            "error": self.error,
        }


@dataclass
class UserPositionInfo:
    """用户岗位信息"""
    position_id: int
    position_name: str
    code: str
    description: str
    skills: Optional[Dict[str, Any]]
    level: str
    status: str


@dataclass
class CourseInfo:
    """课程信息"""
    id: int
    name: str
    description: str
    category: str
    tags: Optional[List[str]]
    difficulty_level: int
    duration_hours: float


# ==================== 服务类 ====================

class AbilityAnalysisService:
    """
    智能工牌能力分析服务
    
    使用 Python 原生实现。
    
    使用示例：
    ```python
    service = AbilityAnalysisService()
    result = await service.analyze(
        db=db_session,
        user_id=1,
        dialogue_history="顾客：你好，我想了解一下你们的服务..."
    )
    print(result.total_score)
    print(result.course_recommendations)
    ```
    """
    
    def __init__(self):
        """初始化服务"""
        self.ai_service = AIService(module_code="ability_analysis")
    
    async def analyze(
        self,
        db: AsyncSession,
        user_id: int,
        dialogue_history: str
    ) -> AbilityAnalysisResult:
        """
        分析员工能力并推荐课程
        
        Args:
            db: 数据库会话（支持多租户，每个租户传入各自的会话）
            user_id: 用户ID
            dialogue_history: 对话记录
            
        Returns:
            AbilityAnalysisResult 分析结果
        """
        try:
            logger.info(f"开始能力分析 - user_id: {user_id}")
            
            # 1. 验证输入
            if not dialogue_history or not dialogue_history.strip():
                return AbilityAnalysisResult(
                    success=False,
                    error="对话记录不能为空"
                )
            
            # 2. 查询用户岗位信息
            user_positions = await self._get_user_positions(db, user_id)
            user_info_str = self._format_user_info(user_positions)
            
            logger.info(f"用户岗位信息: {len(user_positions)} 个岗位")
            
            # 3. 查询所有可选课程
            courses = await self._get_published_courses(db)
            courses_str = self._format_courses(courses)
            
            logger.info(f"可选课程: {len(courses)} 门")
            
            # 4. 调用 AI 分析
            ai_response = await self._call_ai_analysis(
                dialogue_history=dialogue_history,
                user_info=user_info_str,
                courses=courses_str
            )
            
            logger.info(
                f"AI 分析完成 - provider: {ai_response.provider}, "
                f"tokens: {ai_response.total_tokens}, latency: {ai_response.latency_ms}ms"
            )
            
            # 5. 解析 JSON 结果
            analysis_data = self._parse_analysis_result(ai_response.content, courses)
            
            # 6. 构建返回结果
            result = AbilityAnalysisResult(
                success=True,
                total_score=analysis_data.get("total_score", 0),
                ability_dimensions=[
                    AbilityDimension(
                        name=d.get("name", ""),
                        score=d.get("score", 0),
                        feedback=d.get("feedback", "")
                    )
                    for d in analysis_data.get("ability_dimensions", [])
                ],
                course_recommendations=[
                    CourseRecommendation(
                        course_id=c.get("course_id", 0),
                        course_name=c.get("course_name", ""),
                        recommendation_reason=c.get("recommendation_reason", ""),
                        priority=c.get("priority", "medium"),
                        match_score=c.get("match_score", 0)
                    )
                    for c in analysis_data.get("course_recommendations", [])
                ],
                ai_provider=ai_response.provider,
                ai_model=ai_response.model,
                ai_tokens=ai_response.total_tokens,
                ai_latency_ms=ai_response.latency_ms,
            )
            
            logger.info(
                f"能力分析完成 - user_id: {user_id}, total_score: {result.total_score}, "
                f"recommendations: {len(result.course_recommendations)}"
            )
            
            return result
            
        except Exception as e:
            logger.error(
                f"能力分析失败 - user_id: {user_id}, error: {e}",
                exc_info=True
            )
            return AbilityAnalysisResult(
                success=False,
                error=str(e)
            )
    
    async def _get_user_positions(
        self,
        db: AsyncSession,
        user_id: int
    ) -> List[UserPositionInfo]:
        """
        查询用户的岗位信息
        
        获取用户基本信息
        """
        query = text("""
            SELECT 
                p.id as position_id, 
                p.name as position_name, 
                p.code, 
                p.description,
                p.skills, 
                p.level, 
                p.status 
            FROM positions p 
            INNER JOIN position_members pm ON p.id = pm.position_id 
            WHERE pm.user_id = :user_id 
              AND pm.is_deleted = 0 
              AND p.is_deleted = 0
        """)
        
        result = await db.execute(query, {"user_id": user_id})
        rows = result.fetchall()
        
        positions = []
        for row in rows:
            # 解析 skills JSON
            skills = None
            if row.skills:
                if isinstance(row.skills, str):
                    try:
                        skills = json.loads(row.skills)
                    except json.JSONDecodeError:
                        skills = None
                else:
                    skills = row.skills
            
            positions.append(UserPositionInfo(
                position_id=row.position_id,
                position_name=row.position_name,
                code=row.code or "",
                description=row.description or "",
                skills=skills,
                level=row.level or "",
                status=row.status or ""
            ))
        
        return positions
    
    async def _get_published_courses(self, db: AsyncSession) -> List[CourseInfo]:
        """
        查询所有已发布的课程
        
        获取所有课程列表
        """
        query = text("""
            SELECT 
                id, 
                name, 
                description, 
                category, 
                tags, 
                difficulty_level, 
                duration_hours 
            FROM courses 
            WHERE status = 'published' 
              AND is_deleted = FALSE 
            ORDER BY sort_order
        """)
        
        result = await db.execute(query)
        rows = result.fetchall()
        
        courses = []
        for row in rows:
            # 解析 tags JSON
            tags = None
            if row.tags:
                if isinstance(row.tags, str):
                    try:
                        tags = json.loads(row.tags)
                    except json.JSONDecodeError:
                        tags = None
                else:
                    tags = row.tags
            
            courses.append(CourseInfo(
                id=row.id,
                name=row.name,
                description=row.description or "",
                category=row.category or "",
                tags=tags,
                difficulty_level=row.difficulty_level or 3,
                duration_hours=row.duration_hours or 0
            ))
        
        return courses
    
    def _format_user_info(self, positions: List[UserPositionInfo]) -> str:
        """格式化用户岗位信息为文本"""
        if not positions:
            return "暂无岗位信息"
        
        lines = []
        for p in positions:
            info = f"- 岗位：{p.position_name}（{p.code}）"
            if p.level:
                info += f"，级别：{p.level}"
            if p.description:
                info += f"\n  描述：{p.description}"
            if p.skills:
                skills_str = json.dumps(p.skills, ensure_ascii=False)
                info += f"\n  核心技能：{skills_str}"
            lines.append(info)
        
        return "\n".join(lines)
    
    def _format_courses(self, courses: List[CourseInfo]) -> str:
        """格式化课程列表为文本"""
        if not courses:
            return "暂无可选课程"
        
        lines = []
        for c in courses:
            info = f"- ID: {c.id}, 课程名称: {c.name}"
            if c.category:
                info += f", 分类: {c.category}"
            if c.difficulty_level:
                info += f", 难度: {c.difficulty_level}"
            if c.duration_hours:
                info += f", 时长: {c.duration_hours}小时"
            if c.description:
                # 截断过长的描述
                desc = c.description[:100] + "..." if len(c.description) > 100 else c.description
                info += f"\n  描述: {desc}"
            lines.append(info)
        
        return "\n".join(lines)
    
    async def _call_ai_analysis(
        self,
        dialogue_history: str,
        user_info: str,
        courses: str
    ) -> AIResponse:
        """调用 AI 进行能力分析"""
        # 构建用户消息
        user_message = USER_PROMPT.format(
            dialogue_history=dialogue_history,
            user_info=user_info,
            courses=courses
        )
        
        messages = [
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message}
        ]
        
        # 调用 AI（自动支持 4sapi → OpenRouter 降级）
        response = await self.ai_service.chat(
            messages=messages,
            temperature=0.7,  # 保持一定创意性
            prompt_name="ability_analysis"
        )
        
        return response
    
    def _parse_analysis_result(
        self,
        ai_output: str,
        courses: List[CourseInfo]
    ) -> Dict[str, Any]:
        """
        解析 AI 输出的分析结果 JSON
        
        使用 LLM JSON Parser 进行多层兜底解析
        """
        # 先清洗输出
        cleaned_output, rules = clean_llm_output(ai_output)
        if rules:
            logger.debug(f"AI 输出已清洗: {rules}")
        
        # 使用带 Schema 校验的解析
        parsed = parse_with_fallback(
            cleaned_output,
            schema=ABILITY_ANALYSIS_SCHEMA,
            default={"analysis": {}},
            validate_schema=True,
            on_error="default"
        )
        
        # 提取 analysis 部分
        analysis = parsed.get("analysis", {})
        
        # 后处理：验证课程推荐的有效性
        valid_course_ids = {c.id for c in courses}
        valid_recommendations = []
        
        for rec in analysis.get("course_recommendations", []):
            course_id = rec.get("course_id")
            if course_id in valid_course_ids:
                valid_recommendations.append(rec)
            else:
                logger.warning(f"推荐的课程ID不存在: {course_id}")
        
        analysis["course_recommendations"] = valid_recommendations
        
        # 确保能力维度完整
        existing_dims = {d.get("name") for d in analysis.get("ability_dimensions", [])}
        for dim_name in ABILITY_DIMENSIONS:
            if dim_name not in existing_dims:
                logger.warning(f"缺少能力维度: {dim_name}，使用默认值")
                analysis.setdefault("ability_dimensions", []).append({
                    "name": dim_name,
                    "score": 70,
                    "feedback": "暂无具体评价"
                })
        
        return analysis


# ==================== 全局实例 ====================

ability_analysis_service = AbilityAnalysisService()














