from datetime import datetime
from typing import Optional

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

from database.postgres import get_pg_session
from shared.orm import AuditLog
from auth.dependencies import require_sysadmin
from auth.models import TokenPayload

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

_MAX_LIMIT = 200
_DEFAULT_LIMIT = 50


@router.get("")
async def list_audit_log(
    actor_id: Optional[str] = Query(None),
    entity_type: Optional[str] = Query(None),
    entity_id: Optional[str] = Query(None),
    action: Optional[str] = Query(None),
    from_date: Optional[datetime] = Query(None),
    to_date: Optional[datetime] = Query(None),
    limit: int = Query(_DEFAULT_LIMIT, ge=1, le=_MAX_LIMIT),
    offset: int = Query(0, ge=0),
    _user: TokenPayload = Depends(require_sysadmin),
    db: AsyncSession = Depends(get_pg_session),
):
    filters = []
    if actor_id:
        filters.append(AuditLog.actor_id == actor_id)
    if entity_type:
        filters.append(AuditLog.entity_type == entity_type)
    if entity_id:
        filters.append(AuditLog.entity_id == entity_id)
    if action:
        filters.append(AuditLog.action == action)
    if from_date:
        filters.append(AuditLog.occurred_at >= from_date)
    if to_date:
        filters.append(AuditLog.occurred_at <= to_date)

    stmt = (
        select(AuditLog)
        .where(and_(*filters) if filters else True)
        .order_by(AuditLog.occurred_at.desc())
        .offset(offset)
        .limit(limit)
    )
    result = await db.execute(stmt)
    rows = result.scalars().all()

    return {
        "entries": [
            {
                "id":           r.id,
                "occurred_at":  r.occurred_at.isoformat(),
                "actor_id":     r.actor_id,
                "actor_name":   r.actor_name,
                "action":       r.action,
                "entity_type":  r.entity_type,
                "entity_id":    r.entity_id,
                "entity_label": r.entity_label,
                "changes":      r.changes,
                "meta":         r.meta,
            }
            for r in rows
        ],
        "limit":  limit,
        "offset": offset,
    }
