"""
Configuration loader for Elasticsearch MCP.
Supports:
1. profiles.json - Local configuration file
2. Environment variables - For sensitive data (hosts, username, password)
3. getpass() fallback - Interactive password input
"""
from __future__ import annotations

import getpass
import json
import os
import sys
from pathlib import Path

from .models import AppConfig, ConnectionProfile, EnvVars, SafetyConfig


# 配置文件路径
CONFIG_DIR = Path.home() / ".config" / "elasticsearch-client-mcp"
CONFIG_FILE = CONFIG_DIR / "profiles.json"
SETUP_COMPLETE_FLAG = CONFIG_DIR / ".setup_complete"


def _ensure_config_dir() -> None:
    """确保配置目录存在"""
    CONFIG_DIR.mkdir(parents=True, exist_ok=True)


def _parse_bool(val: str | None) -> bool:
    if val is None:
        return False
    return str(val).strip().lower() in ("1", "true", "yes", "on")


def load_safety_config() -> SafetyConfig:
    """从环境变量加载安全配置"""
    return SafetyConfig(
        read_only=_parse_bool(os.environ.get("ES_READ_ONLY")),
        max_search_size=int(os.environ.get("ES_MAX_SEARCH_SIZE", 100)),
        request_timeout=int(os.environ.get("ES_REQUEST_TIMEOUT", 30)),
    )


def _resolve_env_vars_refs(env_vars: EnvVars) -> EnvVars:
    """
    解析环境变量引用。
    返回新的 EnvVars，值为环境变量名（非实际值）。
    用于返回给 LLM 时只暴露变量名。
    """
    # EnvVars 中存储的就是变量名，不需要解析
    return env_vars


def _resolve_actual_values(env_vars: EnvVars) -> EnvVars:
    """
    解析环境变量引用，获取实际值。
    用于连接 ES 时获取真实配置。
    """
    resolved = EnvVars()
    if env_vars.hosts:
        resolved.hosts = os.environ.get(env_vars.hosts, "")
    if env_vars.username:
        resolved.username = os.environ.get(env_vars.username, "")
    if env_vars.password:
        resolved.password = os.environ.get(env_vars.password, "")
    return resolved


def _get_password_interactive(env_var_name: str | None) -> str:
    """交互式获取密码（fallback）"""
    if env_var_name:
        return getpass.getpass(f"Enter password for {env_var_name}: ")
    return getpass.getpass("Enter ES password: ")


def load_config() -> AppConfig:
    """加载完整配置"""
    _ensure_config_dir()

    config = AppConfig()

    # 1. 先尝试从 profiles.json 加载
    if CONFIG_FILE.exists():
        try:
            with open(CONFIG_FILE, "r", encoding="utf-8") as f:
                data = json.load(f)

            profiles = data.get("profiles", [])
            for p in profiles:
                env_vars_data = p.get("env_vars", {})
                env_vars = EnvVars(
                    hosts=env_vars_data.get("hosts"),
                    username=env_vars_data.get("username"),
                    password=env_vars_data.get("password"),
                )
                profile = ConnectionProfile(
                    name=p.get("name", ""),
                    env=p.get("env", "test"),
                    description=p.get("description"),
                    skip_product_check=p.get("skip_product_check", False),
                    env_vars=env_vars,
                )
                config.profiles.append(profile)

            config.has_prompted_setup = data.get("has_prompted_setup", False)
        except (json.JSONDecodeError, IOError) as e:
            print(f"Warning: Failed to load config from {CONFIG_FILE}: {e}", file=sys.stderr)

    # 2. 合并环境变量配置（TEST_ES_PROFILES 等）
    _load_env_profiles(config)

    # 3. 加载安全配置
    config.safety = load_safety_config()

    return config


def _load_env_profiles(config: AppConfig) -> None:
    """从环境变量加载额外配置（向后兼容）"""
    import json as _json

    for env_name in ("test", "uat", "prod"):
        key = f"{env_name.upper()}_ES_PROFILES"
        arr_json = os.environ.get(key)
        if not arr_json:
            continue
        try:
            arr = _json.loads(arr_json)
            if not isinstance(arr, list):
                continue
            for i, v in enumerate(arr):
                if not isinstance(v, dict):
                    continue

                # 检查是否已有同名 profile
                name = v.get("name") or f"{env_name}_{i}"
                existing = config.get_profile(name)
                if existing:
                    continue  # 跳过，已从 profiles.json 加载

                # 处理 hosts
                hosts = v.get("hosts", "")
                if not hosts:
                    continue

                # 构建 env_vars（直接存值，不引用环境变量）
                env_vars = EnvVars(hosts=hosts)
                if v.get("username"):
                    env_vars.username = v.get("username")
                if v.get("password"):
                    env_vars.password = v.get("password")

                profile = ConnectionProfile(
                    name=name,
                    env=env_name,
                    description=v.get("description"),
                    skip_product_check=v.get("skip_product_check", False),
                    env_vars=env_vars,
                )
                config.profiles.append(profile)
        except json.JSONDecodeError:
            pass


def save_profiles(profiles: list[ConnectionProfile], has_prompted_setup: bool = True) -> None:
    """保存 profiles 到配置文件"""
    _ensure_config_dir()

    data = {
        "profiles": [],
        "has_prompted_setup": has_prompted_setup,
    }

    for p in profiles:
        profile_dict = {
            "name": p.name,
            "env": p.env,
            "description": p.description,
            "skip_product_check": p.skip_product_check,
            "env_vars": {
                k: v for k, v in {
                    "hosts": p.env_vars.hosts,
                    "username": p.env_vars.username,
                    "password": p.env_vars.password,
                }.items() if v is not None
            },
        }
        data["profiles"].append(profile_dict)

    with open(CONFIG_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)

    # 创建 setup complete 标记
    SETUP_COMPLETE_FLAG.touch()


def need_setup() -> bool:
    """检查是否需要引导配置"""
    if not CONFIG_FILE.exists():
        return True
    if not SETUP_COMPLETE_FLAG.exists():
        return True
    return False


def get_connection_values(profile: ConnectionProfile) -> dict:
    """
    获取连接的完整配置值（用于实际连接）。
    敏感信息从环境变量读取。
    """
    values = {
        "hosts": profile.env_vars.hosts or "",
        "username": profile.env_vars.username or "",
        "password": profile.env_vars.password or "",
    }

    # 如果 password 是环境变量引用，尝试解析实际值
    if profile.env_vars.password and not values["password"]:
        # 尝试从环境变量获取
        actual_password = os.environ.get(profile.env_vars.password, "")
        if actual_password:
            values["password"] = actual_password
        else:
            # fallback 到交互式输入
            values["password"] = _get_password_interactive(profile.env_vars.password)

    return values


def generate_env_var_commands(profile: ConnectionProfile) -> str:
    """生成环境变量设置命令"""
    prefix = profile.name.upper().replace("-", "_").replace(" ", "_")
    lines = []

    if profile.env_vars.hosts:
        lines.append(f'export {profile.env_vars.hosts}="http://your-es-host:9200"')
    if profile.env_vars.username:
        lines.append(f'export {profile.env_vars.username}="your_username"')
    if profile.env_vars.password:
        lines.append(f'export {profile.env_vars.password}="your_password"')

    return "\n".join(lines)
