"""
Reputation Receipts - Audit trail for agent trust scoring.

These receipts track:
    - Task outcomes recorded
    - Trust score changes
    - Tier promotions/demotions
    - Penalties and bonuses
    - Agent recommendations

Part of the Agent Reputation Engine that tracks
trust and performance across agents.
"""

from __future__ import annotations

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

from receipts.base import BaseReceipt


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

    Records the performance data that updates reputation.
    """

    receipt_type: str = "TaskOutcomeRecordedReceipt"
    domain: str = "organism"
    organ: str = "reputation"

    # Agent
    agent_id: str

    # Task details
    task_id: str
    task_type: str
    success: bool

    # Quality metrics
    quality_score: float
    value_delivered: float
    cost_incurred: float
    efficiency: float

    # Integrity metrics
    intent_preserved: bool
    compliance_score: float

    # Trust change
    old_trust: float
    new_trust: float
    trust_delta: float

    # Tier
    tier: str

    def __init__(
        self,
        *,
        agent_id: str,
        task_id: str,
        task_type: str,
        success: bool,
        quality_score: float,
        value_delivered: float,
        cost_incurred: float,
        intent_preserved: bool,
        compliance_score: float,
        old_trust: float,
        new_trust: float,
        tier: str,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"outcome_{agent_id}_{task_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        efficiency = value_delivered / max(cost_incurred, 0.1)
        trust_delta = new_trust - old_trust

        super().__init__(
            receipt_id=receipt_id,
            agent_id=agent_id,
            task_id=task_id,
            task_type=task_type,
            success=success,
            quality_score=quality_score,
            value_delivered=value_delivered,
            cost_incurred=cost_incurred,
            efficiency=efficiency,
            intent_preserved=intent_preserved,
            compliance_score=compliance_score,
            old_trust=old_trust,
            new_trust=new_trust,
            trust_delta=trust_delta,
            tier=tier,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class TrustScoreChangeReceipt(BaseReceipt):
    """
    Emitted when an agent's trust score changes significantly.

    Records trust transitions for audit trail.
    """

    receipt_type: str = "TrustScoreChangeReceipt"
    domain: str = "organism"
    organ: str = "reputation"

    # Agent
    agent_id: str

    # Trust change
    old_trust: float
    new_trust: float
    trust_delta: float
    change_type: str  # "task_outcome", "penalty", "bonus", "decay"
    reason: str

    # Tier change
    old_tier: str
    new_tier: str
    tier_changed: bool

    def __init__(
        self,
        *,
        agent_id: str,
        old_trust: float,
        new_trust: float,
        change_type: str,
        reason: str,
        old_tier: str,
        new_tier: str,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"trust_change_{agent_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            agent_id=agent_id,
            old_trust=old_trust,
            new_trust=new_trust,
            trust_delta=new_trust - old_trust,
            change_type=change_type,
            reason=reason,
            old_tier=old_tier,
            new_tier=new_tier,
            tier_changed=old_tier != new_tier,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class TierChangeReceipt(BaseReceipt):
    """
    Emitted when an agent's tier changes.

    Records tier promotions and demotions.
    """

    receipt_type: str = "TierChangeReceipt"
    domain: str = "organism"
    organ: str = "reputation"

    # Agent
    agent_id: str

    # Tier change
    old_tier: str
    new_tier: str
    direction: str  # "promotion" or "demotion"

    # Context
    trust_score: float
    total_tasks: int
    trigger: str  # What caused the change

    def __init__(
        self,
        *,
        agent_id: str,
        old_tier: str,
        new_tier: str,
        trust_score: float,
        total_tasks: int,
        trigger: str,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"tier_change_{agent_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        tier_order = ["unknown", "probation", "trusted", "verified", "elite"]
        old_idx = tier_order.index(old_tier) if old_tier in tier_order else 0
        new_idx = tier_order.index(new_tier) if new_tier in tier_order else 0
        direction = "promotion" if new_idx > old_idx else "demotion"

        super().__init__(
            receipt_id=receipt_id,
            agent_id=agent_id,
            old_tier=old_tier,
            new_tier=new_tier,
            direction=direction,
            trust_score=trust_score,
            total_tasks=total_tasks,
            trigger=trigger,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class AgentRecommendationReceipt(BaseReceipt):
    """
    Emitted when an agent recommendation is made.

    Records which agent was recommended for a task.
    """

    receipt_type: str = "AgentRecommendationReceipt"
    domain: str = "organism"
    organ: str = "reputation"

    # Request
    task_type: str
    candidates: List[str]
    min_tier: str

    # Recommendation
    recommended_agent: Optional[str]
    recommendation_score: float
    reasoning: List[str]

    # Alternatives
    all_scores: Dict[str, float]

    def __init__(
        self,
        *,
        task_type: str,
        candidates: List[str],
        min_tier: str,
        recommended_agent: Optional[str],
        recommendation_score: float,
        reasoning: List[str],
        all_scores: Dict[str, float],
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"recommendation_{task_type}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            task_type=task_type,
            candidates=candidates,
            min_tier=min_tier,
            recommended_agent=recommended_agent,
            recommendation_score=recommendation_score,
            reasoning=reasoning,
            all_scores=all_scores,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


class ReputationPenaltyReceipt(BaseReceipt):
    """
    Emitted when a reputation penalty is applied.

    Records manual trust reductions.
    """

    receipt_type: str = "ReputationPenaltyReceipt"
    domain: str = "organism"
    organ: str = "reputation"

    # Agent
    agent_id: str

    # Penalty
    penalty_amount: float
    reason: str

    # Result
    old_trust: float
    new_trust: float
    tier_affected: bool

    def __init__(
        self,
        *,
        agent_id: str,
        penalty_amount: float,
        reason: str,
        old_trust: float,
        new_trust: float,
        tier_affected: bool = False,
        ts: Optional[datetime] = None,
        parent_ids: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        ts = ts or datetime.now(timezone.utc)
        receipt_id = f"penalty_{agent_id}_{ts.strftime('%Y%m%d%H%M%S%f')}"

        super().__init__(
            receipt_id=receipt_id,
            agent_id=agent_id,
            penalty_amount=penalty_amount,
            reason=reason,
            old_trust=old_trust,
            new_trust=new_trust,
            tier_affected=tier_affected,
            ts=ts,
            parent_ids=parent_ids or [],
            **kwargs,
        )


__all__ = [
    "TaskOutcomeRecordedReceipt",
    "TrustScoreChangeReceipt",
    "TierChangeReceipt",
    "AgentRecommendationReceipt",
    "ReputationPenaltyReceipt",
]
