"""
Cross-organization attestation exchange.

Export and import signed attestation bundles for offline federation.
Bundles are self-authenticating: each record carries its signer_pubkey,
so the importer can verify signatures against their trust store.
"""

from __future__ import annotations

import hashlib
import json
from datetime import UTC, datetime
from pathlib import Path


def export_attestation_bundle(
    storage,
    chain_store,
    output_path: Path,
    investigation: str | None = None,
    start_index: int = 0,
    end_index: int | None = None,
) -> dict:
    """Export attestation records + chain wrapping as a signed JSON bundle.

    Args:
        storage: verisoo LocalStorage instance.
        chain_store: ChainStore instance (or None if chain disabled).
        output_path: Path to write the JSON bundle.
        investigation: Optional filter by investigation tag.
        start_index: Start record index in attestation log.
        end_index: End record index (default: all).

    Returns:
        Summary dict with record_count and path.
    """
    stats = storage.get_stats()
    if end_index is None:
        end_index = stats.record_count - 1

    records = []
    for i in range(start_index, end_index + 1):
        try:
            record = storage.get_record(i)
            # Filter by investigation if specified
            if investigation:
                meta = getattr(record, "metadata", {}) or {}
                if isinstance(meta, dict) and meta.get("investigation") != investigation:
                    continue

            rec_data = {
                "index": i,
                "attestor_fingerprint": record.attestor_fingerprint,
                "timestamp": record.timestamp.isoformat() if record.timestamp else None,
                "image_hashes": {
                    "sha256": record.image_hashes.sha256,
                    "phash": record.image_hashes.phash,
                    "dhash": getattr(record.image_hashes, "dhash", None),
                },
                "signature": record.signature.hex() if record.signature else None,
                "metadata": record.metadata if hasattr(record, "metadata") else {},
            }
            records.append(rec_data)
        except Exception:
            continue

    # Include chain records if available
    chain_records = []
    if chain_store is not None:
        try:
            for chain_rec in chain_store:
                chain_records.append({
                    "chain_index": chain_rec.chain_index,
                    "content_hash": chain_rec.content_hash.hex(),
                    "content_type": chain_rec.content_type,
                    "prev_hash": chain_rec.prev_hash.hex(),
                    "signer_pubkey": chain_rec.signer_pubkey.hex(),
                    "signature": chain_rec.signature.hex(),
                    "claimed_ts": chain_rec.claimed_ts,
                    "metadata": chain_rec.metadata,
                })
        except Exception:
            pass

    bundle = {
        "bundle_version": "1",
        "exported_at": datetime.now(UTC).isoformat(),
        "investigation": investigation,
        "attestation_records": records,
        "chain_records": chain_records,
        "record_count": len(records),
        "chain_record_count": len(chain_records),
    }

    output_path.write_text(json.dumps(bundle, indent=2, ensure_ascii=False))

    return {
        "path": str(output_path),
        "record_count": len(records),
        "chain_record_count": len(chain_records),
    }


def import_attestation_bundle(
    bundle_path: Path,
    storage,
    trusted_fingerprints: set[str] | None = None,
    chain_store=None,
    private_key=None,
) -> dict:
    """Import attestation records from a federation bundle.

    Records are stored in the local attestation log with a
    'federated_from' metadata tag. Only records signed by
    trusted fingerprints are imported.

    Args:
        bundle_path: Path to the JSON bundle.
        storage: verisoo LocalStorage instance.
        trusted_fingerprints: Set of trusted attestor fingerprints.
            If None, all records are imported (trust-on-first-use).

    Returns:
        Summary dict with imported/skipped/rejected counts.
    """
    bundle = json.loads(bundle_path.read_text())
    records = bundle.get("attestation_records", [])

    imported = 0
    skipped = 0
    rejected = 0

    for rec_data in records:
        fp = rec_data.get("attestor_fingerprint", "")

        # Check trust
        if trusted_fingerprints and fp not in trusted_fingerprints:
            rejected += 1
            continue

        # Check for duplicate (by SHA-256)
        sha256 = rec_data.get("image_hashes", {}).get("sha256", "")
        if sha256:
            existing = storage.get_records_by_image_sha256(sha256)
            if existing:
                skipped += 1
                continue

        # Import as federated record
        # Tag with federation source metadata
        meta = rec_data.get("metadata", {}) or {}
        meta["federated"] = True
        meta["federated_from"] = fp
        meta["federated_at"] = datetime.now(UTC).isoformat()

        # Store the record (the storage layer handles serialization)
        # We reconstruct a minimal record for append
        try:
            from soosef.verisoo.models import AttestationRecord, ImageHashes

            hashes = ImageHashes(
                sha256=rec_data["image_hashes"]["sha256"],
                phash=rec_data["image_hashes"].get("phash", ""),
                dhash=rec_data["image_hashes"].get("dhash", ""),
            )
            record = AttestationRecord(
                image_hashes=hashes,
                signature=bytes.fromhex(rec_data["signature"]) if rec_data.get("signature") else b"",
                attestor_fingerprint=fp,
                timestamp=datetime.fromisoformat(rec_data["timestamp"]) if rec_data.get("timestamp") else datetime.now(UTC),
                metadata=meta,
            )
            storage.append_record(record)
            imported += 1
        except Exception:
            rejected += 1

    # Generate delivery acknowledgment if chain store and private key provided
    ack_record = None
    if chain_store is not None and private_key is not None and imported > 0:
        try:
            bundle_hash = hashlib.sha256(bundle_path.read_bytes()).hexdigest()
            # Determine sender fingerprint from first imported record
            sender_fp = ""
            for rec_data in records:
                fp = rec_data.get("attestor_fingerprint", "")
                if fp:
                    sender_fp = fp
                    break
            ack_record = chain_store.append_delivery_ack(
                private_key=private_key,
                bundle_hash=bundle_hash,
                sender_fingerprint=sender_fp,
                records_received=imported,
            )
        except Exception:
            pass

    return {
        "imported": imported,
        "skipped": skipped,
        "rejected": rejected,
        "total": len(records),
        "investigation": bundle.get("investigation"),
        "ack_chain_index": ack_record.chain_index if ack_record else None,
    }
