# retoor <retoor@molodetz.nl>

import sys

from devplacepy.cli._shared import _audit_cli


def cmd_gateway_quota_list(args):
    from devplacepy.services.openai_gateway import quota

    rules = quota.quota_rule_store.list()
    if not rules:
        print("No quota rules. Every caller is capped by the global defaults on /admin/services/openai.")
        return
    for rule in rules:
        spent = quota.spent_24h(rule["owner_kind"], rule["owner_id"], rule["app_reference"])
        scope = ", ".join(
            f"{key}={rule[key]}" for key in ("owner_kind", "owner_id", "app_reference") if rule[key]
        ) or "(no dimensions - invalid)"
        limit = "unlimited" if rule["limit_usd"] == 0 else f"${rule['limit_usd']:.2f}/24h"
        active = "active" if rule["is_active"] else "inactive"
        label = f" - {rule['label']}" if rule["label"] else ""
        print(f"{rule['uid']}  [{scope}]  {limit}  spent=${spent:.4f}  {active}{label}")


def cmd_gateway_quota_set(args):
    from pydantic import ValidationError
    from devplacepy.services.openai_gateway import quota

    try:
        payload = quota.QuotaRuleIn(
            owner_kind=args.owner_kind,
            owner_id=args.owner_id,
            app_reference=args.app_reference,
            limit_usd=args.limit_usd,
            is_active=not args.inactive,
            label=args.label or "",
        )
    except ValidationError as exc:
        print(f"Invalid rule: {exc.errors()[0].get('msg', exc)}")
        sys.exit(1)
    saved = quota.quota_rule_store.set(payload, uid=args.uid, created_by="cli")
    _audit_cli(
        "gateway.quota_rule.update",
        f"CLI saved gateway quota rule {saved['uid']}",
        metadata={
            "owner_kind": saved["owner_kind"],
            "owner_id": saved["owner_id"],
            "app_reference": saved["app_reference"],
            "limit_usd": saved["limit_usd"],
        },
        target_type="gateway_quota_rule",
        target_uid=saved["uid"],
    )
    print(f"Saved quota rule {saved['uid']}")


def cmd_gateway_quota_delete(args):
    from devplacepy.services.openai_gateway import quota

    if not quota.quota_rule_store.remove(args.uid):
        print(f"Quota rule '{args.uid}' not found")
        sys.exit(1)
    _audit_cli(
        "gateway.quota_rule.delete",
        f"CLI deleted gateway quota rule {args.uid}",
        target_type="gateway_quota_rule",
        target_uid=args.uid,
    )
    print(f"Deleted quota rule {args.uid}")


def cmd_gateway_quota_reset(args):
    from devplacepy.services.openai_gateway import quota

    try:
        payload = quota.QuotaResetIn(
            owner_kind=args.owner_kind,
            owner_id=args.owner_id,
            app_reference=args.app_reference,
        )
    except Exception as exc:
        print(f"Error: {exc}")
        sys.exit(1)
    scope = quota.reset(payload, created_by="cli")
    label = quota.scope_label(scope, fallback="every caller")
    _audit_cli(
        "gateway.quota.reset",
        f"CLI reset the gateway 24h spend for {label}",
        target_type="gateway_quota",
        target_uid=scope["uid"],
        metadata={
            "owner_kind": scope["owner_kind"],
            "owner_id": scope["owner_id"],
            "app_reference": scope["app_reference"],
            "reset_at": scope["reset_at"],
        },
    )
    print(f"Reset the rolling 24h spend for {label}")


def register_gateway(subparsers):
    gateway = subparsers.add_parser("gateway", help="AI gateway management")
    gateway_sub = gateway.add_subparsers(title="action", dest="action")

    quota = gateway_sub.add_parser("quota", help="Manage rolling-24h AI gateway quota rules")
    quota_sub = quota.add_subparsers(title="sub-action", dest="sub_action")

    quota_list = quota_sub.add_parser("list", help="List all quota rules and their current 24h spend")
    quota_list.set_defaults(func=cmd_gateway_quota_list)

    quota_set = quota_sub.add_parser(
        "set", help="Create or update a quota rule (scope by role/user/app, any combination)"
    )
    quota_set.add_argument("--uid", help="Existing rule uid to update; omit to create a new rule")
    quota_set.add_argument(
        "--owner-kind",
        choices=("internal", "key", "user", "admin", "anonymous"),
        help="Role to scope by. Omit for any role",
    )
    quota_set.add_argument("--owner-id", help="Specific user uid to scope by. Omit for any caller")
    quota_set.add_argument("--app-reference", help="App label to scope by. Omit for any app")
    quota_set.add_argument(
        "--limit-usd", type=float, required=True, help="Rolling 24h USD cap (0 = unlimited)"
    )
    quota_set.add_argument("--label", help="Optional admin-facing note")
    quota_set.add_argument("--inactive", action="store_true", help="Create the rule disabled")
    quota_set.set_defaults(func=cmd_gateway_quota_set)

    quota_delete = quota_sub.add_parser("delete", help="Delete a quota rule by uid")
    quota_delete.add_argument("uid", help="Quota rule uid")
    quota_delete.set_defaults(func=cmd_gateway_quota_delete)

    quota_reset = quota_sub.add_parser(
        "reset",
        help="Clear the rolling-24h spend so a capped caller can call again (keeps the usage history)",
    )
    quota_reset.add_argument(
        "--owner-kind",
        choices=("internal", "key", "user", "admin", "anonymous"),
        help="Role to scope by. Omit to reset every role",
    )
    quota_reset.add_argument("--owner-id", help="Specific user uid to scope by. Omit for every caller")
    quota_reset.add_argument("--app-reference", help="App label to scope by. Omit for every app")
    quota_reset.set_defaults(func=cmd_gateway_quota_reset)
