"""Audit service — append-only Hospitality audit trail."""
from __future__ import annotations

from enum import Enum
from typing import Any
from uuid import UUID

from sqlalchemy.ext.asyncio import AsyncSession

from app.models.foundation import HospitalityAuditLog
from app.models.types import AuditAction
from app.repositories.foundation import HospitalityAuditLogRepository


def _json_safe(value: Any) -> Any:
    if isinstance(value, UUID):
        return str(value)
    if isinstance(value, Enum):
        return value.value
    if isinstance(value, dict):
        return {str(k): _json_safe(v) for k, v in value.items()}
    if isinstance(value, (list, tuple, set)):
        return [_json_safe(v) for v in value]
    return value


class AuditService:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session
        self.repo = HospitalityAuditLogRepository(session)

    async def record(
        self,
        *,
        tenant_id: UUID,
        entity_type: str,
        entity_id: UUID,
        action: AuditAction,
        actor_user_id: str | None = None,
        changes: dict[str, Any] | None = None,
        message: str | None = None,
        commit: bool = False,
    ) -> HospitalityAuditLog:
        entry = HospitalityAuditLog(
            tenant_id=tenant_id,
            entity_type=entity_type,
            entity_id=entity_id,
            action=action,
            actor_user_id=actor_user_id,
            changes=_json_safe(changes) if changes is not None else None,
            message=message,
        )
        await self.repo.add(entry)
        if commit:
            await self.session.commit()
            await self.session.refresh(entry)
        return entry
