"""RCA state tracking facade for MCP/debug workflows.

This module preserves the public RCA API while delegating internals to focused
identity/transition/backend helpers.
"""

from __future__ import annotations

import uuid
from datetime import datetime, timezone
from typing import Any, Literal

from . import rca_identity as _rca_identity
from .rca_backend import (
    get_rca_history as _get_rca_history_backend,
)
from .rca_backend import (
    get_rca_status as _get_rca_status_backend,
)
from .rca_backend import (
    persist_rca_record,
)
from .rca_engine import build_rca_attempt_record
from .rca_transitions import (
    DEFAULT_STATE,
)

RCABackend = Literal["sqlite", "jsonl"]


def _now_utc() -> str:
    return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")


def _new_attempt_id() -> str:
    return f"{int(datetime.now(timezone.utc).timestamp() * 1000)}-{uuid.uuid4().hex[:8]}"


def build_failure_signature(
    snapshot: dict[str, Any] | None,
    *,
    stdout: str = "",
    stderr: str = "",
) -> str:
    """Build a stable failure signature from snapshot (preferred) or textual output."""
    return _rca_identity.build_failure_signature(snapshot, stdout=stdout, stderr=stderr)


def derive_session_id(
    snapshot: dict[str, Any] | None,
    *,
    out_dir: str,
    fallback: str = "global",
) -> str:
    """Derive stable session id from out_dir + pytest nodeid/name when available."""
    return _rca_identity.derive_session_id(snapshot, out_dir=out_dir, fallback=fallback)


def get_rca_history(
    *,
    out_dir: str,
    session_id: str | None = None,
    limit: int = 20,
) -> list[dict[str, Any]]:
    """Load RCA history, newest-first."""
    return _get_rca_history_backend(out_dir=out_dir, session_id=session_id, limit=limit)


def get_rca_status(*, out_dir: str, session_id: str | None = None) -> dict[str, Any] | None:
    """Return latest RCA attempt for a session."""
    return _get_rca_status_backend(out_dir=out_dir, session_id=session_id)


def advance_rca_attempt(
    *,
    out_dir: str,
    session_id: str,
    action: str,
    failure_signature: str,
    evidence_refs: list[str] | None = None,
    hypothesis: str | None = None,
    experiment_plan: str | None = None,
    proposed_change_summary: str | None = None,
    verification_result: dict[str, Any] | None = None,
    gate_mode: str | None = None,
    exploratory: bool = False,
    override_reason: str | None = None,
    stall_threshold: int = 3,
    exploration_budget: int = 2,
) -> dict[str, Any]:
    """Advance RCA state machine and persist attempt row."""
    now = _now_utc()
    previous = get_rca_status(out_dir=out_dir, session_id=session_id)
    record = build_rca_attempt_record(
        previous=previous,
        attempt_id=_new_attempt_id(),
        session_id=session_id,
        action=action,
        failure_signature=failure_signature,
        evidence_refs=evidence_refs,
        hypothesis=hypothesis,
        experiment_plan=experiment_plan,
        proposed_change_summary=proposed_change_summary,
        verification_result=verification_result,
        gate_mode=gate_mode,
        exploratory=exploratory,
        override_reason=override_reason,
        stall_threshold=stall_threshold,
        exploration_budget=exploration_budget,
        now=now,
    )
    persist_rca_record(out_dir=out_dir, record=record)
    return record


# Backward-compatible alias for callers/tests that use this constant.
_DEFAULT_STATE = DEFAULT_STATE
