#!/usr/bin/env python
"""Grant or list platform admin (``admins`` table).

There is no separate admin login: admins sign in with the normal magic-link flow and use the
same ``Authorization: Bearer <access_token>``. Admin-only API routes check that the user's id
has a row in ``admins``.

From repo root (same ``DATABASE_URL`` / ``.env`` as the API):

  python -m scripts.promote_admin promote --email you@company.com
  python -m scripts.promote_admin promote --user-id <uuid>
  python -m scripts.promote_admin list

Requires: ``DATABASE_URL`` (PostgreSQL).
"""
from __future__ import annotations

import argparse
import asyncio
import os
import sys
from uuid import UUID, uuid4

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from sqlalchemy import select


async def cmd_list() -> int:
    from src.core.database import async_session_factory
    from src.domain.admin.models import Admin
    from src.domain.auth.models import User

    async with async_session_factory() as db:
        result = await db.execute(
            select(Admin, User.email)
            .join(User, User.id == Admin.user_id)
            .order_by(Admin.created_at)
        )
        rows = result.all()
    if not rows:
        print("No platform admins (admins table is empty).")
        return 0
    for adm, email in rows:
        print(f"{adm.user_id}\t{email}\tcreated={adm.created_at}")
    print(f"\nTotal: {len(rows)}")
    return 0


async def cmd_promote(email: str | None, user_id: str | None) -> int:
    if bool(email) == bool(user_id):
        print("Specify exactly one of --email or --user-id.", file=sys.stderr)
        return 2

    from src.core.database import async_session_factory
    from src.domain.admin.models import Admin
    from src.domain.auth.repository import UserRepository

    uid: UUID
    async with async_session_factory() as db:
        repo = UserRepository(db)
        if email:
            u = await repo.get_by_email(email.strip().lower())
            if not u:
                print(f"No user with email: {email!r}", file=sys.stderr)
                return 1
            uid = u.id
        else:
            uid = UUID(user_id.strip())  # type: ignore[arg-type]
            u = await repo.get_by_id(uid)
            if not u:
                print(f"No user with id: {uid}", file=sys.stderr)
                return 1

        existing = await db.execute(select(Admin).where(Admin.user_id == uid))
        if existing.scalar_one_or_none():
            print(f"Already a platform admin: {u.email} ({uid})")
            return 0

        db.add(Admin(id=uuid4(), user_id=uid, created_by=None))
        await db.commit()
        print(f"Promoted to platform admin: {u.email} ({uid})")
    return 0


def main() -> int:
    p = argparse.ArgumentParser(description="Platform admin membership")
    sub = p.add_subparsers(dest="cmd", required=True)

    sub.add_parser("list", help="List users in admins table")

    pr = sub.add_parser("promote", help="Insert a row into admins for this user")
    pr.add_argument("--email", help="User email (must already exist in users)")
    pr.add_argument("--user-id", dest="user_id", help="User UUID")

    args = p.parse_args()
    if args.cmd == "list":
        return asyncio.run(cmd_list())
    return asyncio.run(cmd_promote(email=args.email, user_id=args.user_id))


if __name__ == "__main__":
    raise SystemExit(main())
