"""
Proof-Aware Receipt Writer

Wraps receipt emission with tri-temporal proof chain + Merkle epochs.

Usage:
    from receipts.proof_writer import emit_proof_receipt

    receipt = emit_proof_receipt(
        {"receipt_type": "ClinicalProphecyStone", ...},
        stream_key="clinical/sepsis/patient-abc",
        anchor_critical=True,  # For court-grade receipts
    )
"""

from __future__ import annotations

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

from receipts.proof_chain import ProofChainEntry, get_proof_chain
from receipts.merkle_epoch import MerkleEpoch, get_epoch_manager

logger = logging.getLogger(__name__)


def emit_proof_receipt(
    receipt: Dict[str, Any],
    *,
    stream_key: str,
    event_time: Optional[datetime] = None,
    sign: bool = True,
    timestamp: bool = True,
    anchor_critical: bool = False,
    epoch_storage_dir: Optional[Path] = None,
) -> Dict[str, Any]:
    """
    Emit a receipt with full proof chain integration.

    This adds tri-temporal timestamps (E/O/R), hash chaining, and
    Merkle epoch integration to any receipt.

    Args:
        receipt: The receipt payload (dict)
        stream_key: Stream identifier (e.g., "clinical/prior_auth/CASE-9271")
        event_time: Claimed event time (defaults to now)
        sign: Whether to Ed25519 sign (placeholder for now)
        timestamp: Whether to add RFC 3161 timestamp
        anchor_critical: Force immediate Rekor anchor (for court-grade)
        epoch_storage_dir: Directory for epoch persistence

    Returns:
        Receipt augmented with proof_chain block:
        {
            ...original fields...
            "proof_chain": {
                "id": "sha256:...",
                "prev": "sha256:...",
                "stream_key": "...",
                "event_time": "...",
                "observed_at": "...",
                "receipt_at": "...",
                "payload_hash": "sha256:...",
                "deltaC": {...},
                "epoch_id": "...",
                "rekor": {...}  # if anchored
            }
        }
    """
    proof_chain = get_proof_chain()
    epoch_manager = get_epoch_manager(storage_dir=epoch_storage_dir)

    # Step 1: Add to proof chain (computes E/O/R and hash)
    entry = proof_chain.append(
        stream_key=stream_key,
        payload=receipt,
        event_time=event_time,
    )

    # Step 2: Add to Merkle epoch
    epoch = epoch_manager.add_entry(entry)

    # Step 3: Augment receipt with proof fields
    proof_block = {
        "id": entry.id,
        "prev": entry.prev,
        "stream_key": stream_key,
        "event_time": entry.event_time.isoformat(),
        "observed_at": entry.observed_at.isoformat(),
        "receipt_at": entry.receipt_at.isoformat(),
        "payload_hash": entry.payload_hash,
        "deltaC": entry.delta_c,
        "epoch_id": epoch.epoch_id,
    }

    # Step 4: Optional RFC 3161 timestamp
    if timestamp:
        try:
            from receipts.rfc3161_utils import add_rfc3161_timestamp
            # Add to a copy to get TSA data
            temp = dict(receipt)
            add_rfc3161_timestamp(temp, use_stub=True, required=False)
            if "rfc3161_tst" in temp:
                proof_block["tsa"] = temp["rfc3161_tst"]
        except ImportError:
            logger.debug("RFC 3161 utils not available, skipping timestamp")
        except Exception as e:
            logger.warning("Failed to add RFC 3161 timestamp: %s", e)

    # Step 5: Critical anchoring (force close epoch + submit to Rekor)
    if anchor_critical:
        closed_epoch = epoch_manager.force_close()
        if closed_epoch:
            rekor_result = _anchor_epoch_to_rekor(closed_epoch)
            if rekor_result:
                proof_block["rekor"] = {
                    "epoch_id": closed_epoch.epoch_id,
                    "merkle_root": closed_epoch.merkle_root,
                    "uuid": closed_epoch.rekor_uuid,
                    "log_index": closed_epoch.rekor_log_index,
                    "timestamp": closed_epoch.rekor_timestamp.isoformat() if closed_epoch.rekor_timestamp else None,
                }
                logger.info(
                    "Critical anchor complete: stream=%s, rekor_uuid=%s",
                    stream_key,
                    closed_epoch.rekor_uuid,
                )

    receipt["proof_chain"] = proof_block

    logger.debug(
        "Emitted proof receipt: stream=%s, id=%s, epoch=%s",
        stream_key,
        entry.id[:16] + "...",
        epoch.epoch_id,
    )

    return receipt


