"""Audit log — תיעוד כל פעולה במערכת.

כל פעולה מתועדת: מי, מתי, מה, על איזה תיק.
"""

from __future__ import annotations

import json
import logging
from datetime import datetime, timezone
from uuid import UUID, uuid4

from legal_mcp.services import db

logger = logging.getLogger("audit")


async def log_action(
    action: str,
    case_id: UUID | None = None,
    document_id: UUID | None = None,
    details: dict | None = None,
    user: str = "system",
) -> None:
    """רישום פעולה ב-audit log.

    Args:
        action: סוג הפעולה (upload, classify, extract_claims, set_outcome, write_block, export, etc.)
        case_id: מזהה תיק (אם רלוונטי)
        document_id: מזהה מסמך (אם רלוונטי)
        details: פרטים נוספים
        user: מזהה המשתמש
    """
    pool = await db.get_pool()
    async with pool.acquire() as conn:
        await conn.execute(
            """INSERT INTO audit_log (id, action, case_id, document_id, details, actor, created_at)
               VALUES ($1, $2, $3, $4, $5, $6, $7)""",
            uuid4(), action, case_id, document_id,
            json.dumps(details or {}, ensure_ascii=False, default=str),
            user, datetime.now(timezone.utc),
        )
    logger.info("AUDIT: %s | case=%s | user=%s | %s", action, case_id, user,
                json.dumps(details or {}, ensure_ascii=False)[:200])


async def log_action_safe(
    action: str,
    case_id: "UUID | None" = None,
    document_id: "UUID | None" = None,
    details: dict | None = None,
    user: str = "system",
) -> None:
    """Non-fatal audit: never let an audit-log failure break the caller's action.

    The authoritative integrity trail is git (X5 §2.1); audit_log is the
    'who/what/when' observability layer, so a write failure is logged as a
    warning and swallowed.
    """
    try:
        await log_action(action, case_id=case_id, document_id=document_id,
                         details=details, user=user)
    except Exception as e:  # noqa: BLE001 — observability must not break the op
        logger.warning("audit log_action failed (non-fatal) for %s: %s", action, e)


async def get_audit_log(
    case_id: UUID | None = None,
    action: str | None = None,
    limit: int = 50,
) -> list[dict]:
    """שליפת audit log."""
    pool = await db.get_pool()
    conditions = []
    params: list = []
    idx = 1

    if case_id:
        conditions.append(f"case_id = ${idx}")
        params.append(case_id)
        idx += 1
    if action:
        conditions.append(f"action = ${idx}")
        params.append(action)
        idx += 1

    where = f"WHERE {' AND '.join(conditions)}" if conditions else ""
    params.append(limit)

    async with pool.acquire() as conn:
        rows = await conn.fetch(
            f"SELECT * FROM audit_log {where} ORDER BY created_at DESC LIMIT ${idx}",
            *params,
        )

    return [dict(r) for r in rows]
