"""
Intent Integrity receipts — audit trail for semantic intent verification.

These receipts track:
    - When intent hashes are assigned to goals/tasks/relays
    - When intent drift is detected across handoffs
    - Chain of custody for semantic intent

Part of the Intent Integrity System that ensures goals survive
multi-agent handoff chains without semantic corruption.
"""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Any, Dict, List, Optional

from receipts.base import BaseReceipt


class IntentHashAssignedReceipt(BaseReceipt):
    """
    Emitted when an intent hash is computed and assigned.

    This marks the origin point of intent tracking for a goal/task/relay.
    """

    receipt_type: str = "IntentHashAssignedReceipt"
    domain: str = "governance"
    organ: str = "intent_integrity"

    # What entity received the hash
    entity_type: str  # "goal", "task", "relay"
    entity_id: str

    # The computed hash
    intent_hash: str
    algorithm: str = "sha256"

    # Source fields used to compute hash
    intent_fields: Dict[str, Any]

    # Context
    agent_id: Optional[str] = None  # Which agent computed/assigned it
    step_name: Optional[str] = None  # "origin", "handoff_to_qa", etc.

    def __init__(
        self,
        *,
        entity_type: str,
        entity_id: str,
        intent_hash: str,
        intent_fields: Dict[str, Any],
        algorithm: str = "sha256",
        agent_id: Optional[str] = None,
        step_name: Optional[str] = None,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"intent_assigned_{entity_id}_{ts.isoformat()}"
        super().__init__(
            receipt_id=receipt_id,
            entity_type=entity_type,
            entity_id=entity_id,
            intent_hash=intent_hash,
            intent_fields=intent_fields,
            algorithm=algorithm,
            agent_id=agent_id,
            step_name=step_name,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class IntentDriftDetectedReceipt(BaseReceipt):
    """
    Emitted when intent drift is detected during verification.

    This is a CRITICAL audit event — it means the semantic goal
    has changed during handoff, which may indicate:
        - Accidental scope creep
        - Miscommunication between agents
        - Malicious intent modification

    Systems should alert on this receipt type.
    """

    receipt_type: str = "IntentDriftDetectedReceipt"
    domain: str = "governance"
    organ: str = "intent_integrity"

    # What entity drifted
    entity_type: str  # "goal", "task", "relay"
    entity_id: str

    # The hashes
    original_intent_hash: str
    current_intent_hash: str

    # Drift details
    drift_delta: Dict[str, Any]  # {added, removed, modified}
    drift_severity: str = "warning"  # "info", "warning", "critical"

    # Context
    from_agent: Optional[str] = None
    to_agent: Optional[str] = None
    relay_id: Optional[str] = None
    step_name: Optional[str] = None

    def __init__(
        self,
        *,
        entity_type: str,
        entity_id: str,
        original_intent_hash: str,
        current_intent_hash: str,
        drift_delta: Dict[str, Any],
        drift_severity: str = "warning",
        from_agent: Optional[str] = None,
        to_agent: Optional[str] = None,
        relay_id: Optional[str] = None,
        step_name: Optional[str] = None,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"intent_drift_{entity_id}_{ts.isoformat()}"
        super().__init__(
            receipt_id=receipt_id,
            entity_type=entity_type,
            entity_id=entity_id,
            original_intent_hash=original_intent_hash,
            current_intent_hash=current_intent_hash,
            drift_delta=drift_delta,
            drift_severity=drift_severity,
            from_agent=from_agent,
            to_agent=to_agent,
            relay_id=relay_id,
            step_name=step_name,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class IntentChainValidatedReceipt(BaseReceipt):
    """
    Emitted after validating intent across a relay chain.

    Records the full chain verification result for auditing.
    """

    receipt_type: str = "IntentChainValidatedReceipt"
    domain: str = "governance"
    organ: str = "intent_integrity"

    # Chain info
    chain_id: str  # Usually the root task/goal ID
    chain_length: int
    relay_ids: List[str]

    # Validation result
    is_valid: bool
    drift_events: List[Dict[str, Any]]  # List of {index, from_hash, to_hash}

    # Original intent
    original_intent_hash: str
    final_intent_hash: Optional[str] = None

    def __init__(
        self,
        *,
        chain_id: str,
        chain_length: int,
        relay_ids: List[str],
        is_valid: bool,
        drift_events: List[Dict[str, Any]],
        original_intent_hash: str,
        final_intent_hash: Optional[str] = None,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"intent_chain_{chain_id}_{ts.isoformat()}"
        super().__init__(
            receipt_id=receipt_id,
            chain_id=chain_id,
            chain_length=chain_length,
            relay_ids=relay_ids,
            is_valid=is_valid,
            drift_events=drift_events,
            original_intent_hash=original_intent_hash,
            final_intent_hash=final_intent_hash,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class IntentRestoredReceipt(BaseReceipt):
    """
    Emitted when drifted intent is restored to original.

    This is a recovery action — someone/something corrected
    the intent back to the original specification.
    """

    receipt_type: str = "IntentRestoredReceipt"
    domain: str = "governance"
    organ: str = "intent_integrity"

    entity_type: str
    entity_id: str

    # Before and after
    drifted_intent_hash: str
    restored_intent_hash: str

    # How it was restored
    restoration_method: str  # "manual", "auto_rollback", "agent_correction"
    restored_by: Optional[str] = None  # agent_id or user_id

    def __init__(
        self,
        *,
        entity_type: str,
        entity_id: str,
        drifted_intent_hash: str,
        restored_intent_hash: str,
        restoration_method: str,
        restored_by: Optional[str] = None,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"intent_restored_{entity_id}_{ts.isoformat()}"
        super().__init__(
            receipt_id=receipt_id,
            entity_type=entity_type,
            entity_id=entity_id,
            drifted_intent_hash=drifted_intent_hash,
            restored_intent_hash=restored_intent_hash,
            restoration_method=restoration_method,
            restored_by=restored_by,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


__all__ = [
    "IntentHashAssignedReceipt",
    "IntentDriftDetectedReceipt",
    "IntentChainValidatedReceipt",
    "IntentRestoredReceipt",
]
