import uuid
from datetime import datetime

from fastapi import APIRouter, Depends
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_db
from app.core.permissions import require_permission
from app.core.security import AuthContext, get_auth_context
from app.models.audit import AuditLogEntry
from app.schemas.audit import AuditLogEntryRead

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


@router.get("", response_model=list[AuditLogEntryRead])
async def list_audit_log(
    skip: int = 0,
    limit: int = 100,
    entity_type: str | None = None,
    entity_id: uuid.UUID | None = None,
    actor_id: uuid.UUID | None = None,
    occurred_from: datetime | None = None,
    ctx: AuthContext = Depends(get_auth_context),
    db: AsyncSession = Depends(get_db),
    _: AuthContext = Depends(require_permission("settings", "view")),
) -> list[AuditLogEntry]:
    """
    Read-only by design (NFR-SEC-004/NFR-AUD-001: an immutable trail) — there
    is no POST here. Entries are written internally by other endpoints via
    app.crud.audit.write_audit_log, in the same transaction as the action
    they record.
    """
    stmt = select(AuditLogEntry).where(AuditLogEntry.tenant_id == ctx.tenant_id)
    if entity_type is not None:
        stmt = stmt.where(AuditLogEntry.entity_type == entity_type)
    if entity_id is not None:
        stmt = stmt.where(AuditLogEntry.entity_id == entity_id)
    if actor_id is not None:
        stmt = stmt.where(AuditLogEntry.actor_id == actor_id)
    if occurred_from is not None:
        stmt = stmt.where(AuditLogEntry.occurred_at >= occurred_from)
    stmt = stmt.order_by(AuditLogEntry.occurred_at.desc()).offset(skip).limit(limit)
    return list((await db.execute(stmt)).scalars().all())
