"""
智能体配置管理
每个智能体目录下有一个 config.yaml，定义人格、模型、记忆策略等。
"""

from pathlib import Path
from dataclasses import dataclass, field
from typing import Optional
import yaml


@dataclass
class MemoryConfig:
    """记忆系统配置"""
    max_recent_episodes: int = 10        # 最近 N 条对话作为近期记忆
    max_working_tokens: int = 2000       # 工作记忆 token 上限
    max_context_tokens: int = 8000       # 总上下文 token 上限
    summary_threshold_days: int = 30     # 超过 N 天的记忆自动压缩摘要
    summary_retention_days: int = 180    # 摘要保留天数
    semantic_decay_days: int = 90        # 低访问事实开始降权天数
    semantic_forget_days: int = 180      # 低价值事实遗忘天数
    consolidate_interval: int = 7        # 每 N 天自动整理一次记忆
    enable_semantic_search: bool = False # 是否启用语义搜索(需要 embedding 模型)


@dataclass
class VoiceConfig:
    """语音配置"""
    enabled: bool = False
    stt_provider: str = "tencent"        # tencent
    stt_region: str = "ap-guangzhou"     # 腾讯云地域
    stt_engine_model_type: str = "16k_zh"# 腾讯云 ASR 引擎模型
    stt_hotword_list: str = ""           # 临时热词: 词|权重,词|权重
    stt_hotword_id: str = ""             # 腾讯云热词表 ID
    stt_customization_id: str = ""       # 腾讯云自学习模型 ID
    stt_filter_dirty: int = 0            # 是否过滤脏词
    stt_filter_modal: int = 0            # 是否过滤语气词
    stt_filter_punc: int = 0             # 是否过滤标点
    stt_convert_num_mode: int = 1        # 阿拉伯数字智能转换
    tts_voice: str = "zh-CN-YunxiNeural" # TTS 音色(edge-tts)
    tts_rate: str = "+0%"                 # TTS 语速(edge-tts, 如 +10% / -10%)
    language: str = "zh"                  # 主要语言


@dataclass
class AgentConfig:
    """智能体配置"""
    name: str = "coco"
    description: str = ""
    owner_name: str = "公子"
    relationship: str = ""
    api_base: str = ""                    # 兼容旧配置；新配置改用用户级 models.yaml
    api_key: str = ""                     # 兼容旧配置；新配置改用用户级 models.yaml
    system_prompt: str = ""               # 系统提示词(可覆盖 IDENTITY.md)
    max_response_tokens: int = 2048
    memory: MemoryConfig = field(default_factory=MemoryConfig)
    voice: VoiceConfig = field(default_factory=VoiceConfig)

    @classmethod
    def from_yaml(cls, path: Path) -> "AgentConfig":
        """从 YAML 文件加载配置"""
        if not path.exists():
            return cls(name=path.parent.name)

        with open(path, "r", encoding="utf-8") as f:
            data = yaml.safe_load(f) or {}

        # 嵌套配置解析
        mem_data = data.pop("memory", {})
        voice_data = data.pop("voice", {})
        data.pop("model", None)
        api_base = str(data.pop("api_base", "") or "").strip().rstrip("/")
        api_key = str(data.pop("api_key", "") or "").strip()
        data.pop("temperature", None)
        data.pop("status", None)

        config = cls(**data)
        config.owner_name = str(config.owner_name or "公子").strip() or "公子"
        config.relationship = str(config.relationship or "").strip()
        config.api_base = api_base
        config.api_key = api_key
        config.memory = MemoryConfig(**{**MemoryConfig().__dict__, **mem_data})
        voice_defaults = VoiceConfig().__dict__
        voice_data = {key: value for key, value in voice_data.items() if key in voice_defaults}
        config.voice = VoiceConfig(**{**voice_defaults, **voice_data})
        return config

    def to_yaml(self, path: Path) -> None:
        """保存配置到 YAML"""
        data = {
            "name": self.name,
            "description": self.description,
            "owner_name": self.owner_name,
            "relationship": self.relationship,
            "system_prompt": self.system_prompt,
            "max_response_tokens": self.max_response_tokens,
            "memory": {
                "max_recent_episodes": self.memory.max_recent_episodes,
                "max_working_tokens": self.memory.max_working_tokens,
                "max_context_tokens": self.memory.max_context_tokens,
                "summary_threshold_days": self.memory.summary_threshold_days,
                "summary_retention_days": self.memory.summary_retention_days,
                "semantic_decay_days": self.memory.semantic_decay_days,
                "semantic_forget_days": self.memory.semantic_forget_days,
                "consolidate_interval": self.memory.consolidate_interval,
                "enable_semantic_search": self.memory.enable_semantic_search,
            },
            "voice": {
                "enabled": self.voice.enabled,
                "stt_provider": self.voice.stt_provider,
                "stt_region": self.voice.stt_region,
                "stt_engine_model_type": self.voice.stt_engine_model_type,
                "stt_hotword_list": self.voice.stt_hotword_list,
                "stt_hotword_id": self.voice.stt_hotword_id,
                "stt_customization_id": self.voice.stt_customization_id,
                "stt_filter_dirty": self.voice.stt_filter_dirty,
                "stt_filter_modal": self.voice.stt_filter_modal,
                "stt_filter_punc": self.voice.stt_filter_punc,
                "stt_convert_num_mode": self.voice.stt_convert_num_mode,
                "tts_voice": self.voice.tts_voice,
                "tts_rate": self.voice.tts_rate,
                "language": self.voice.language,
            },
        }
        with open(path, "w", encoding="utf-8") as f:
            yaml.dump(data, f, allow_unicode=True, default_flow_style=False)
