"""Data export/delete endpoints — GDPR Art. 17/20 compliance.

POST /v1/data/export — trigger data export (Art. 20 portability)
POST /v1/data/delete — trigger data deletion (Art. 17 erasure)
"""

from __future__ import annotations

import logging
from datetime import UTC, datetime, timedelta
from typing import Any

from fastapi import APIRouter, Request
from fastapi.responses import JSONResponse

_log = logging.getLogger(__name__)

data_router = APIRouter(prefix="/v1/data", tags=["data"])


async def _require_api_key_auth(
    request: Request,
) -> tuple[str, str, str]:
    """Validate API key and return (customer_id, email, tier).

    Requires Team+ tier (hosted_dashboard feature).
    """
    from backend.api.middleware.api_key_auth import (
        APIKeyAuthError,
        require_api_key,
    )

    ctx = await require_api_key(request)

    if "hosted_dashboard" not in ctx.features:
        raise APIKeyAuthError(
            403,
            f"Data operations require Team+ tier (current: {ctx.tier})",
        )

    return ctx.customer_id, ctx.email, ctx.tier


@data_router.post("/export")
async def export_data(request: Request) -> JSONResponse:
    """GDPR Art. 20 data portability — trigger background export.

    Rate limited to 1 per 24 hours per customer.
    Assembles ZIP with customer data → GCS → email with signed URL.
    """
    from src.complyform.core.errors import DataExportRateLimitError

    customer_id, email, tier = await _require_api_key_auth(request)

    # Check rate limit
    from backend.shared.firestore import get_db

    db = get_db()
    cust_doc = await db.collection("customers").document(customer_id).get()

    if cust_doc.exists:
        cust_data: dict[str, Any] = cust_doc.to_dict()  # type: ignore[assignment]
        last_export = cust_data.get("last_export_at")
        if last_export:
            last_dt = (
                datetime.fromisoformat(str(last_export))
                if isinstance(last_export, str)
                else last_export
            )
            if hasattr(last_dt, "tzinfo") and last_dt.tzinfo is None:
                last_dt = last_dt.replace(tzinfo=UTC)
            if datetime.now(UTC) - last_dt < timedelta(hours=24):
                raise DataExportRateLimitError()

    # Mark export start
    now = datetime.now(UTC).isoformat()
    await (
        db.collection("customers").document(customer_id).update({"last_export_at": now})
    )

    # Audit event
    try:
        from backend.dashboard.audit import write_audit_event
        from backend.shared.tier_config import TIER_CONFIG

        retention = TIER_CONFIG.get(tier, {}).get("retention_months")
        await write_audit_event(
            customer_id=customer_id,
            event="dashboard.data_exported",
            actor_email=email,
            actor_role="api",
            ip_hash="api-request",
            metadata={"source": "api"},
            retention_months=retention,
        )
    except Exception:
        _log.exception("Failed to write export audit event")

    # TODO: trigger background Cloud Task for actual assembly
    # For now, return acknowledgment
    return JSONResponse(
        {
            "status": "export_started",
            "estimated_minutes": 5,
            "customer_id": customer_id,
        }
    )


@data_router.post("/delete")
async def delete_data(request: Request) -> JSONResponse:
    """GDPR Art. 17 right to erasure — delete all customer data.

    Requires {"confirm": true} in request body.
    Retains Paddle record (legal/accounting requirement).
    """
    customer_id, email, tier = await _require_api_key_auth(request)

    body: dict[str, Any] = await request.json()
    if not body.get("confirm"):
        return JSONResponse(
            {"error": 'Request body must include {"confirm": true}'},
            status_code=400,
        )

    from backend.shared.firestore import get_db

    db = get_db()

    # Delete subcollections
    subcollections = [
        "projects",
        "scans",
        "members",
        "audit_log",
        "webhooks",
        "shared_links",
    ]
    for subcol in subcollections:
        col_ref = db.collection("customers").document(customer_id).collection(subcol)
        async for doc in col_ref.stream():
            await doc.reference.delete()

    # Delete SSO config
    await db.collection("sso_configs").document(customer_id).delete()

    # Deactivate license (set status = "deleted")
    await db.collection("customers").document(customer_id).update({"status": "deleted"})

    # Delete GCS findings
    try:
        from google.cloud import storage

        gcs_client = storage.Client()
        bucket = gcs_client.bucket("complyform-findings")
        blobs = bucket.list_blobs(prefix=f"{customer_id}/")
        for blob in blobs:
            blob.delete()
    except Exception:
        _log.exception("Failed to delete GCS findings for %s", customer_id)

    # Audit (before customer doc is fully gone)
    try:
        from backend.dashboard.audit import write_audit_event

        await write_audit_event(
            customer_id=customer_id,
            event="dashboard.settings_updated",
            actor_email=email,
            actor_role="api",
            ip_hash="api-request",
            metadata={"section": "data", "action": "deletion_completed"},
        )
    except Exception:
        _log.exception("Failed to write deletion audit event")

    # TODO: send data-deletion-confirmed Postmark email

    return JSONResponse(
        {
            "status": "deletion_started",
            "customer_id": customer_id,
        }
    )
