"""
Agent Presets - Agent 类型预设配置

定义不同类型 Agent 的工具权限和运行参数。
用户可通过 .agent/presets.json 覆盖或添加预设。
"""

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


@dataclass
class AgentPreset:
    """Agent 预设配置"""

    # 工具权限
    allowed_tools: Optional[List[str]] = None  # None 表示允许全部
    denied_tools: Optional[List[str]] = None   # 黑名单

    # 运行参数
    max_iterations: int = 30
    temperature: Optional[float] = None

    # System Prompt（完全自定义 system prompt；None = 使用默认模板 + skills）
    system_prompt: Optional[str] = None

    # Skills（注入 system prompt 的 skill 名称列表；None = 加载全部）
    skills: Optional[List[str]] = None

    # 描述
    description: Optional[str] = None


# 内置预设
_DEFAULT_SKILLS = ["planning", "research", "browser"]

AGENT_PRESETS = {
    "default": AgentPreset(
        allowed_tools=None,
        max_iterations=30,
        skills=_DEFAULT_SKILLS,
        description="默认 Agent，拥有全部工具权限",
    ),
    "delegate": AgentPreset(
        allowed_tools=None,
        max_iterations=30,
        skills=_DEFAULT_SKILLS,
        description="委托子 Agent，拥有全部工具权限（由 agent 工具创建）",
    ),
    "explore": AgentPreset(
        allowed_tools=["read", "glob", "grep", "list_files"],
        denied_tools=["write", "edit", "bash", "task"],
        max_iterations=15,
        skills=["planning"],
        description="探索型 Agent，只读权限，用于代码分析",
    ),
    "evaluate": AgentPreset(
        allowed_tools=["read_file", "grep_content", "glob_files", "goal"],
        max_iterations=10,
        skills=["planning"],
        description="评估型 Agent，只读权限，用于结果评估",
    ),
}


def get_preset(name: str) -> AgentPreset:
    """获取预设配置"""
    if name not in AGENT_PRESETS:
        raise ValueError(f"Unknown preset: {name}. Available: {list(AGENT_PRESETS.keys())}")
    return AGENT_PRESETS[name]


def register_preset(name: str, preset: AgentPreset) -> None:
    """注册自定义预设"""
    AGENT_PRESETS[name] = preset


def load_system_prompt_from_file(path: str) -> str:
    """
    从 .prompt 文件加载 system prompt

    Args:
        path: .prompt 文件路径（相对或绝对）

    Returns:
        system prompt 文本

    Raises:
        FileNotFoundError: 文件不存在
        ValueError: 文件格式错误或缺少 $system$ 分节
    """
    from agent.llm.prompts import load_prompt

    prompt_path = Path(path)
    if not prompt_path.is_absolute():
        # 相对路径：相对于当前工作目录
        prompt_path = Path.cwd() / prompt_path

    config, messages = load_prompt(prompt_path)

    if "system" not in messages:
        raise ValueError(f".prompt 文件缺少 $system$ 分节: {path}")

    return messages["system"]


def load_presets_from_json(json_path: str) -> None:
    """
    从 JSON 文件加载预设配置

    支持特殊字段：
    - system_prompt_file: 从 .prompt 文件加载 system prompt（相对于 JSON 文件所在目录）

    Args:
        json_path: presets.json 文件路径
    """
    import json

    json_path = Path(json_path)
    if not json_path.exists():
        raise FileNotFoundError(f"presets.json 不存在: {json_path}")

    with open(json_path, "r", encoding="utf-8") as f:
        presets_data = json.load(f)

    base_dir = json_path.parent

    for name, cfg in presets_data.items():
        # 处理 system_prompt_file
        if "system_prompt_file" in cfg:
            prompt_file = cfg.pop("system_prompt_file")
            prompt_path = base_dir / prompt_file
            cfg["system_prompt"] = load_system_prompt_from_file(str(prompt_path))

        preset = AgentPreset(**cfg)
        register_preset(name, preset)
