"""complyform-license-audit — quarterly license/subscription mismatch detection.

Trigger: Quarterly Cloud Scheduler.

Compares Firestore active licenses against Paddle active subscriptions to find
orphaned or missing records.  Also checks for customers missing consent records.
Emails mismatch report to ``alerts@complyform.dev``.

Contract: always returns 200.
"""

from __future__ import annotations

import logging
from typing import Any

import httpx

from backend.ops._shared import cloud_function_wrapper, log_action, send_alert_email
from backend.shared.firestore import get_db

_log = logging.getLogger(__name__)

_PADDLE_API_BASE = "https://api.paddle.com"


async def _get_paddle_api_key() -> str:
    """Retrieve Paddle API key from Secret Manager."""
    from google.cloud import secretmanager

    client = secretmanager.SecretManagerServiceClient()
    name = "projects/complyform-prod/secrets/paddle-api-key/versions/latest"
    response = client.access_secret_version(request={"name": name})
    return response.payload.data.decode("utf-8")


@cloud_function_wrapper("complyform-license-audit")
async def license_audit(request: Any) -> dict[str, Any]:
    """Compare Firestore active licenses vs Paddle active subscriptions."""
    db = get_db()

    # 1. Firestore: active customers with their customer_ids
    firestore_active: set[str] = set()
    query = db.collection("customers").where("status", "==", "active")
    async for doc in query.stream():
        firestore_active.add(doc.id)

    # 2. Paddle: active subscription customer_ids
    paddle_key = await _get_paddle_api_key()
    headers = {
        "Authorization": f"Bearer {paddle_key}",
        "Content-Type": "application/json",
    }
    paddle_active: set[str] = set()
    url = f"{_PADDLE_API_BASE}/subscriptions?status=active&per_page=200"
    async with httpx.AsyncClient(timeout=30.0) as client:
        while url:
            resp = await client.get(url, headers=headers)
            resp.raise_for_status()
            body = resp.json()
            for sub in body.get("data", []):
                customer_id = (sub.get("custom_data") or {}).get("customer_id", "")
                if customer_id:
                    paddle_active.add(customer_id)
            url = body.get("meta", {}).get("pagination", {}).get("next", "")

    # 3. Find mismatches
    in_firestore_not_paddle = firestore_active - paddle_active
    in_paddle_not_firestore = paddle_active - firestore_active

    # 4. Consent integrity check
    missing_consent: list[str] = []
    for customer_id in firestore_active:
        try:
            consent_doc = (
                await db.collection("customers")
                .document(customer_id)
                .collection("consent")
                .document("latest")
                .get()
            )
            if not consent_doc.exists:
                missing_consent.append(customer_id)
            else:
                data = consent_doc.to_dict() or {}
                if not data.get("tos_accepted_at"):
                    missing_consent.append(customer_id)
        except Exception:
            _log.exception("Consent check error for %s", customer_id)
            missing_consent.append(customer_id)

    # 5. Build report
    has_issues = bool(
        in_firestore_not_paddle or in_paddle_not_firestore or missing_consent
    )

    report_lines: list[str] = [
        "License Audit Report",
        "=" * 40,
        f"Firestore active customers: {len(firestore_active)}",
        f"Paddle active subscriptions: {len(paddle_active)}",
        "",
    ]

    if in_firestore_not_paddle:
        report_lines.append(
            f"Active in Firestore but NOT in Paddle ({len(in_firestore_not_paddle)}):"
        )
        for cid in sorted(in_firestore_not_paddle):
            report_lines.append(f"  - {cid}")
        report_lines.append("")

    if in_paddle_not_firestore:
        report_lines.append(
            f"Active in Paddle but NOT in Firestore ({len(in_paddle_not_firestore)}):"
        )
        for cid in sorted(in_paddle_not_firestore):
            report_lines.append(f"  - {cid}")
        report_lines.append("")

    if missing_consent:
        report_lines.append(
            f"Missing consent (tos_accepted_at) ({len(missing_consent)}):"
        )
        for cid in sorted(missing_consent):
            report_lines.append(f"  - {cid}")
        report_lines.append("")

    if not has_issues:
        report_lines.append("No mismatches found. All records are consistent.")

    subject_status = "MISMATCH DETECTED" if has_issues else "CLEAN"
    await send_alert_email(
        subject=f"[ComplyForm] License Audit — {subject_status}",
        body="\n".join(report_lines),
    )

    log_action(
        customer_id=None,
        action="license_audit_complete",
        firestore_count=len(firestore_active),
        paddle_count=len(paddle_active),
        mismatches=len(in_firestore_not_paddle) + len(in_paddle_not_firestore),
        missing_consent=len(missing_consent),
    )
    return {
        "firestore_active": len(firestore_active),
        "paddle_active": len(paddle_active),
        "in_firestore_not_paddle": len(in_firestore_not_paddle),
        "in_paddle_not_firestore": len(in_paddle_not_firestore),
        "missing_consent": len(missing_consent),
    }


entry_point = license_audit
