#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
候选词数据模型
"""

from dataclasses import dataclass, field
from typing import List, Dict, Any, Optional
from enum import Enum


class CandidateSource(Enum):
    """候选词来源"""
    GLOBAL = "global"                   # 全局提取（整个how文件）
    CURRENT_POST = "current_post"       # 当前帖子


@dataclass
class Candidate:
    """候选词模型"""

    # 基本信息
    persona_feature_name: str           # 人设特征名称
    similarity: float                   # 相似度得分

    # 来源信息（关键！）
    source: CandidateSource             # 来源：global / current_post
    source_topic_point: Optional[str] = None  # 如果来自当前帖子，记录来源选题点名称

    # 元数据
    feature_type: str = ""              # 特征类型：标签/分类
    feature_level: str = ""             # 人设特征层级
    classification_path: str = ""        # 分类路径（用/分隔）
    match_reason: str = ""              # 匹配说明

    def to_dict(self) -> Dict[str, Any]:
        """转为字典（保存时使用）"""
        return {
            "persona_feature_name": self.persona_feature_name,
            "similarity": self.similarity,
            "source": self.source.value,
            "source_topic_point": self.source_topic_point,
            "feature_type": self.feature_type,
            "feature_level": self.feature_level,
            "classification_path": self.classification_path,
            "match_reason": self.match_reason
        }

    @staticmethod
    def from_dict(data: Dict[str, Any]) -> 'Candidate':
        """从字典创建"""
        source_str = data.get('source', 'global')
        source = CandidateSource(source_str) if source_str else CandidateSource.GLOBAL

        return Candidate(
            persona_feature_name=data.get('persona_feature_name', ''),
            similarity=data.get('similarity', 0.0),
            source=source,
            source_topic_point=data.get('source_topic_point'),
            feature_type=data.get('feature_type', ''),
            feature_level=data.get('feature_level', ''),
            classification_path=data.get('classification_path', ''),
            match_reason=data.get('match_reason', '')
        )

    def get_source_label(self) -> str:
        """获取来源标签（用于展示）"""
        return "当前帖子" if self.source == CandidateSource.CURRENT_POST else "全局"


@dataclass
class TopicPointCandidates:
    """选题点的候选词集合"""
    topic_point_name: str               # 选题点名称
    topic_point_level: str              # 选题点层级
    topic_point_description: str = ""   # 选题点描述
    candidates: List[Candidate] = field(default_factory=list)  # 候选词列表

    def to_dict(self) -> Dict[str, Any]:
        """转为字典"""
        return {
            "topic_point_name": self.topic_point_name,
            "topic_point_level": self.topic_point_level,
            "topic_point_description": self.topic_point_description,
            "candidates": [c.to_dict() for c in self.candidates],
            "statistics": {
                "total_candidates": len(self.candidates),
                "from_current_post": sum(
                    1 for c in self.candidates
                    if c.source == CandidateSource.CURRENT_POST
                ),
                "from_global": sum(
                    1 for c in self.candidates
                    if c.source == CandidateSource.GLOBAL
                )
            }
        }

    @staticmethod
    def from_dict(data: Dict[str, Any]) -> 'TopicPointCandidates':
        """从字典创建"""
        candidates = [
            Candidate.from_dict(c)
            for c in data.get('candidates', [])
        ]

        return TopicPointCandidates(
            topic_point_name=data.get('topic_point_name', ''),
            topic_point_level=data.get('topic_point_level', ''),
            topic_point_description=data.get('topic_point_description', ''),
            candidates=candidates
        )

    def get_top_n(self, n: int = 20) -> List[Candidate]:
        """获取Top N个候选词（按相似度降序）"""
        return sorted(
            self.candidates,
            key=lambda c: c.similarity,
            reverse=True
        )[:n]

    def filter_by_source(self, source: CandidateSource) -> List[Candidate]:
        """按来源过滤"""
        return [c for c in self.candidates if c.source == source]


@dataclass
class PostCandidates:
    """帖子的所有候选词"""
    post_id: str                        # 帖子ID
    topic_points_candidates: List[TopicPointCandidates] = field(default_factory=list)

    def to_dict(self) -> Dict[str, Any]:
        """转为字典"""
        total_candidates = sum(len(tpc.candidates) for tpc in self.topic_points_candidates)
        total_from_current = sum(
            len(tpc.filter_by_source(CandidateSource.CURRENT_POST))
            for tpc in self.topic_points_candidates
        )
        total_from_global = sum(
            len(tpc.filter_by_source(CandidateSource.GLOBAL))
            for tpc in self.topic_points_candidates
        )

        return {
            "post_id": self.post_id,
            "topic_points_candidates": [tpc.to_dict() for tpc in self.topic_points_candidates],
            "statistics": {
                "total_topic_points": len(self.topic_points_candidates),
                "total_candidates": total_candidates,
                "from_current_post": total_from_current,
                "from_global": total_from_global
            }
        }

    @staticmethod
    def from_dict(data: Dict[str, Any]) -> 'PostCandidates':
        """从字典创建"""
        tpc_list = [
            TopicPointCandidates.from_dict(tpc)
            for tpc in data.get('topic_points_candidates', [])
        ]

        return PostCandidates(
            post_id=data.get('post_id', ''),
            topic_points_candidates=tpc_list
        )

    def get_topic_point_candidates(self, topic_point_name: str) -> Optional[TopicPointCandidates]:
        """获取指定选题点的候选词"""
        for tpc in self.topic_points_candidates:
            if tpc.topic_point_name == topic_point_name:
                return tpc
        return None
