from datetime import datetime
from uuid import UUID

from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

from src.api.v1.dependencies.auth import get_current_user, require_role
from src.domain.entities import UserRole
from src.infrastructure.database.repositories import AuditLogRepository
from src.infrastructure.database.session import get_db_session
from src.services.auth.security import TokenData
from src.services.audit.audit_service import AuditService

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


class AuditLogResponse(BaseModel):
    id: UUID
    actor_id: UUID | None
    actor_type: str | None
    action: str
    resource_type: str
    resource_id: str | None
    old_value: dict | None
    new_value: dict | None
    ip_address: str | None
    user_agent: str | None
    request_id: str | None
    created_at: datetime | None


class AuditLogListResponse(BaseModel):
    items: list[AuditLogResponse]
    total: int
    offset: int
    limit: int


def _get_service(session: AsyncSession) -> AuditService:
    return AuditService(AuditLogRepository(session))


@router.get("/logs", response_model=AuditLogListResponse)
async def list_audit_logs(
    actor_id: UUID | None = None,
    action: str | None = None,
    resource_type: str | None = None,
    offset: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=200),
    session: AsyncSession = Depends(get_db_session),
    current_user: TokenData = Depends(require_role(UserRole.ADMIN)),
):
    service = _get_service(session)
    entities, total = await service.list_logs(
        actor_id=actor_id, action=action, resource_type=resource_type,
        offset=offset, limit=limit,
    )
    items = [
        AuditLogResponse(
            id=e.id, actor_id=e.actor_id, actor_type=e.actor_type,
            action=e.action, resource_type=e.resource_type,
            resource_id=e.resource_id, old_value=e.old_value,
            new_value=e.new_value, ip_address=e.ip_address,
            user_agent=e.user_agent, request_id=e.request_id,
            created_at=e.created_at,
        )
        for e in entities
    ]
    return AuditLogListResponse(items=items, total=total, offset=offset, limit=limit)