def _anchor_epoch_to_rekor(epoch: MerkleEpoch) -> bool:
    """
    Anchor an epoch's Merkle root to Rekor.

    Returns True if successful, False otherwise.
    """
    try:
        from receipts.rekor_client import submit_to_rekor, REKOR_ENABLED

        if not REKOR_ENABLED:
            logger.debug("Rekor disabled, skipping anchor")
            return False

        if not epoch.merkle_root:
            epoch.compute_root()

        # Submit to Rekor
        # Note: Full implementation needs signing key
        result = submit_to_rekor(
            receipt_hash=epoch.merkle_root.replace("sha256:", ""),
            signature=b"",  # Placeholder - needs proper signing
            public_key=b"",  # Placeholder - needs key
            artifact_type=f"merkle_epoch:{epoch.epoch_id}",
        )

        if result:
            epoch.rekor_uuid = result.uuid
            epoch.rekor_log_index = result.log_index
            epoch.rekor_timestamp = datetime.now(timezone.utc)
            return True

        return False

    except ImportError:
        logger.debug("Rekor client not available")
        return False
    except Exception as e:
        logger.error("Failed to anchor epoch to Rekor: %s", e)
        return False


def verify_proof_chain(stream_key: str) -> Dict[str, Any]:
    """
    Verify integrity of a proof chain.

    Returns:
        {
            "valid": True/False,
            "chain_length": N,
            "head": "sha256:...",
            "tail": "sha256:...",
            "reason": "..." (if invalid)
        }
    """
    proof_chain = get_proof_chain()
    return proof_chain.verify_chain(stream_key)


def get_proof_chain_stats() -> Dict[str, Any]:
    """
    Get statistics about the proof chain and epochs.

    Returns:
        {
            "chains": N,
            "entries": N,
            "current_epoch": "...",
            "closed_epochs": N,
            "unanchored_epochs": N,
            ...
        }
    """
    proof_chain = get_proof_chain()
    epoch_manager = get_epoch_manager()

    return {
        **proof_chain.stats(),
        **epoch_manager.stats(),
    }


def get_chain_entries(stream_key: str, limit: int = 100) -> list:
    """Get entries from a proof chain."""
    proof_chain = get_proof_chain()
    entries = proof_chain.get_chain(stream_key, limit=limit)
    return [e.to_dict() for e in entries]


def force_close_epoch() -> Optional[Dict[str, Any]]:
    """Force close the current epoch and return its data."""
    epoch_manager = get_epoch_manager()
    epoch = epoch_manager.force_close()
    return epoch.to_dict() if epoch else None


def anchor_pending_epochs(max_count: int = 10) -> list:
    """
    Anchor pending epochs to Rekor.

    Returns list of anchored epoch IDs.
    """
    epoch_manager = get_epoch_manager()
    pending = epoch_manager.get_epochs_for_anchoring(max_count=max_count)

    anchored = []
    for epoch in pending:
        if _anchor_epoch_to_rekor(epoch):
            anchored.append(epoch.epoch_id)

    return anchored


__all__ = [
    "emit_proof_receipt",
    "verify_proof_chain",
    "get_proof_chain_stats",
    "get_chain_entries",
    "force_close_epoch",
    "anchor_pending_epochs",
]
