"""
Audio Domain Receipts

Includes:
- AudioReceipt: For every audio ingestion event

Part of Audio Organ: Multi-fidelity audio perception
"""

import time
import logging
from typing import Dict, Any, Optional, List
from dataclasses import dataclass
from datetime import datetime
from enum import Enum

from receipts.base import BaseReceipt
from receipts.compat.pyd import Field
from tools.proofkit import ProofKit

# Initialize ProofKit for audio receipts
proofkit = ProofKit()
logger = logging.getLogger(__name__)


class AudioMode(Enum):
    """Levels of audio fidelity for the Audio Organ."""

    SEMANTIC = "semantic"  # Layer A: Text/transcript only
    LOW_QUALITY = "low_quality"  # Layer B: Compressed audio
    HIGH_QUALITY = "high_quality"  # Layer C: Full fidelity audio


class AudioReceipt(BaseReceipt):
    """
    Cryptographic receipt for every audio ingestion event.
    Keeps the Audio Organ constitutional - every 'listen' is governed.
    """

    receipt_type: str = "AudioReceipt"

    # Audio specifics
    audio_mode: str  # "semantic", "low_quality", "high_quality"
    reason: str      # Why this fidelity level was chosen
    app_context: str # Active application
    duration_ms: int = 0  # Audio duration
    sample_rate: int = 0  # Audio sample rate

    # Performance metrics
    capture_ms: int = 0
    data_size_bytes: int = 0

    # Constitutional & privacy
    privacy_safe: bool = True
    consent_obtained: bool = True
    consent_token: Optional[str] = None
    profile: str = "enterprise"
    receipt_mode: str = "signed"  # "signed" | "minimal"
    retention_days: Optional[int] = None
    encryption_required: bool = False

    # Proof Rails vNext attestation
    attestation: Dict[str, Any] = Field(default_factory=dict)

    def sign(self, key: bytes, algorithm: str = "hmac-sha256") -> None:
        """
        Sign this audio receipt with Proof Rails vNext attestation.

        Args:
            key: Signing key
            algorithm: Signing algorithm ("hmac-sha256" or "ed25519")
        """
        if self.receipt_mode != "signed":
            logger.debug(f"Skipping signature for AudioReceipt {self.receipt_id} (receipt_mode: {self.receipt_mode})")
            return

        try:
            # Create signed receipt data
            signed_receipt = proofkit.sign_receipt(
                self.to_dict(),
                key,
                algorithm
            )
            # Extract attestation block
            self.attestation = signed_receipt.get("attestation", {})
            logger.info(f"Signed AudioReceipt: {self.receipt_id}")
        except Exception as e:
            logger.error(f"Failed to sign AudioReceipt {self.receipt_id}: {e}")
            # Continue without attestation rather than failing

    def verify_signature(self, key: bytes, algorithm: str = "hmac-sha256") -> bool:
        """
        Verify the cryptographic signature of this audio receipt.

        Args:
            key: Verification key
            algorithm: Algorithm used for signing

        Returns:
            True if signature is valid
        """
        if not self.attestation:
            return False

        try:
            return proofkit.verify_receipt_signature(
                self.to_dict(),
                key,
                algorithm
            )
        except Exception as e:
            logger.error(f"Failed to verify AudioReceipt {self.receipt_id}: {e}")
            return False

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for serialization."""
        data = super().to_dict()
        # Ensure new fields are present explicitly
        data["profile"] = self.profile
        data["receipt_mode"] = self.receipt_mode
        data["retention_days"] = self.retention_days
        data["encryption_required"] = self.encryption_required
        return data


# Convenience functions for creating audio receipts

def create_audio_receipt(
    audio_mode: AudioMode,
    reason: str,
    app_context: str,
    duration_ms: int = 0,
    sample_rate: int = 0,
    capture_ms: int = 0,
    data_size_bytes: int = 0,
    sign_key: Optional[bytes] = None,
    sign_algorithm: str = "hmac-sha256",
    profile: str = "enterprise",
    receipt_mode: str = "signed",
    retention_days: Optional[int] = None,
    encryption_required: bool = False,
    consent_token: Optional[str] = None,
    **kwargs
) -> AudioReceipt:
    """
    Create an AudioReceipt for an audio capture event.

    Args:
        audio_mode: Level of audio fidelity used
        reason: Why this fidelity level was chosen
        app_context: Active application during capture
        duration_ms: Audio duration in milliseconds
        sample_rate: Audio sample rate
        capture_ms: Time taken to capture (performance metric)
        data_size_bytes: Size of captured data (performance metric)
        sign_key: Optional cryptographic key for signing
        sign_algorithm: Signing algorithm ("hmac-sha256" or "ed25519")
        profile: Profile determining signing behavior
        receipt_mode: "signed" or "minimal" mode
        retention_days: Optional retention period
        encryption_required: Whether encryption is required
        **kwargs: Additional fields

    Returns:
        AudioReceipt instance, signed if key provided and receipt_mode is "signed"
    """
    import uuid
    
    # Generate ID if not provided
    if "receipt_id" not in kwargs:
        kwargs["receipt_id"] = f"aud_{int(time.time())}_{uuid.uuid4().hex[:8]}"
    
    # Set domain if not provided
    if "domain" not in kwargs:
        kwargs["domain"] = "audio"

    receipt = AudioReceipt(
        audio_mode=audio_mode.value,
        reason=reason,
        app_context=app_context,
        duration_ms=duration_ms,
        sample_rate=sample_rate,
        capture_ms=capture_ms,
        data_size_bytes=data_size_bytes,
        privacy_safe=True,  # Audio captures are generally privacy-safe
        consent_obtained=True,  # Assume consent for audio
        consent_token=consent_token,
        profile=profile,
        receipt_mode=receipt_mode,
        retention_days=retention_days,
        encryption_required=encryption_required,
        **kwargs
    )

    # Sign if key provided and receipt_mode is "signed"
    if sign_key and receipt_mode == "signed":
        receipt.sign(sign_key, sign_algorithm)

    return receipt


def emit_audio_receipt(receipt: AudioReceipt) -> str:
    """
    Emit an AudioReceipt to the ledger.
    Returns the receipt ID.
    """
    # This would integrate with the existing receipt writer
    # For now, just return a mock ID
    receipt_id = f"audio_{int(time.time())}_{hash(str(receipt)) % 10000}"
    logger.info(f"Emitted AudioReceipt: {receipt_id}")
    return receipt_id


# Example usage

def example_audio_receipt():
    """Example of creating and emitting an AudioReceipt."""
    # Example signing key (in production, use proper key management)
    sign_key = b"example-key-32-bytes-for-audio!!!"

    receipt = create_audio_receipt(
        audio_mode=AudioMode.SEMANTIC,
        reason="voice command processing",
        app_context="Terminal",
        duration_ms=2500,
        sample_rate=16000,
        capture_ms=25,
        data_size_bytes=5120,
        sign_key=sign_key  # Enable cryptographic signing
    )

    # Verify signature works
    is_valid = receipt.verify_signature(sign_key)
    print(f"AudioReceipt signature valid: {is_valid}")

    receipt_id = emit_audio_receipt(receipt)
    return receipt_id


if __name__ == "__main__":
    # Run example
    receipt_id = example_audio_receipt()
    print(f"Created AudioReceipt: {receipt_id}")