"""Flags, audit entries and usage records written by the worker."""
from __future__ import annotations
from typing import Any

from .db import Jsonb
from .ids import new_id

# severity per flag type (design §RV-01; 'block' types stop finalization by default)
FLAG_SEVERITY = {
    "unreadable_page": "block", "unmapped_content": "block", "unidentified_script": "block",
    "cover_roll_mismatch": "warn", "low_confidence_extraction": "warn", "blank_disagreement": "warn",
    "low_mapping_confidence": "warn", "duplicate_answer": "warn", "uncertain_affects_score": "warn",
    "too_many_pages": "warn", "processing_failed": "block", "rubric_minimal": "info",
    "choice_rule_applied": "info",
}


def raise_flag(conn, *, tenant_id: str, batch_id: str, type_: str, script_id: str | None = None,
               page_id: str | None = None, element_id: str | None = None,
               segment_id: str | None = None, payload: dict | None = None) -> str:
    fid = new_id()
    conn.execute(
        """INSERT INTO flags (id, tenant_id, batch_id, script_id, page_id, element_id, segment_id,
                              type, severity, payload_json)
           VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
        (fid, tenant_id, batch_id, script_id, page_id, element_id, segment_id, type_,
         FLAG_SEVERITY.get(type_, "warn"), Jsonb(payload or {})))
    if script_id:
        conn.execute("UPDATE scripts SET flags_count = flags_count + 1 WHERE id=%s AND tenant_id=%s",
                     (script_id, tenant_id))
    return fid


def audit(conn, *, tenant_id: str | None, action: str, entity_type: str, entity_id: str | None,
          before: Any = None, after: Any = None, model_info: dict | None = None,
          tokens: dict | None = None, qs_version: int | None = None, actor_id: str = "worker") -> None:
    conn.execute(
        """INSERT INTO audit_log (id, tenant_id, actor_type, actor_id, action, entity_type, entity_id,
                                  before_json, after_json, qs_version, model_info_json, tokens_json)
           VALUES (%s,%s,'worker',%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
        (new_id(), tenant_id, actor_id, action, entity_type, entity_id,
         Jsonb(before) if before is not None else None, Jsonb(after) if after is not None else None,
         qs_version, Jsonb(model_info) if model_info else None, Jsonb(tokens) if tokens else None))


def record_usage(conn, *, tenant_id: str, op_type: str, credits_milli: int, result, batch_id=None,
                 script_id=None, page_id=None) -> None:
    """`result` is a providers.base.Result (or None for non-AI charges)."""
    conn.execute(
        """INSERT INTO usage_records (id, tenant_id, batch_id, script_id, page_id, op_type, credits_milli,
                                      tokens_in, tokens_out, cached_tokens, cost_micro, provider, model)
           VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
        (new_id(), tenant_id, batch_id, script_id, page_id, op_type, credits_milli,
         getattr(result, "tokens_in", 0), getattr(result, "tokens_out", 0),
         getattr(result, "cached_tokens", 0), getattr(result, "cost_micro", 0),
         getattr(result, "provider", None), getattr(result, "model", None)))
