from __future__ import annotations

from typing import Iterable, List, Tuple

from .evidence_receipt import EvidenceReceipt, compute_merkle_leaf
from .anchor_service import AnchorService


def anchor_receipts(service: AnchorService, receipts: Iterable[EvidenceReceipt]) -> List[EvidenceReceipt]:
    """Anchor a batch of receipts with the AnchorService and return new receipts
    with anchor metadata attached immutably.

    Each returned receipt is a new instance with metadata extended with:
      - merkle_root
      - merkle_proof
      - merkle_index
      - anchor_id

    The ordering of receipts is the list order provided.
    """
    rec_list = list(receipts)
    leaves = [compute_merkle_leaf(r) for r in rec_list]
    anchor = service.add_anchor(leaves)
    anchor_id = anchor["anchor_id"]
    merkle_root = anchor["merkle_root"]
    # propagate the full signed envelope information so downstream
    # consumers can verify the anchor (signature_input, content_digest, signature)
    sig_input = anchor.get("signature_input")
    content_digest = anchor.get("content_digest")
    signature = anchor.get("signature")

    anchored: List[EvidenceReceipt] = []
    for idx, r in enumerate(rec_list):
        proof = service.get_proof(anchor_id, idx)
        # produce a new EvidenceReceipt with metadata extended immutably
        new_meta = {
            **(r.metadata or {}),
            "merkle_root": merkle_root,
            "merkle_proof": proof,
            "merkle_index": idx,
            "anchor_id": anchor_id,
            "anchor_signature_input": sig_input,
            "anchor_content_digest": content_digest,
            "anchor_signature": signature,
        }
        new_r = r.__class__(
            timestamp=r.timestamp,
            guardian_policy_version=r.guardian_policy_version,
            dna_hash=r.dna_hash,
            evidence_type=r.evidence_type,
            source=r.source,
            metadata=new_meta,
            voice_hash=r.voice_hash,
            scene_hash=r.scene_hash,
            prediction_hash=r.prediction_hash,
            freshness_ms=r.freshness_ms,
        )
        anchored.append(new_r)

    return anchored


__all__ = ["anchor_receipts"]
