"""GDPR privacy API routes.

⚠️ AUTO-GENERATED BY PRISM — DO NOT EDIT
This file is regenerated on every `prisme generate`.
"""

from __future__ import annotations

from datetime import datetime
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Query, Request
from sqlalchemy.ext.asyncio import AsyncSession

from {{ package_name }}.privacy.audit_service import AuditService
from {{ package_name }}.privacy.data_export_service import DataExportService
from {{ package_name }}.privacy.data_deletion_service import DataDeletionService
{% if has_retention %}
from {{ package_name }}.privacy.retention_service import RetentionService
{% endif %}

router = APIRouter(prefix="/privacy", tags=["privacy"])


def _get_client_ip(request: Request) -> str | None:
    """Extract client IP from request."""
    forwarded = request.headers.get("x-forwarded-for")
    if forwarded:
        return forwarded.split(",")[0].strip()
    if request.client:
        return request.client.host
    return None


@router.get("/audit-log")
async def query_audit_log(
    request: Request,
    session: AsyncSession = Depends(),
    model_name: str | None = Query(None, description="Filter by model name"),
    record_id: str | None = Query(None, description="Filter by record ID"),
    user_id: str | None = Query(None, description="Filter by user ID"),
    operation: str | None = Query(None, description="Filter by operation type"),
    since: datetime | None = Query(None, description="Filter entries after this time"),
    until: datetime | None = Query(None, description="Filter entries before this time"),
    limit: int = Query(100, ge=1, le=1000, description="Maximum entries"),
    offset: int = Query(0, ge=0, description="Entries to skip"),
) -> list[dict[str, Any]]:
    """Query the GDPR audit log.

    Returns audit trail entries with optional filters.
    """
    audit = AuditService(session)
    entries = await audit.query(
        model_name=model_name,
        record_id=record_id,
        user_id=user_id,
        operation=operation,
        since=since,
        until=until,
        limit=limit,
        offset=offset,
    )
    return [
        {
            "id": e.id,
            "timestamp": e.timestamp.isoformat() if e.timestamp else None,
            "user_id": e.user_id,
            "operation": e.operation,
            "model_name": e.model_name,
            "record_id": e.record_id,
            "field_name": e.field_name,
            "ip_address": e.ip_address,
            "details": e.details,
        }
        for e in entries
    ]


@router.post("/export/{subject_id}")
async def export_subject_data(
    subject_id: str,
    request: Request,
    session: AsyncSession = Depends(),
    format: str = Query("json", description="Export format: json, csv"),
    subject_field: str = Query("id", description="Field to match subject"),
) -> dict[str, Any]:
    """Export all personal data for a data subject (GDPR Article 15/20).

    Generates a complete data export containing all personal data
    stored for the specified subject.
    """
    service = DataExportService(session)
    try:
        return await service.export_subject_data(
            subject_id=subject_id,
            subject_field=subject_field,
            format=format,
            requesting_user_id=None,  # TODO: extract from auth
            ip_address=_get_client_ip(request),
        )
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e


@router.post("/erase/{subject_id}")
async def erase_subject_data(
    subject_id: str,
    request: Request,
    session: AsyncSession = Depends(),
    anonymize: bool = Query(False, description="Anonymize instead of delete"),
    subject_field: str = Query("id", description="Field to match subject"),
) -> dict[str, Any]:
    """Erase or anonymize personal data for a data subject (GDPR Article 17).

    This is an irreversible operation. When anonymize=False, records are
    permanently deleted. When anonymize=True, PII fields are replaced
    with placeholder values.
    """
    service = DataDeletionService(session)
    return await service.erase_subject_data(
        subject_id=subject_id,
        subject_field=subject_field,
        anonymize=anonymize,
        requesting_user_id=None,  # TODO: extract from auth
        ip_address=_get_client_ip(request),
    )
{% if has_retention %}


@router.get("/retention/report")
async def retention_report(
    session: AsyncSession = Depends(),
) -> list[dict[str, Any]]:
    """Get a report of records approaching retention expiry.

    Shows how many records are expired and how many are
    expiring within the next 30 days, per model.
    """
    service = RetentionService(session)
    return await service.get_retention_report()


@router.post("/retention/enforce")
async def enforce_retention(
    request: Request,
    session: AsyncSession = Depends(),
) -> dict[str, Any]:
    """Manually trigger retention policy enforcement.

    Deletes all records that have exceeded their retention period.
    This is also run automatically by the retention background job.
    """
    service = RetentionService(session)
    results = await service.enforce_all()

    # Audit the manual enforcement
    audit = AuditService(session)
    await audit.log(
        operation="retention_enforce",
        model_name="*",
        user_id=None,
        ip_address=_get_client_ip(request),
        details=f"Manual retention enforcement: {results}",
    )
    await session.commit()

    return {"enforced_at": datetime.now().isoformat(), "results": results}
{% endif %}
