# -*- coding: utf-8 -*-
"""
Quick Config CLI 工具
用于快速配置 LLM 平台信息（Claude/OpenAI）到 Jarvis 配置文件的 llms 部分
"""

import json
import yaml
from pathlib import Path
from typing import Optional
import typer
from rich.console import Console
import requests  # type: ignore

from .output import PrettyOutput
from .input import get_single_line_input, user_confirm

app = typer.Typer(help="快速配置 LLM 平台信息到 Jarvis 配置文件")
console = Console()


@app.command()
def quick_config(
    platform: Optional[str] = typer.Option(
        None, "--platform", "-p", help="LLM平台类型 (claude/openai)"
    ),
    base_url: Optional[str] = typer.Option(None, "--url", "-u", help="API基础URL"),
    api_key: Optional[str] = typer.Option(None, "--key", "-k", help="API密钥"),
    config_name: Optional[str] = typer.Option(
        None, "--name", "-n", help="配置名称，如果未指定将使用平台名称"
    ),
    output_file: Optional[Path] = typer.Option(
        None, "--output", "-o", help="输出配置文件路径，默认为~/.jarvis/config.yaml"
    ),
):
    """快速配置 LLM 平台信息到 Jarvis 配置文件的 llms 部分"""

    # 提示用户输入缺失的参数
    if platform is None:
        platform = get_single_line_input("请输入LLM平台类型 (claude/openai):")
    if base_url is None:
        base_url = get_single_line_input("请输入API基础URL:")
    if api_key is None:
        api_key = get_single_line_input("请输入API密钥:")

    # 验证平台类型
    platform = platform.lower().strip()
    if platform not in ["claude", "openai"]:
        PrettyOutput.auto_print(
            f"❌ 不支持的平台类型: {platform}，仅支持 claude 和 openai"
        )
        raise typer.Exit(code=1)

    # 如果未指定配置名称，使用平台名称
    if not config_name:
        config_name = platform

    PrettyOutput.auto_print(
        f"🚀 开始配置 {platform.upper()} 平台，配置名称: {config_name}"
    )

    # 测试API连接并获取模型列表
    models = get_models(platform, base_url, api_key)
    if not models:
        PrettyOutput.auto_print("⚠️  警告：无法获取模型列表，将使用默认模型名称")
        if platform == "claude":
            models = ["claude-3-5-sonnet-latest"]
        else:  # openai
            models = ["gpt-4o"]

    PrettyOutput.auto_print(
        f"📋 可用模型: {', '.join(models[:10])}{'...' if len(models) > 10 else ''}"
    )

    # 询问用户是否配置所有模型
    if len(models) > 1:
        console.print("[bold]可用模型列表:[/]")
        for i, model in enumerate(models, 1):
            console.print(f"  {i}. {model}")

        configure_all = user_confirm("是否配置所有模型？", default=False)

        if configure_all:
            selected_models = models
        else:
            model_choices = get_single_line_input(
                "请输入要配置的模型序号（用逗号分隔）:"
            )
            try:
                indices = [int(x.strip()) - 1 for x in model_choices.split(",")]
                selected_models = []
                for idx in indices:
                    if 0 <= idx < len(models):
                        selected_models.append(models[idx])
                    else:
                        PrettyOutput.auto_print(f"❌ 无效的模型序号: {idx + 1}")
                        raise typer.Exit(code=1)
                if not selected_models:
                    PrettyOutput.auto_print("❌ 没有选择任何有效模型")
                    raise typer.Exit(code=1)
            except ValueError:
                PrettyOutput.auto_print("❌ 请输入有效的数字序号，用逗号分隔")
                raise typer.Exit(code=1)
    else:
        # 单个模型情况，直接选择
        selected_models = [models[0]]

    PrettyOutput.auto_print(
        f"✅ 已选择 {len(selected_models)} 个模型: {', '.join(selected_models)}"
    )

    # 选择默认模型
    if len(selected_models) == 1:
        default_model = selected_models[0]
        PrettyOutput.auto_print(f"🎯 默认模型: {default_model}")
    else:
        console.print("[bold]请选择默认模型:[/]")
        for i, model in enumerate(selected_models, 1):
            console.print(f"  {i}. {model}")

        default_choice = get_single_line_input("请输入默认模型序号:")
        try:
            default_idx = int(default_choice.strip()) - 1
            if 0 <= default_idx < len(selected_models):
                default_model = selected_models[default_idx]
                PrettyOutput.auto_print(f"🎯 默认模型: {default_model}")
            else:
                PrettyOutput.auto_print(f"❌ 无效的模型序号: {default_choice}")
                raise typer.Exit(code=1)
        except ValueError:
            PrettyOutput.auto_print("❌ 请输入有效的数字序号")
            raise typer.Exit(code=1)

    # 设置默认输出文件
    if output_file is None:
        jarvis_dir = Path.home() / ".jarvis"
        output_file = jarvis_dir / "config.yaml"

    # 确保输出目录存在
    output_file.parent.mkdir(parents=True, exist_ok=True)

    # 读取现有配置
    config: dict = {}
    if output_file.exists():
        try:
            with open(output_file, "r", encoding="utf-8") as f:
                if output_file.suffix in (".yaml", ".yml"):
                    config = yaml.safe_load(f) or {}
                else:
                    config = json.load(f)
        except Exception as e:
            PrettyOutput.auto_print(f"⚠️  无法读取现有配置文件 {output_file}: {e}")
            if not user_confirm("是否继续创建新配置？", default=True):
                raise typer.Exit(code=0)

    # 初始化llms部分
    if "llms" not in config:
        config["llms"] = {}

    # 初始化llm_groups部分
    if "llm_groups" not in config:
        config["llm_groups"] = {}

    # 为每个选择的模型创建配置
    for i, model in enumerate(selected_models):
        if len(selected_models) == 1:
            # 单个模型使用指定的配置名称
            model_config_name = config_name
        else:
            # 多个模型使用配置名称+模型名的方式避免冲突
            model_config_name = (
                f"{config_name}_{model.replace('.', '_').replace('-', '_')}"
            )

        # 根据平台类型生成正确的配置键名
        if platform == "openai":
            llm_config_dict = {
                "openai_api_key": api_key,
                "openai_api_base": base_url,
            }
        elif platform == "claude":
            llm_config_dict = {
                "anthropic_api_key": api_key,
                "anthropic_base_url": base_url,
            }
        else:
            llm_config_dict = {
                f"{platform}_api_key": api_key,
                f"{platform}_base_url": base_url,
            }

        llm_config = {
            "platform": platform,
            "model": model,
            "max_input_token_count": 128000,
            "llm_config": llm_config_dict,
        }

        # 添加模型配置
        config["llms"][model_config_name] = llm_config

        # 如果是默认模型，创建llm_groups配置
        if model == default_model:
            # 使用模型名称作为组名，替换特殊字符
            group_name = model.replace(".", "_").replace("-", "_")
            # 创建模型组配置
            config["llm_groups"][group_name] = {"normal_llm": model_config_name}
            PrettyOutput.auto_print(
                f"✅ 已创建模型组 '{group_name}'，使用 {model_config_name} 作为默认模型"
            )

    PrettyOutput.auto_print(f"✅ 已为 {len(selected_models)} 个模型创建配置")

    # 设置默认模型组
    default_group_name = default_model.replace(".", "_").replace("-", "_")
    config["llm_group"] = default_group_name
    PrettyOutput.auto_print(f"✅ 已设置默认模型组为 '{default_group_name}'")

    # 保存配置文件
    try:
        if output_file.suffix in (".yaml", ".yml"):
            with open(output_file, "w", encoding="utf-8") as f:
                yaml.safe_dump(
                    config,
                    f,
                    allow_unicode=True,
                    default_flow_style=False,
                    sort_keys=False,
                )
        else:
            with open(output_file, "w", encoding="utf-8") as f:
                json.dump(config, f, indent=2, ensure_ascii=False)

        PrettyOutput.auto_print(f"✅ 配置已保存到 {output_file}")

    except Exception as e:
        PrettyOutput.auto_print(f"❌ 保存配置失败: {e}")
        raise typer.Exit(code=1)


def get_models(platform: str, base_url: str, api_key: str) -> list:
    """获取平台的模型列表"""
    try:
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }

        if platform == "openai":
            url = f"{base_url}/models" if not base_url.endswith("/models") else base_url
            response = requests.get(url, headers=headers, timeout=10)
            if response.status_code == 200:
                data = response.json()
                models = [item["id"] for item in data.get("data", [])]
                return models
        elif platform == "claude":
            # Claude API doesn't have a direct models endpoint, use a common model list
            # For Claude, we'll return a list of known Claude models
            known_claude_models = [
                "claude-3-5-sonnet-latest",
                "claude-3-5-sonnet-20241022",
                "claude-3-5-sonnet-20240620",
                "claude-3-opus-latest",
                "claude-3-opus-20240229",
                "claude-3-sonnet-latest",
                "claude-3-sonnet-20240229",
                "claude-3-haiku-latest",
                "claude-3-haiku-20240307",
            ]
            return known_claude_models
    except Exception as e:
        PrettyOutput.auto_print(f"⚠️  获取模型列表失败: {e}")

    return []


if __name__ == "__main__":
    app()
