"""
Router Audit Log – consultazione ed esportazione degli eventi di sistema.

Endpoint:
  GET /api/v1/audit-log           – lista paginata con filtri (solo admin/super_admin)
  GET /api/v1/audit-log/export    – esportazione CSV o PDF (solo admin/super_admin)

Permessi:
  - admin: vede solo gli eventi del proprio tenant
  - super_admin: vede tutti i tenant (filtrabile per tenant_id)
"""

import uuid
from datetime import datetime
from typing import Optional

from fastapi import APIRouter, Query
from fastapi.responses import Response, StreamingResponse

from app.dependencies import AdminUser, DB
from app.schemas.audit_log import AuditLogListResponse
from app.services.audit_service import AuditService

router = APIRouter(prefix="/audit-log", tags=["Audit Log"])


def _effective_tenant_id(current_user, tenant_id: Optional[uuid.UUID]) -> Optional[uuid.UUID]:
    """Determina il tenant_id effettivo in base al ruolo dell'utente."""
    if current_user.is_super_admin:
        return tenant_id  # None = tutti i tenant
    return current_user.tenant_id  # sempre vincolato al proprio tenant


@router.get("", response_model=AuditLogListResponse)
async def list_audit_log(
    current_user: AdminUser,
    db: DB,
    page: int = Query(1, ge=1, description="Numero di pagina"),
    page_size: int = Query(25, ge=1, le=100, description="Elementi per pagina"),
    action: Optional[str] = Query(None, description="Filtra per azione (es. auth.login, user.*)"),
    user_id: Optional[uuid.UUID] = Query(None, description="Filtra per utente"),
    outcome: Optional[str] = Query(None, pattern="^(success|failure)$", description="Esito: success o failure"),
    date_from: Optional[datetime] = Query(None, description="Data inizio (ISO 8601)"),
    date_to: Optional[datetime] = Query(None, description="Data fine (ISO 8601)"),
    resource_type: Optional[str] = Query(None, description="Tipo risorsa (user, mailbox, message, ...)"),
    tenant_id: Optional[uuid.UUID] = Query(None, description="Filtra per tenant (solo super_admin)"),
) -> AuditLogListResponse:
    """Restituisce la lista paginata degli eventi di audit."""
    svc = AuditService(db)
    return await svc.list(
        tenant_id=_effective_tenant_id(current_user, tenant_id),
        page=page,
        page_size=page_size,
        action=action,
        user_id=user_id,
        outcome=outcome,
        date_from=date_from,
        date_to=date_to,
        resource_type=resource_type,
    )


@router.get("/export")
async def export_audit_log(
    current_user: AdminUser,
    db: DB,
    format: str = Query("csv", pattern="^(csv|pdf)$", description="Formato: csv o pdf"),
    action: Optional[str] = Query(None),
    user_id: Optional[uuid.UUID] = Query(None),
    outcome: Optional[str] = Query(None, pattern="^(success|failure)$"),
    date_from: Optional[datetime] = Query(None),
    date_to: Optional[datetime] = Query(None),
    resource_type: Optional[str] = Query(None),
    tenant_id: Optional[uuid.UUID] = Query(None),
) -> Response:
    """
    Esporta i log di audit in formato CSV o PDF.
    Applica gli stessi filtri dell'endpoint lista.
    """
    svc = AuditService(db)
    effective_tid = _effective_tenant_id(current_user, tenant_id)

    # Nome file con periodo
    suffix = ""
    if date_from:
        suffix += f"_dal_{date_from.strftime('%Y%m%d')}"
    if date_to:
        suffix += f"_al_{date_to.strftime('%Y%m%d')}"

    if format == "csv":
        csv_content = await svc.export_csv(
            tenant_id=effective_tid,
            action=action,
            user_id=user_id,
            outcome=outcome,
            date_from=date_from,
            date_to=date_to,
            resource_type=resource_type,
        )
        filename = f"audit_log{suffix}.csv"
        return Response(
            content=csv_content.encode("utf-8-sig"),  # BOM per compatibilita' Excel
            media_type="text/csv; charset=utf-8",
            headers={"Content-Disposition": f'attachment; filename="{filename}"'},
        )

    else:  # pdf
        pdf_bytes = await svc.export_pdf_bytes(
            tenant_id=effective_tid,
            action=action,
            user_id=user_id,
            outcome=outcome,
            date_from=date_from,
            date_to=date_to,
            resource_type=resource_type,
        )
        filename = f"audit_log{suffix}.pdf"
        return Response(
            content=pdf_bytes,
            media_type="application/pdf",
            headers={"Content-Disposition": f'attachment; filename="{filename}"'},
        )
