"""Administration commands.

    python -m cli.manage create-admin --email you@example.com --name "Your Name"
    python -m cli.manage create-center --slug sac --name "Sierra Avalanche Center" --afp-center-id SAC
    python -m cli.manage invite --email forecaster@example.com --center sac --role forecaster
    python -m cli.manage add-zone --center sac --name "Central Sierra Nevada"
"""

import getpass
import secrets
from datetime import UTC, datetime, timedelta

import typer

from app.auth import hash_password, token_hash
from app.configs import seed_default
from app.settings import get_settings

from .common import center_by_slug, connect

app = typer.Typer(no_args_is_help=True)


@app.command()
def create_admin(email: str = typer.Option(...), name: str = typer.Option(...), password: str = typer.Option(None)):
    """Create (or promote) a site administrator."""
    pw = password or getpass.getpass("Password (10+ characters): ")
    with connect() as conn:
        row = conn.execute(
            """INSERT INTO users (email, name, password_hash, is_admin) VALUES (%s, %s, %s, true)
               ON CONFLICT (email) DO UPDATE SET is_admin = true, password_hash = EXCLUDED.password_hash, name = EXCLUDED.name
               RETURNING id""",
            (email, name, hash_password(pw)),
        ).fetchone()
    typer.echo(f"Admin user {email} (id {row['id']}) ready.")


@app.command()
def create_center(
    slug: str = typer.Option(...),
    name: str = typer.Option(...),
    afp_center_id: str = typer.Option(None),
    timezone: str = typer.Option("America/Los_Angeles"),
    locale: str = typer.Option("en"),
    danger_scale: str = typer.Option("NAC"),
):
    """Create a center and seed its active config (version 1) from the default."""
    with connect() as conn:
        row = conn.execute(
            """INSERT INTO centers (slug, name, afp_center_id, timezone, locale, danger_scale)
               VALUES (%s, %s, %s, %s, %s, %s)
               ON CONFLICT (slug) DO UPDATE SET name = EXCLUDED.name RETURNING id""",
            (slug, name, afp_center_id, timezone, locale, danger_scale),
        ).fetchone()
        config_id = seed_default(conn, row["id"])
    typer.echo(f"Center {slug} (id {row['id']}) ready; active config id {config_id}.")


@app.command()
def add_zone(center: str = typer.Option(...), name: str = typer.Option(...), afp_zone_id: str = typer.Option(None)):
    with connect() as conn:
        c = center_by_slug(conn, center)
        conn.execute(
            "INSERT INTO zones (center_id, name, afp_zone_id) VALUES (%s, %s, %s) ON CONFLICT (center_id, name) DO NOTHING",
            (c["id"], name, afp_zone_id),
        )
    typer.echo(f"Zone {name!r} ready for {center}.")


@app.command()
def invite(email: str = typer.Option(...), center: str = typer.Option(None), role: str = typer.Option("forecaster"), admin: bool = False):
    """Print a one-time invite link (valid 14 days). Send it to the person yourself."""
    token = secrets.token_urlsafe(32)
    with connect() as conn:
        center_id = center_by_slug(conn, center)["id"] if center else None
        conn.execute(
            """INSERT INTO invites (token_hash, email, center_id, role, is_admin, expires_at)
               VALUES (%s, %s, %s, %s, %s, %s)""",
            (token_hash(token), email, center_id, role if center_id else None, admin, datetime.now(UTC) + timedelta(days=14)),
        )
    typer.echo(f"{get_settings().public_base_url.rstrip('/')}/invite/{token}")


@app.command()
def add_member(email: str = typer.Option(...), center: str = typer.Option(...), role: str = typer.Option("forecaster")):
    with connect() as conn:
        user = conn.execute("SELECT id FROM users WHERE email = %s", (email,)).fetchone()
        if not user:
            raise SystemExit(f"No user {email}")
        conn.execute(
            """INSERT INTO memberships (user_id, center_id, role) VALUES (%s, %s, %s)
               ON CONFLICT (user_id, center_id) DO UPDATE SET role = EXCLUDED.role""",
            (user["id"], center_by_slug(conn, center)["id"], role),
        )
    typer.echo(f"{email} is now {role} at {center}.")


@app.command()
def list_centers():
    with connect() as conn:
        for c in conn.execute(
            """SELECT c.slug, c.name, (SELECT count(*) FROM forecasts f WHERE f.center_id = c.id) AS forecasts,
                      (SELECT version FROM center_configs cc WHERE cc.center_id = c.id AND status = 'active') AS config_version
               FROM centers c ORDER BY c.slug"""
        ):
            typer.echo(f"{c['slug']:<12} {c['name']:<40} forecasts={c['forecasts']} config=v{c['config_version']}")


if __name__ == "__main__":
    app()
