# -*- coding: utf-8 -*-
"""Config-related extended CLI commands."""

from __future__ import annotations

import argparse
from pathlib import Path
from typing import Any

from services.commands import (
    DEFAULT_CONFIG_FILE,
    PROJECT_CONFIG_FILE,
    USER_CONFIG_FILE,
    read_merged_config,
    sync_server_manager_config_templates,
)

from .common import (
    config_target_path,
    emit_json,
    is_json_output,
    is_sensitive_key,
    mask_config,
    print_kv,
    update_key_value_file,
)


def add_config_subparsers(parent: argparse.ArgumentParser) -> None:
    config_sub = parent.add_subparsers(dest="config_command", help="配置命令")

    cfg_path = config_sub.add_parser("path", help="显示配置目录路径")
    _add_json_flag(cfg_path)

    cfg_files = config_sub.add_parser("files", help="列出配置文件及存在状态")
    _add_json_flag(cfg_files)

    cfg_init = config_sub.add_parser("init", help="同步项目 .server_manager/config 模板")
    _add_json_flag(cfg_init)

    cfg_show = config_sub.add_parser("show", help="显示合并后的配置")
    cfg_show.add_argument("--server", "-s", help="服务器目录名；指定后叠加该服 kv.config")
    cfg_show.add_argument("--include-sensitive", action="store_true", help="包含密码等敏感字段")
    _add_json_flag(cfg_show)

    cfg_get = config_sub.add_parser("get", help="读取单个配置项")
    cfg_get.add_argument("key")
    cfg_get.add_argument("--server", "-s", help="服务器目录名；指定后叠加该服 kv.config")
    cfg_get.add_argument("--include-sensitive", action="store_true", help="允许输出敏感字段")
    _add_json_flag(cfg_get)

    cfg_set = config_sub.add_parser("set", help="设置项目 user.config 或单服 kv.config")
    cfg_set.add_argument("key")
    cfg_set.add_argument("value")
    cfg_set.add_argument("--server", "-s", help="写入指定服务器的 config/kv.config；默认写入项目 user.config")
    _add_json_flag(cfg_set)

    cfg_unset = config_sub.add_parser("unset", help="删除项目 user.config 或单服 kv.config 中的配置项")
    cfg_unset.add_argument("key")
    cfg_unset.add_argument("--server", "-s", help="从指定服务器的 config/kv.config 删除；默认从项目 user.config 删除")
    _add_json_flag(cfg_unset)


def handle_config(args: argparse.Namespace, cli: Any) -> None:
    sub = getattr(args, "config_command", None)
    if not sub:
        raise SystemExit("请指定 config 子命令：path/files/init/show/get/set/unset")
    if sub == "path":
        data = {"server_root": cli.server_root, "config_dir": str(cli.config_path)}
        if is_json_output(args):
            emit_json(data)
        else:
            print(data["config_dir"])
    elif sub == "files":
        _handle_config_files(args, cli)
    elif sub == "init":
        ok, err = sync_server_manager_config_templates(Path(cli.server_root))
        data = {"success": ok, "server_root": cli.server_root, "config_dir": str(cli.config_path), "error": err}
        if is_json_output(args):
            emit_json(data)
        else:
            print("✓ 配置模板已同步" if ok else f"✗ {err}")
    elif sub == "show":
        config = read_merged_config(cli.server_root, server_dir=args.server, run_dir=cli.run_dir)
        config = mask_config(config, include_sensitive=args.include_sensitive)
        data = {"server": args.server, "config": config}
        if is_json_output(args):
            emit_json(data)
        else:
            print_kv(config)
    elif sub == "get":
        config = read_merged_config(cli.server_root, server_dir=args.server, run_dir=cli.run_dir)
        value = config.get(args.key)
        if is_sensitive_key(args.key) and not args.include_sensitive:
            value = "***" if value is not None else None
        data = {"server": args.server, "key": args.key, "value": value, "exists": args.key in config}
        if is_json_output(args):
            emit_json(data)
        else:
            print("" if value is None else value)
    elif sub == "set":
        path = config_target_path(cli, args.server)
        if args.server and not path.exists():
            raise SystemExit(f"配置文件不存在: {path}")
        update_key_value_file(path, updates={args.key: args.value})
        data = {"success": True, "path": str(path), "key": args.key, "value": args.value}
        if is_json_output(args):
            emit_json(data)
        else:
            print(f"✓ 已写入: {path}")
    elif sub == "unset":
        path = config_target_path(cli, args.server)
        if not path.exists():
            raise SystemExit(f"配置文件不存在: {path}")
        update_key_value_file(path, unset_keys=[args.key])
        data = {"success": True, "path": str(path), "key": args.key}
        if is_json_output(args):
            emit_json(data)
        else:
            print(f"✓ 已删除: {args.key}")


def _handle_config_files(args: argparse.Namespace, cli: Any) -> None:
    config_dir = Path(cli.config_path)
    files = []
    files_to_check = [
        (DEFAULT_CONFIG_FILE, config_dir / DEFAULT_CONFIG_FILE),
        (PROJECT_CONFIG_FILE, Path(cli.server_root) / "config" / PROJECT_CONFIG_FILE),
        (USER_CONFIG_FILE, config_dir / USER_CONFIG_FILE),
        ("sys_game.config.example", config_dir / "sys_game.config.example"),
        ("sys_login.config.example", config_dir / "sys_login.config.example"),
        ("sys_center.config.example", config_dir / "sys_center.config.example"),
        ("sys_cross.config.example", config_dir / "sys_cross.config.example"),
        ("sys_client.config.example", config_dir / "sys_client.config.example"),
    ]
    for name, path in files_to_check:
        files.append({"name": name, "path": str(path), "exists": path.exists()})
    data = {"config_dir": str(config_dir), "files": files}
    if is_json_output(args):
        emit_json(data)
        return
    for item in files:
        print(f"{'OK' if item['exists'] else 'MISS':<5} {item['path']}")


def _add_json_flag(parser: argparse.ArgumentParser) -> None:
    from .common import add_json_flag

    add_json_flag(parser)
