"""
Text Domain Receipts

Includes:
- TextReceipt: For every text ingestion event

Part of Text Organ: Multi-fidelity text 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 text receipts
proofkit = ProofKit()
logger = logging.getLogger(__name__)


class TextMode(Enum):
    """Levels of text fidelity for the Text Organ."""

    SEMANTIC = "semantic"  # Layer A: Basic text extraction
    STRUCTURED = "structured"  # Layer B: With formatting/layout
    FULL = "full"  # Layer C: Complete document with metadata


class TextReceipt(BaseReceipt):
    """
    Cryptographic receipt for every text ingestion event.
    Keeps the Text Organ constitutional - every 'read' is governed.
    """

    receipt_type: str = "TextReceipt"

    # Text specifics
    text_mode: str  # "semantic", "structured", "full"
    reason: str     # Why this fidelity level was chosen
    app_context: str # Active application
    content_type: str = "text/plain"  # MIME type
    char_count: int = 0  # Character count

    # 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 text 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 TextReceipt {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 TextReceipt: {self.receipt_id}")
        except Exception as e:
            logger.error(f"Failed to sign TextReceipt {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 text 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 TextReceipt {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 text receipts

def create_text_receipt(
    text_mode: TextMode,
    reason: str,
    app_context: str,
    content_type: str = "text/plain",
    char_count: 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
) -> TextReceipt:
    """
    Create a TextReceipt for a text capture event.

    Args:
        text_mode: Level of text fidelity used
        reason: Why this fidelity level was chosen
        app_context: Active application during capture
        content_type: MIME type of the text content
        char_count: Number of characters captured
        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:
        TextReceipt 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"txt_{int(time.time())}_{uuid.uuid4().hex[:8]}"
    
    # Set domain if not provided
    if "domain" not in kwargs:
        kwargs["domain"] = "text"

    receipt = TextReceipt(
        text_mode=text_mode.value,
        reason=reason,
        app_context=app_context,
        content_type=content_type,
        char_count=char_count,
        capture_ms=capture_ms,
        data_size_bytes=data_size_bytes,
        privacy_safe=True,  # Text captures are generally privacy-safe
        consent_obtained=True,  # Assume consent for text
        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_text_receipt(receipt: TextReceipt) -> str:
    """
    Emit a TextReceipt 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"text_{int(time.time())}_{hash(str(receipt)) % 10000}"
    logger.info(f"Emitted TextReceipt: {receipt_id}")
    return receipt_id


# Example usage

def example_text_receipt():
    """Example of creating and emitting a TextReceipt."""
    # Example signing key (in production, use proper key management)
    sign_key = b"example-key-32-bytes-for-text!!!"

    receipt = create_text_receipt(
        text_mode=TextMode.SEMANTIC,
        reason="reading error message",
        app_context="VSCode",
        content_type="text/plain",
        char_count=247,
        capture_ms=15,
        data_size_bytes=512,
        sign_key=sign_key  # Enable cryptographic signing
    )

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

    receipt_id = emit_text_receipt(receipt)
    return receipt_id


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