from __future__ import annotations

import uuid
from datetime import UTC, datetime
from typing import Any

from sqlalchemy.orm import Session

from app.core.logging import get_logger
from app.models.audit_log import AuditLog
from app.repositories.audit_log import AuditLogRepository
from app.schemas.audit_log import AuditLogRead
from app.services.agent_foundation import AgentFoundationService

logger = get_logger("app.services.audit")


class AuditLogService:
    def __init__(self, db: Session) -> None:
        self.db = db
        self.repository = AuditLogRepository(db)

    def list_logs(
        self,
        *,
        resource_type: str | None = None,
        resource_id: str | None = None,
        action: str | None = None,
        limit: int = 50,
    ) -> list[AuditLogRead]:
        self._ensure_ready()
        items = self.repository.list(
            resource_type=resource_type,
            resource_id=resource_id,
            action=action,
            limit=limit,
        )
        return [AuditLogRead.model_validate(item) for item in items]

    def log_action(
        self,
        *,
        actor: str,
        action: str,
        resource_type: str,
        resource_id: str,
        before_json: dict[str, Any] | None = None,
        after_json: dict[str, Any] | None = None,
        request_id: str | None = None,
        commit: bool = True,
    ) -> AuditLog:
        log = AuditLog(
            actor=actor,
            action=action,
            resource_type=resource_type,
            resource_id=resource_id,
            before_json=before_json,
            after_json=after_json,
            request_id=request_id or uuid.uuid4().hex,
            created_at=datetime.now(UTC),
        )
        created = self.repository.create(log, commit=commit)
        logger.info(
            "Created audit log id=%s action=%s resource=%s:%s",
            created.id,
            created.action,
            created.resource_type,
            created.resource_id,
        )
        return created

    def _ensure_ready(self) -> None:
        AgentFoundationService(self.db).ensure_foundation_ready()
