"""Execution data models for creation generation tracking."""

from enum import Enum
from typing import Any

from pydantic import BaseModel, Field


class ExecutionStatus(str, Enum):
    """Execution status enumeration.

    Attributes
    ----------
    PENDING : str
        Execution created but not yet started
    RUNNING : str
        Execution currently in progress
    COMPLETED : str
        Execution finished successfully
    FAILED : str
        Execution failed with error
    """

    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"


class ExecutionResult(BaseModel):
    """Result data from a completed execution.

    Attributes
    ----------
    title : str
        Generated creation title
    creation_id : str
        Unique identifier of the created content
    file_path : str
        Path to the generated file
    """

    title: str = Field(..., description="Generated creation title")
    creation_id: str = Field(..., description="Unique identifier of the created content")
    file_path: str = Field(..., description="Path to the generated file")


class ExecutionData(BaseModel):
    """Complete execution tracking data.

    This model represents the full state of a creation generation execution,
    including metadata, status, timestamps, and results.

    Attributes
    ----------
    execution_id : str
        Unique identifier for this execution
    query : str
        Creation query string that triggered this execution
    status : ExecutionStatus
        Current status of the execution
    created_at : str
        ISO 8601 timestamp when execution was created
    started_at : str | None
        ISO 8601 timestamp when execution started running (None if not started)
    completed_at : str | None
        ISO 8601 timestamp when execution completed (None if not completed)
    failed_at : str | None
        ISO 8601 timestamp when execution failed (None if not failed)
    result : ExecutionResult | None
        Execution result data (only present when status is COMPLETED)
    error : str | None
        Error message (only present when status is FAILED)

    Examples
    --------
    >>> # Pending execution
    >>> exec_data = ExecutionData(
    ...     execution_id="exec_001",
    ...     query="domain/creation?subject=X",
    ...     status=ExecutionStatus.PENDING,
    ...     created_at=datetime.now().isoformat()
    ... )

    >>> # Completed execution
    >>> exec_data = ExecutionData(
    ...     execution_id="exec_001",
    ...     query="domain/creation?subject=X",
    ...     status=ExecutionStatus.COMPLETED,
    ...     created_at="2026-01-21T10:00:00",
    ...     started_at="2026-01-21T10:00:05",
    ...     completed_at="2026-01-21T10:05:30",
    ...     result=ExecutionResult(
    ...         title="Report Title",
    ...         creation_id="creation_123",
    ...         file_path="/path/to/file.mdx"
    ...     )
    ... )
    """

    execution_id: str = Field(..., description="Unique identifier for this execution")
    query: str = Field(..., description="Creation query string")
    status: ExecutionStatus = Field(..., description="Current execution status")
    created_at: str = Field(..., description="ISO 8601 timestamp when execution was created")
    started_at: str | None = Field(
        default=None, description="ISO 8601 timestamp when execution started"
    )
    completed_at: str | None = Field(
        default=None, description="ISO 8601 timestamp when execution completed"
    )
    failed_at: str | None = Field(
        default=None, description="ISO 8601 timestamp when execution failed"
    )
    result: ExecutionResult | None = Field(
        default=None, description="Execution result (when completed)"
    )
    error: str | None = Field(default=None, description="Error message (when failed)")

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary representation.

        Returns
        -------
        dict[str, Any]
            Dictionary representation with all fields
        """
        return self.model_dump(exclude_none=False)
