"""API models for OlmoEarth configuration management."""

from datetime import datetime
from enum import StrEnum
from typing import Any
from uuid import UUID

from pydantic import BaseModel, Field

from olmoearth_shared.api.common.search_filters import (
    DatetimeFilter,
    KeywordFilter,
    NumericFilter,
    SortDirection,
)
from olmoearth_shared.api.run.model_pipelines import ModelStageResponse
from olmoearth_shared.api.run.workflow import WorkflowResponse
from olmoearth_shared.models.olmoearth_config.olmoearth_config import OlmoEarthConfig


class OlmoEarthConfigSortField(StrEnum):
    """Fields that can be used for sorting OlmoEarthConfig search results."""

    CREATED_AT = "created_at"
    UPDATED_AT = "updated_at"
    VERSION = "version"  # Compound sort: (major, minor, micro)


class SearchOlmoEarthConfigsRequest(BaseModel):
    """Request model for searching OlmoEarth configurations."""

    # Filters
    id: KeywordFilter[UUID] | None = None
    version_major: NumericFilter | None = None
    version_minor: NumericFilter | None = None
    version_micro: NumericFilter | None = None
    created_at: DatetimeFilter | None = None
    updated_at: DatetimeFilter | None = None

    # Include related entities
    include_workflows: bool = Field(default=False, description="Include associated workflows")
    include_model_stages: bool = Field(
        default=False, description="Include associated model stages"
    )

    # Pagination
    limit: int = Field(default=50, ge=1, le=1000)
    offset: int = Field(default=0, ge=0)

    # Sorting
    sort_by: OlmoEarthConfigSortField = OlmoEarthConfigSortField.CREATED_AT
    sort_direction: SortDirection = SortDirection.DESC


class RawOlmoEarthConfigResponse(BaseModel):
    """Response model for raw (stored) OlmoEarth configuration.

    Returns the raw config dict as stored in the database, not the validated
    Pydantic model. This allows viewing configs that may not pass current schema
    validation.
    """

    id: UUID
    config: dict[str, Any]
    version: str  # Reconstituted version string (e.g., "0.0.1")
    version_major: int
    version_minor: int
    version_micro: int
    created_at: datetime
    updated_at: datetime
    validation_errors: str | None = Field(
        default=None,
        description="Pydantic validation errors if the config fails to deserialize, None if valid",
    )

    # Optional related entities (full models, following existing patterns)
    workflows: list[WorkflowResponse] | None = None
    model_stages: list[ModelStageResponse] | None = None


class OlmoEarthConfigResponse(BaseModel):
    """Response model for a validated OlmoEarth configuration update."""

    id: UUID
    config: OlmoEarthConfig
    version: str
    version_major: int
    version_minor: int
    version_micro: int
    created_at: datetime
    updated_at: datetime


class OlmoEarthConfigUpdate(BaseModel):
    """Request model for updating an OlmoEarth configuration."""

    config: OlmoEarthConfig = Field(description="The new configuration to store")
    update_incomplete_workflow_scratch_dirs: bool = Field(
        default=False,
        description="If true, update olmoearth_config.yaml in scratch dirs of incomplete workflows (pending, running, or failed)",
    )


class ScratchDirUpdateResult(BaseModel):
    """Result of updating a single workflow's scratch directory."""

    workflow_id: UUID
    success: bool
    error: str | None = None
