"""Financial and operational reporting, separate from clinical report permissions."""

import asyncio
from datetime import date
from typing import Annotated, Literal
from uuid import UUID

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

from app.core.auth_deps import require_permission
from app.core.dependencies import get_db
from app.core.permissions import PermissionCode
from app.core.rate_limit import limiter
from app.core.responses import SuccessResponse
from app.models.audit import AuditCategory
from app.models.user import User
from app.services.audit_service import AuditService
from app.services.management_reporting_service import (
    ManagementReport,
    ManagementReportingService,
    ReportSection,
)

router = APIRouter(prefix="/management-reporting", tags=["Management Reporting"])
service = ManagementReportingService()


@router.get("", response_model=SuccessResponse[ManagementReport])
@limiter.limit("12/minute")
async def generate_report(
    request: Request,
    db: Annotated[AsyncSession, Depends(get_db)],
    user: Annotated[User, Depends(require_permission(PermissionCode.REPORTING_READ))],
    start_date: date,
    end_date: date,
    lab_id: UUID | None = None,
) -> SuccessResponse[ManagementReport]:
    return SuccessResponse(data=await service.generate(db, user, start_date, end_date, lab_id))


@router.get("/export")
@limiter.limit("6/minute")
async def export_report(
    request: Request,
    db: Annotated[AsyncSession, Depends(get_db)],
    user: Annotated[User, Depends(require_permission(PermissionCode.REPORTING_EXPORT))],
    reader: Annotated[User, Depends(require_permission(PermissionCode.REPORTING_READ))],
    start_date: date,
    end_date: date,
    format: Annotated[Literal["csv", "pdf"], Query()] = "csv",
    section: ReportSection = "combined",
    lab_id: UUID | None = None,
) -> Response:
    report = await service.generate(db, user, start_date, end_date, lab_id)
    content = (
        service.csv_bytes(report, section)
        if format == "csv"
        else await asyncio.to_thread(service.pdf_bytes, report, section)
    )
    await AuditService().record_event(
        db,
        action="MANAGEMENT_REPORT_EXPORTED",
        description="Exported management reporting.",
        category=AuditCategory.BILLING.value,
        actor_name=user.name,
        actor_role=str(user.role),
        actor_id=user.id,
        target_type="management_report",
        lab_id=report.overview.lab_id,
        ip_address=request.client.host if request.client else None,
        details={
            "start": str(start_date),
            "end": str(end_date),
            "format": format,
            "section": section,
            "scope": str(report.overview.lab_id or "all"),
        },
    )
    await db.commit()
    return Response(
        content,
        media_type="text/csv" if format == "csv" else "application/pdf",
        headers={
            "Content-Disposition": f'attachment; filename="munal-{section}-{start_date}-{end_date}.{format}"',
        },
    )
