"""
Background Task Orchestrator Receipts

Receipt types for all background task events:
- BackgroundTaskReceipt
- BackgroundTaskProgressReceipt
- BackgroundTaskCompleteReceipt
- BackgroundTaskErrorReceipt
- AttentionAllocationReceipt

These form the complete audit trail of concurrent background execution.
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from pydantic import Field

from receipts.base import BaseReceipt


# ─────────────────────────────────────────────────────────────────────
# Receipt Types
# ─────────────────────────────────────────────────────────────────────

class BackgroundTaskSpawnedReceipt(BaseReceipt):
    """
    Emitted when a background task is spawned.

    This is the "birth certificate" of a background task.
    Records the request, priority, and expected duration.
    """
    receipt_type: str = Field(default="BackgroundTaskSpawnedReceipt", alias="type")
    domain: str = Field(default="organism")

    task_id: str = Field(description="Unique task identifier")
    parent_goal_id: str = Field(description="Goal that spawned this task")
    task_type: str = Field(description="Type: goal, script, test, index, analysis, maintenance")
    description: str = Field(description="Human-readable task description")
    priority: str = Field(default="normal", description="Priority: low, normal, high, critical")
    auto_retry: bool = Field(default=True, description="Should we retry on failure?")
    max_retries: int = Field(default=3, description="How many times to retry")
    estimated_duration_ms: Optional[float] = Field(default=None, description="Estimated duration")
    constraints: Optional[Dict[str, Any]] = Field(default=None, description="Task constraints")


class BackgroundTaskProgressReceipt(BaseReceipt):
    """
    Emitted periodically while a background task is running.

    Updates the progress, resource usage, and status.
    """
    receipt_type: str = Field(default="BackgroundTaskProgressReceipt", alias="type")
    domain: str = Field(default="organism")

    task_id: str = Field(description="Task being updated")
    progress_percent: int = Field(ge=0, le=100, description="Progress 0-100")
    status: str = Field(description="polling, executing, finalizing")
    current_step: str = Field(description="Current organism phase: eyes, brain, hands")
    items_processed: Optional[int] = Field(default=None, description="Items completed")
    items_remaining: Optional[int] = Field(default=None, description="Items remaining")
    cpu_usage_percent: float = Field(default=0.0, description="Current CPU %")
    memory_delta_mb: float = Field(default=0.0, description="Memory used since start")
    estimated_time_remaining_ms: Optional[float] = Field(default=None, description="ETA")


class BackgroundTaskCompleteReceipt(BaseReceipt):
    """
    Emitted when a background task finishes successfully.

    Records the result, duration, impact on cognition (ΔC).
    """
    receipt_type: str = Field(default="BackgroundTaskCompleteReceipt", alias="type")
    domain: str = Field(default="organism")

    task_id: str = Field(description="Task that completed")
    success: bool = Field(description="Whether task succeeded")
    duration_ms: float = Field(description="Total execution time")
    items_processed: Optional[int] = Field(default=None, description="Items processed")
    result_summary: str = Field(default="", description="JSON summary of results")
    result_size_kb: float = Field(default=0.0, description="Output data size")
    chi_curve_impact: float = Field(default=0.0, ge=0.0, le=1.0, description="ΔC unlocked")
    dignity_score: float = Field(default=1.0, ge=0.0, le=1.0, description="Final dignity score")
    attempt: int = Field(default=1, description="Which attempt succeeded")
    memory_peak_mb: float = Field(default=0.0, description="Peak memory used")
    cpu_peak_percent: float = Field(default=0.0, description="Peak CPU used")


class BackgroundTaskErrorReceipt(BaseReceipt):
    """
    Emitted when a background task fails.

    Records the error, attempts, and whether we're retrying.
    """
    receipt_type: str = Field(default="BackgroundTaskErrorReceipt", alias="type")
    domain: str = Field(default="organism")

    task_id: str = Field(description="Task that failed")
    error: str = Field(description="Human-readable error message")
    error_type: str = Field(description="timeout, guardian_denied, internal_error, etc")
    traceback: Optional[str] = Field(default=None, description="Full traceback")
    attempt: int = Field(description="Which attempt failed")
    max_retries: int = Field(description="How many retries allowed")
    will_retry: bool = Field(default=False, description="Are we trying again?")
    retry_delay_ms: Optional[float] = Field(default=None, description="Delay before retry")


class AttentionAllocationReceipt(BaseReceipt):
    """
    Emitted when the organism shifts attention between goals.

    Records which goal the organism is now focusing on, why,
    and how long it focused on the previous goal.
    """
    receipt_type: str = Field(default="AttentionAllocationReceipt", alias="type")
    domain: str = Field(default="organism")

    from_goal_id: Optional[str] = Field(default=None, description="Previous foreground goal")
    to_goal_id: str = Field(description="New foreground goal")
    reason: str = Field(description="Why attention shifted: critical_result, timeout, user_request, budget_limited")
    attention_duration_ms: Optional[float] = Field(default=None, description="Time spent on previous goal")
    foreground_priority: str = Field(default="normal", description="Priority of new foreground")
    background_tasks_running: int = Field(default=0, description="Active background tasks")
    background_slots_remaining: int = Field(default=4, description="Available background slots")
    throttle_level: str = Field(default="NONE", description="Current throttle level")
    available_cpu_percent: float = Field(default=100.0, description="Available CPU")


# ─────────────────────────────────────────────────────────────────────
# Factory Functions (for easy creation)
# ─────────────────────────────────────────────────────────────────────

def create_background_task_spawned(
    task_id: str,
    parent_goal_id: str,
    task_type: str,
    description: str,
    priority: str = "normal",
    auto_retry: bool = True,
    max_retries: int = 3,
    estimated_duration_ms: Optional[float] = None,
    **kwargs,
) -> BackgroundTaskSpawnedReceipt:
    """Create a task spawned receipt."""
    return BackgroundTaskSpawnedReceipt(
        receipt_id=f"bg_spawned_{task_id}",
        task_id=task_id,
        parent_goal_id=parent_goal_id,
        task_type=task_type,
        description=description,
        priority=priority,
        auto_retry=auto_retry,
        max_retries=max_retries,
        estimated_duration_ms=estimated_duration_ms,
        **kwargs,
    )


def create_background_task_progress(
    task_id: str,
    progress_percent: int,
    status: str,
    current_step: str,
    cpu_usage_percent: float = 0.0,
    memory_delta_mb: float = 0.0,
    items_processed: Optional[int] = None,
    items_remaining: Optional[int] = None,
    estimated_time_remaining_ms: Optional[float] = None,
    **kwargs,
) -> BackgroundTaskProgressReceipt:
    """Create a task progress receipt."""
    return BackgroundTaskProgressReceipt(
        receipt_id=f"bg_progress_{task_id}_{progress_percent}",
        task_id=task_id,
        progress_percent=progress_percent,
        status=status,
        current_step=current_step,
        items_processed=items_processed,
        items_remaining=items_remaining,
        cpu_usage_percent=cpu_usage_percent,
        memory_delta_mb=memory_delta_mb,
        estimated_time_remaining_ms=estimated_time_remaining_ms,
        **kwargs,
    )


def create_background_task_complete(
    task_id: str,
    duration_ms: float,
    result_summary: str = "",
    result_size_kb: float = 0.0,
    chi_curve_impact: float = 0.0,
    dignity_score: float = 1.0,
    attempt: int = 1,
    items_processed: Optional[int] = None,
    memory_peak_mb: float = 0.0,
    cpu_peak_percent: float = 0.0,
    success: bool = True,
    **kwargs,
) -> BackgroundTaskCompleteReceipt:
    """Create a task complete receipt."""
    return BackgroundTaskCompleteReceipt(
        receipt_id=f"bg_complete_{task_id}",
        task_id=task_id,
        success=success,
        duration_ms=duration_ms,
        items_processed=items_processed,
        result_summary=result_summary,
        result_size_kb=result_size_kb,
        chi_curve_impact=chi_curve_impact,
        dignity_score=dignity_score,
        attempt=attempt,
        memory_peak_mb=memory_peak_mb,
        cpu_peak_percent=cpu_peak_percent,
        **kwargs,
    )


def create_background_task_error(
    task_id: str,
    error: str,
    error_type: str,
    attempt: int,
    max_retries: int,
    will_retry: bool = False,
    traceback: Optional[str] = None,
    retry_delay_ms: Optional[float] = None,
    **kwargs,
) -> BackgroundTaskErrorReceipt:
    """Create a task error receipt."""
    return BackgroundTaskErrorReceipt(
        receipt_id=f"bg_error_{task_id}_{attempt}",
        task_id=task_id,
        error=error,
        error_type=error_type,
        traceback=traceback,
        attempt=attempt,
        max_retries=max_retries,
        will_retry=will_retry,
        retry_delay_ms=retry_delay_ms,
        **kwargs,
    )


def create_attention_shifted(
    from_goal_id: Optional[str],
    to_goal_id: str,
    reason: str,
    foreground_priority: str = "normal",
    background_tasks_running: int = 0,
    background_slots_remaining: int = 4,
    throttle_level: str = "NONE",
    available_cpu_percent: float = 100.0,
    attention_duration_ms: Optional[float] = None,
    **kwargs,
) -> AttentionAllocationReceipt:
    """Create an attention shifted receipt."""
    return AttentionAllocationReceipt(
        receipt_id=f"attention_shift_{to_goal_id}",
        from_goal_id=from_goal_id,
        to_goal_id=to_goal_id,
        reason=reason,
        attention_duration_ms=attention_duration_ms,
        foreground_priority=foreground_priority,
        background_tasks_running=background_tasks_running,
        background_slots_remaining=background_slots_remaining,
        throttle_level=throttle_level,
        available_cpu_percent=available_cpu_percent,
        **kwargs,
    )


# ─────────────────────────────────────────────────────────────────────
# Exports
# ─────────────────────────────────────────────────────────────────────

__all__ = [
    "BackgroundTaskSpawnedReceipt",
    "BackgroundTaskProgressReceipt",
    "BackgroundTaskCompleteReceipt",
    "BackgroundTaskErrorReceipt",
    "AttentionAllocationReceipt",
    "create_background_task_spawned",
    "create_background_task_progress",
    "create_background_task_complete",
    "create_background_task_error",
    "create_attention_shifted",
]
