"""
Phase Receipt Emitter - Lightweight utilities for emitting MetabolicPhaseReceipts.

Usage at gate transition points:
    from receipts.phase_emitter import emit_phase_transition

    # On EVHD failure
    emit_phase_transition(
        from_phase="flow",
        to_phase="contradiction",
        catalyst="evhd_monotonicity_fail",
        related_receipt_id=prophecy_id,
        context={"rho": 0.45, "threshold": 0.60}
    )
"""

from __future__ import annotations

import logging
from pathlib import Path
from typing import Any, Dict, Literal, Optional
from datetime import datetime, timezone

from receipts.crif import MetabolicPhaseReceipt
from receipts.writer import write_receipt

logger = logging.getLogger(__name__)

PhaseType = Literal["contradiction", "recursion", "incompleteness", "flow"]


def emit_phase_transition(
    from_phase: PhaseType,
    to_phase: PhaseType,
    catalyst: str,
    related_receipt_id: Optional[str] = None,
    context: Optional[Dict[str, Any]] = None,
    domain: str = "loom_metabolics",
) -> Optional[str]:
    """
    Emit a MetabolicPhaseReceipt marking a CRIF phase transition.

    Args:
        from_phase: Source CRIF phase
        to_phase: Target CRIF phase
        catalyst: Trigger description (e.g., "evhd_monotonicity_fail", "dignity_floor_breach")
        related_receipt_id: Optional related decision receipt ID
        context: Optional additional context (thresholds, values, etc.)
        domain: Receipt domain

    Returns:
        Receipt ID if successfully written, None otherwise

    Examples:
        # EVHD monotonicity failure
        emit_phase_transition(
            "flow", "contradiction",
            "evhd_monotonicity_fail",
            related_receipt_id="PROP_MLB_001",
            context={"rho": 0.45, "threshold": 0.60, "support": 250}
        )

        # Dignity floor breach
        emit_phase_transition(
            "flow", "contradiction",
            "dignity_floor_breach",
            related_receipt_id="PROP_MLB_002",
            context={"dwf": 0.65, "floor": 0.70}
        )

        # Calibration coverage failure
        emit_phase_transition(
            "flow", "incompleteness",
            "calibration_coverage_fail",
            context={"empirical": 0.85, "target": 0.90, "tolerance": 0.02}
        )

        # Successful recalibration
        emit_phase_transition(
            "incompleteness", "flow",
            "recalibration_success",
            context={"ece_before": 0.045, "ece_after": 0.018}
        )
    """
    try:
        # Generate receipt ID
        ts_str = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
        receipt_id = f"PHASE_{from_phase}_{to_phase}_{ts_str}"

        # Build receipt
        receipt = MetabolicPhaseReceipt(
            receipt_id=receipt_id,
            domain=domain,
            from_phase=from_phase,
            to_phase=to_phase,
            catalyst=catalyst,
            related_receipt_id=related_receipt_id,
        )

        # Add context to metadata if provided
        if context:
            if not hasattr(receipt, "metadata"):
                receipt.metadata = {}  # type: ignore[attr-defined]
            receipt.metadata.update(context)  # type: ignore[attr-defined]

        # Write receipt
        write_receipt(receipt)

        logger.info(
            "Emitted phase transition: %s → %s (catalyst: %s) → %s",
            from_phase,
            to_phase,
            catalyst,
            receipt_id,
        )

        return receipt_id

    except Exception as e:
        # Non-blocking: log error but don't crash the pipeline
        logger.warning(
            "Failed to emit phase transition %s → %s: %s",
            from_phase,
            to_phase,
            e,
            exc_info=True,
        )
        return None


# Convenience functions for common transitions

def emit_evhd_failure(
    rho: Optional[float],
    threshold: float,
    support: int,
    related_receipt_id: Optional[str] = None,
) -> Optional[str]:
    """Emit phase receipt for EVHD monotonicity failure."""
    return emit_phase_transition(
        from_phase="flow",
        to_phase="contradiction",  # Historical validation contradicts model
        catalyst="evhd_monotonicity_fail",
        related_receipt_id=related_receipt_id,
        context={
            "rho": rho,
            "threshold": threshold,
            "support": support,
        },
    )


def emit_dignity_failure(
    dwf: float,
    floor: float,
    related_receipt_id: Optional[str] = None,
) -> Optional[str]:
    """Emit phase receipt for dignity floor breach."""
    return emit_phase_transition(
        from_phase="flow",
        to_phase="contradiction",  # Low confidence = model contradicts itself
        catalyst="dignity_floor_breach",
        related_receipt_id=related_receipt_id,
        context={
            "dwf": dwf,
            "floor": floor,
        },
    )


def emit_calibration_failure(
    empirical_coverage: Optional[float] = None,
    target_coverage: Optional[float] = None,
    ece_worst: Optional[float] = None,
    sample_size: Optional[int] = None,
    related_receipt_id: Optional[str] = None,
) -> Optional[str]:
    """Emit phase receipt for calibration/coverage failure."""
    context = {}
    if empirical_coverage is not None:
        context["empirical_coverage"] = empirical_coverage
    if target_coverage is not None:
        context["target_coverage"] = target_coverage
    if ece_worst is not None:
        context["ece_worst"] = ece_worst
    if sample_size is not None:
        context["sample_size"] = sample_size

    return emit_phase_transition(
        from_phase="flow",
        to_phase="incompleteness",  # Coverage gap = incomplete calibration
        catalyst="calibration_coverage_fail",
        related_receipt_id=related_receipt_id,
        context=context,
    )


def emit_recalibration_success(
    ece_before: Optional[float] = None,
    ece_after: Optional[float] = None,
    coverage_before: Optional[float] = None,
    coverage_after: Optional[float] = None,
    related_receipt_id: Optional[str] = None,
) -> Optional[str]:
    """Emit phase receipt for successful recalibration (flow restored)."""
    context = {}
    if ece_before is not None:
        context["ece_before"] = ece_before
    if ece_after is not None:
        context["ece_after"] = ece_after
    if coverage_before is not None:
        context["coverage_before"] = coverage_before
    if coverage_after is not None:
        context["coverage_after"] = coverage_after

    return emit_phase_transition(
        from_phase="incompleteness",
        to_phase="flow",  # Calibration restored = flow resumed
        catalyst="recalibration_success",
        related_receipt_id=related_receipt_id,
        context=context,
    )


__all__ = [
    "emit_phase_transition",
    "emit_evhd_failure",
    "emit_dignity_failure",
    "emit_calibration_failure",
    "emit_recalibration_success",
]
