"""
Symbiosis Receipts - Audit trail for task species co-evolution.

These receipts track:
    - When task pairings are observed
    - When symbiotic relationships are discovered
    - When ecosystem state changes
    - When species fitness evolves

Part of the Symbiosis Engine that makes the system smarter
by learning which tasks work well together.
"""

from __future__ import annotations

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

from receipts.base import BaseReceipt


class TaskPairingObservedReceipt(BaseReceipt):
    """
    Emitted when a task pairing outcome is recorded.

    This is the raw observation data that feeds the symbiosis engine.
    """

    receipt_type: str = "TaskPairingObservedReceipt"
    domain: str = "organism"
    organ: str = "symbiosis"

    # Pairing details
    species_a: str
    species_b: str
    sequence: str  # "parallel", "sequential_ab", "sequential_ba"

    # Outcome
    success: bool
    efficiency_multiplier: float
    duration_ms: float

    # Context
    goal_id: Optional[str] = None

    def __init__(
        self,
        *,
        species_a: str,
        species_b: str,
        sequence: str,
        success: bool,
        efficiency_multiplier: float,
        duration_ms: float = 0.0,
        goal_id: 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"pairing_{species_a}_{species_b}_{ts.strftime('%Y%m%d%H%M%S%f')}"
        super().__init__(
            receipt_id=receipt_id,
            species_a=species_a,
            species_b=species_b,
            sequence=sequence,
            success=success,
            efficiency_multiplier=efficiency_multiplier,
            duration_ms=duration_ms,
            goal_id=goal_id,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class SymbiosisDiscoveredReceipt(BaseReceipt):
    """
    Emitted when a significant symbiotic relationship is discovered.

    This marks the moment when the system learns that two task types
    work particularly well (or poorly) together.
    """

    receipt_type: str = "SymbiosisDiscoveredReceipt"
    domain: str = "organism"
    organ: str = "symbiosis"

    # Relationship
    species_a: str
    species_b: str
    relationship_type: str  # "mutualism", "competition", etc.

    # Metrics
    symbiosis_score: float  # [-1, 1]
    confidence: float  # [0, 1]
    sample_count: int
    avg_efficiency_boost: float

    def __init__(
        self,
        *,
        species_a: str,
        species_b: str,
        relationship_type: str,
        symbiosis_score: float,
        confidence: float,
        sample_count: int,
        avg_efficiency_boost: float,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"symbiosis_{species_a}_{species_b}_{ts.strftime('%Y%m%d%H%M%S')}"
        super().__init__(
            receipt_id=receipt_id,
            species_a=species_a,
            species_b=species_b,
            relationship_type=relationship_type,
            symbiosis_score=symbiosis_score,
            confidence=confidence,
            sample_count=sample_count,
            avg_efficiency_boost=avg_efficiency_boost,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class EcosystemStateChangeReceipt(BaseReceipt):
    """
    Emitted when the ecosystem state changes.

    This tracks the overall health of the task ecosystem.
    """

    receipt_type: str = "EcosystemStateChangeReceipt"
    domain: str = "organism"
    organ: str = "symbiosis"

    # State change
    previous_state: str
    new_state: str  # "thriving", "balanced", "stressed", "degraded", "collapsed"

    # Metrics at time of change
    diversity_index: float
    total_efficiency: float
    total_species: int
    viable_species: int
    mutualistic_relationships: int
    competitive_relationships: int

    # Trigger
    trigger_reason: str  # Why the change happened

    def __init__(
        self,
        *,
        previous_state: str,
        new_state: str,
        diversity_index: float,
        total_efficiency: float,
        total_species: int,
        viable_species: int,
        mutualistic_relationships: int,
        competitive_relationships: int,
        trigger_reason: str = "metrics_threshold",
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"ecosystem_{new_state}_{ts.strftime('%Y%m%d%H%M%S')}"
        super().__init__(
            receipt_id=receipt_id,
            previous_state=previous_state,
            new_state=new_state,
            diversity_index=diversity_index,
            total_efficiency=total_efficiency,
            total_species=total_species,
            viable_species=viable_species,
            mutualistic_relationships=mutualistic_relationships,
            competitive_relationships=competitive_relationships,
            trigger_reason=trigger_reason,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class SpeciesFitnessUpdateReceipt(BaseReceipt):
    """
    Emitted when a species' fitness is updated.

    Tracks the evolution of task species over time.
    """

    receipt_type: str = "SpeciesFitnessUpdateReceipt"
    domain: str = "organism"
    organ: str = "symbiosis"

    # Species
    species_name: str

    # Fitness change
    old_fitness: float
    new_fitness: float
    fitness_trend: float  # Positive = improving

    # Context
    success_rate: float
    total_spawned: int
    total_completed: int
    total_failed: int

    def __init__(
        self,
        *,
        species_name: str,
        old_fitness: float,
        new_fitness: float,
        fitness_trend: float,
        success_rate: float,
        total_spawned: int,
        total_completed: int,
        total_failed: int,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"fitness_{species_name}_{ts.strftime('%Y%m%d%H%M%S')}"
        super().__init__(
            receipt_id=receipt_id,
            species_name=species_name,
            old_fitness=old_fitness,
            new_fitness=new_fitness,
            fitness_trend=fitness_trend,
            success_rate=success_rate,
            total_spawned=total_spawned,
            total_completed=total_completed,
            total_failed=total_failed,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class PairingRecommendationReceipt(BaseReceipt):
    """
    Emitted when the engine makes a pairing recommendation.

    Tracks what the system learned and what it suggests.
    """

    receipt_type: str = "PairingRecommendationReceipt"
    domain: str = "organism"
    organ: str = "symbiosis"

    # Request
    current_species: str
    available_species: List[str]

    # Recommendation
    recommended_species: Optional[str]
    recommendation_score: float
    recommendation_reason: str

    # Context
    symbiosis_score: Optional[float] = None
    confidence: Optional[float] = None

    def __init__(
        self,
        *,
        current_species: str,
        available_species: List[str],
        recommended_species: Optional[str],
        recommendation_score: float,
        recommendation_reason: str,
        symbiosis_score: Optional[float] = None,
        confidence: Optional[float] = None,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"recommendation_{current_species}_{ts.strftime('%Y%m%d%H%M%S%f')}"
        super().__init__(
            receipt_id=receipt_id,
            current_species=current_species,
            available_species=available_species,
            recommended_species=recommended_species,
            recommendation_score=recommendation_score,
            recommendation_reason=recommendation_reason,
            symbiosis_score=symbiosis_score,
            confidence=confidence,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


__all__ = [
    "TaskPairingObservedReceipt",
    "SymbiosisDiscoveredReceipt",
    "EcosystemStateChangeReceipt",
    "SpeciesFitnessUpdateReceipt",
    "PairingRecommendationReceipt",
]
