from __future__ import annotations

import typer

from dattos_cli.config import (
    save_config, get_config, get_active_profile,
    get_profile_config_path, list_profiles, set_active_profile, ConfigError,
)
from dattos_cli.output import print_json, print_error

app = typer.Typer(help="Manage CLI configuration.", no_args_is_help=True)

ALLOWED_KEYS = {"api-url": "api_url", "api-key": "api_key", "folder-id": "folder_id"}


@app.command("set")
def set_config(
    key: str = typer.Argument(help="Config key (api-url, api-key, folder-id). For api-url, you can pass just the instance name (e.g. 'my-company') and it expands to the full URL."),
    value: str = typer.Argument(help="Value to set"),
):
    """Set a configuration value in ~/.dattos/config.json."""
    mapped = ALLOWED_KEYS.get(key)
    if not mapped:
        from dattos_cli.output import print_error
        print_error("invalid_key", f"Unknown key: {key}. Allowed: {', '.join(ALLOWED_KEYS)}", 1)
        raise typer.Exit(1)
    if mapped == "api_url" and not value.startswith("http"):
        import re
        if not re.match(r'^[a-zA-Z0-9-]+$', value):
            print_error("invalid_value", "Instance name must be alphanumeric with hyphens only", 1)
            raise typer.Exit(1)
        value = f"https://{value}.dattos.com.br/dattos.api"
    if mapped == "api_key":
        from dattos_cli.credentials import store_secret
        from dattos_cli.config import _load_profile_config, _write_profile_config
        stored = store_secret(get_active_profile(), "api_key", value)
        if stored:
            # Remove from file config (it's in keyring now)
            cfg = _load_profile_config()
            cfg.pop("api_key", None)
            _write_profile_config(cfg)
            display_value = value[:4] + "***"
            print_json({"key": key, "value": display_value, "status": "saved", "storage": "keyring"})
            return
    save_config(mapped, value)
    display_value = value[:4] + "***" if mapped == "api_key" else value
    print_json({"key": key, "value": display_value, "status": "saved"})


@app.command("show")
def show_config():
    """Show the current resolved configuration (API key is masked)."""
    try:
        cfg = get_config()
    except ConfigError as e:
        print_error("config_error", str(e), 2)
        raise typer.Exit(2)
    masked_key = "***" + cfg.api_key[-4:] if len(cfg.api_key) > 4 else "***"
    print_json({
        "profile": get_active_profile(),
        "api_url": cfg.api_url,
        "api_key": masked_key,
        "folder_id": cfg.folder_id or "(not set)",
        "folder_name": cfg.folder_name or "(not set)",
    })


# --- Profile subcommands ---

profile_app = typer.Typer(help="Manage configuration profiles.", no_args_is_help=True)
app.add_typer(profile_app, name="profile")


@profile_app.command("list")
def profile_list():
    """List all configuration profiles."""
    profiles = list_profiles()
    active = get_active_profile()
    print_json({"profiles": profiles, "active": active})


@profile_app.command("switch")
def profile_switch(
    name: str = typer.Argument(help="Profile name to switch to."),
):
    """Switch the active profile (creates it if it doesn't exist)."""
    profile_dir = get_profile_config_path(name).parent
    profile_dir.mkdir(parents=True, exist_ok=True)
    if not (profile_dir / "config.json").exists():
        (profile_dir / "config.json").write_text("{}")
    set_active_profile(name)
    print_json({"profile": name, "status": "active"})
