"""GET /admin/api/audit-log — paginated read of the operation audit trail.

Read-only, paginated, filterable. Writes happen automatically via the
AuditMiddleware in govcrawler.api.audit — no POST surface here.
"""
from __future__ import annotations

from datetime import datetime
from typing import Any

from fastapi import Depends, Query
from sqlalchemy import desc, func, select
from sqlalchemy.orm import Session

from govcrawler.models import AdminAuditLog

from ._common import _session, iso_cn, router


@router.get("/api/audit-log")
def list_audit_log(
    actor: str | None = Query(None, description="filter by Basic Auth username"),
    action: str | None = Query(None, description="filter by action class (target.run, ...)"),
    resource_type: str | None = Query(None, description="site / target / article / ..."),
    resource_id: str | None = Query(None, description="exact resource id"),
    since: datetime | None = Query(None, description="created_at floor (ISO-8601)"),
    method: str | None = Query(None, description="POST / PUT / DELETE / PATCH"),
    only_failed: bool = Query(False, description="status_code >= 400"),
    limit: int = Query(50, ge=1, le=200),
    offset: int = Query(0, ge=0),
    s: Session = Depends(_session),
) -> dict[str, Any]:
    """Paginated audit log feed. Newest first."""
    filters = []
    if actor:
        filters.append(AdminAuditLog.actor == actor)
    if action:
        filters.append(AdminAuditLog.action == action)
    if resource_type:
        filters.append(AdminAuditLog.resource_type == resource_type)
    if resource_id:
        filters.append(AdminAuditLog.resource_id == resource_id)
    if since is not None:
        filters.append(AdminAuditLog.created_at >= since)
    if method:
        filters.append(AdminAuditLog.method == method.upper())
    if only_failed:
        filters.append(AdminAuditLog.status_code >= 400)

    count_stmt = select(func.count(AdminAuditLog.id))
    for f in filters:
        count_stmt = count_stmt.where(f)
    total = s.execute(count_stmt).scalar() or 0

    stmt = (
        select(AdminAuditLog)
        .order_by(desc(AdminAuditLog.id))
        .offset(offset)
        .limit(limit)
    )
    for f in filters:
        stmt = stmt.where(f)
    rows = s.execute(stmt).scalars().all()

    return {
        "count": len(rows),
        "total": total,
        "limit": limit,
        "offset": offset,
        "items": [
            {
                "id": r.id,
                "created_at": iso_cn(r.created_at),
                "actor": r.actor,
                "actor_ip": r.actor_ip,
                "method": r.method,
                "path": r.path,
                "status_code": r.status_code,
                "duration_ms": r.duration_ms,
                "payload_digest": r.payload_digest,
                "action": r.action,
                "resource_type": r.resource_type,
                "resource_id": r.resource_id,
            }
            for r in rows
        ],
    }
