"""axi settings — view and edit axi configuration.

Modeled on Claude Code's settings UX:
  axi settings                              show all active settings
  axi settings get routing.default_mode     read a value
  axi settings set routing.default_mode auto
  axi settings --global set routing.cloud_provider openai
  axi settings reset routing.default_mode   remove project override
"""

from __future__ import annotations

import argparse
import sys
from typing import Any

from .store import _DEFAULTS, SettingsStore


def _fmt_value(v: Any) -> str:
    if isinstance(v, bool):
        return str(v).lower()
    return str(v)


def _print_table(settings: dict[str, Any]) -> None:
    """Print settings as a two-column table, grouped by section."""
    from collections import defaultdict

    sections: dict[str, dict[str, Any]] = defaultdict(dict)
    for k, v in sorted(settings.items()):
        parts = k.split(".", 1)
        section = parts[0] if len(parts) > 1 else "general"
        leaf = parts[1] if len(parts) > 1 else parts[0]
        sections[section][leaf] = v

    col_width = max((len(k) for s in sections.values() for k in s), default=20) + 2

    for section, items in sorted(sections.items()):
        print(f"\n  [{section}]")
        for key, val in sorted(items.items()):
            dotted = f"{section}.{key}"
            print(f"    {dotted:<{col_width}}  {_fmt_value(val)}")
    print()


def get_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="axi settings",
        description="View and edit axi configuration",
    )
    parser.add_argument(
        "--global", dest="global_scope", action="store_true",
        help="Operate on global settings (~/.neut/settings.toml)",
    )
    sub = parser.add_subparsers(dest="cmd")

    get_p = sub.add_parser("get", help="Read a setting value")
    get_p.add_argument("key", help="Dotted key, e.g. routing.default_mode")

    set_p = sub.add_parser("set", help="Write a setting value")
    set_p.add_argument("key", help="Dotted key, e.g. routing.default_mode")
    set_p.add_argument("value", help="New value")

    reset_p = sub.add_parser("reset", help="Remove a setting override")
    reset_p.add_argument("key", help="Dotted key to reset")

    sub.add_parser("edit", help="Open settings file in $EDITOR")

    return parser


def main():
    parser = get_parser()
    args = parser.parse_args()
    scope = "global" if args.global_scope else "project"
    store = SettingsStore()

    if args.cmd is None:
        # Show all settings
        settings = store.all()
        if args.global_scope:
            from .store import _GLOBAL_SETTINGS_PATH, _flatten, _load_toml
            settings = _flatten(_load_toml(_GLOBAL_SETTINGS_PATH))
        if not settings:
            print("\n  No settings configured. Using defaults.\n")
            settings = store.all()
        _print_table(settings)
        return

    if args.cmd == "get":
        val = store.get(args.key)
        if val is None:
            print("  (not set — no default)", file=sys.stderr)
            sys.exit(1)
        print(_fmt_value(val))
        return

    if args.cmd == "set":
        # Coerce common types
        raw = args.value
        if raw.lower() in ("true", "yes"):
            value: Any = True
        elif raw.lower() in ("false", "no"):
            value = False
        elif raw.startswith("[") and raw.endswith("]"):
            # Explicit list syntax: [a, b, c]
            value = [v.strip().strip("'\"") for v in raw[1:-1].split(",") if v.strip()]
        elif isinstance(_DEFAULTS.get(args.key), list):
            # Key's default is a list — parse comma-separated into list
            value = [v.strip() for v in raw.split(",") if v.strip()]
        else:
            try:
                value = int(raw)
            except ValueError:
                value = raw

        store.set(args.key, value, scope=scope)
        target = "~/.neut/settings.toml" if scope == "global" else ".neut/settings.toml"
        print(f"  {args.key} = {_fmt_value(value)}  →  {target}")
        return

    if args.cmd == "reset":
        removed = store.reset(args.key, scope=scope)
        if removed:
            print(f"  Removed override: {args.key} ({scope})")
        else:
            print(f"  {args.key} not set in {scope} scope (nothing to reset)")
        return

    if args.cmd == "edit":
        import os
        import subprocess

        from .store import _GLOBAL_SETTINGS_PATH, _PROJECT_SETTINGS_PATH

        path = _GLOBAL_SETTINGS_PATH if scope == "global" else _PROJECT_SETTINGS_PATH
        path.parent.mkdir(parents=True, exist_ok=True)
        if not path.exists():
            # Seed with current settings so the user has something to edit
            store_snapshot = store.all()
            from .store import _save_toml, _unflatten
            _save_toml(path, _unflatten(store_snapshot))

        editor = os.environ.get("EDITOR", os.environ.get("VISUAL", "vi"))
        subprocess.call([editor, str(path)])
        print(f"  Settings saved to {path}")
        return
