"""Guarded deletion of legacy Cloudflare Pages projects.

This command is deliberately a two-step operation:

  python scripts/delete_cf_pages_projects.py --audit w4p-audit.json
  python scripts/delete_cf_pages_projects.py --audit w4p-audit.json --execute --confirm DELETE-W4P-PAGES

Only projects marked W4P_READY_TO_RETIRE_PAGES by the read-only audit can be
deleted. The audit must be recent and every Pages project name must be unique.
"""
from __future__ import annotations

import argparse
import asyncio
import json
import sys
from datetime import UTC, datetime, timedelta
from pathlib import Path

import httpx

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

CF_API = "https://api.cloudflare.com/client/v4"


async def delete_from_audit(audit_path: str, execute: bool, confirm: str) -> dict:
    from src.config import get_settings

    audit = json.loads(Path(audit_path).read_text(encoding="utf-8"))
    audited_at = datetime.fromisoformat(audit["audited_at"].replace("Z", "+00:00"))
    if datetime.now(UTC) - audited_at > timedelta(hours=2):
        raise RuntimeError("audit_is_older_than_two_hours_rerun_audit")
    rows = audit.get("projects") or []
    eligible = [row for row in rows if row.get("status") == "W4P_READY_TO_RETIRE_PAGES" and row.get("safe_to_delete_pages") is True]
    ineligible = [row for row in rows if row not in eligible]
    names: dict[str, list[str]] = {}
    for row in eligible:
        for name in row.get("pages_project_names") or []:
            names.setdefault(name, []).append(row["project_id"])
    duplicates = {name: ids for name, ids in names.items() if len(ids) > 1}
    if duplicates:
        raise RuntimeError(f"pages_project_name_shared_by_projects:{sorted(duplicates)}")
    plan = {
        "audit": audit_path,
        "eligible_projects": [row["project_id"] for row in eligible],
        "pages_projects": sorted(names),
        "ineligible_projects": [row["project_id"] for row in ineligible],
        "executed": False,
    }
    if not execute:
        return plan
    if confirm != "DELETE-W4P-PAGES":
        raise RuntimeError("explicit_confirmation_required:DELETE-W4P-PAGES")
    settings = get_settings()
    if not settings.cloudflare_account_id or not settings.cloudflare_api_token:
        raise RuntimeError("cloudflare_account_id_or_api_token_missing")
    results = []
    async with httpx.AsyncClient(timeout=30.0) as client:
        headers = {"Authorization": f"Bearer {settings.cloudflare_api_token}"}
        for name in sorted(names):
            response = await client.delete(
                f"{CF_API}/accounts/{settings.cloudflare_account_id}/pages/projects/{name}",
                headers=headers,
            )
            if response.status_code not in {200, 202, 204, 404}:
                raise RuntimeError(f"pages_delete_failed:{name}:http_{response.status_code}")
            results.append({"name": name, "status": response.status_code, "already_absent": response.status_code == 404})
    plan["executed"] = True
    plan["deletions"] = results
    return plan


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--audit", required=True)
    parser.add_argument("--execute", action="store_true")
    parser.add_argument("--confirm", default="")
    args = parser.parse_args()
    result = asyncio.run(delete_from_audit(args.audit, args.execute, args.confirm))
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    main()
