"""Plan domain model for CleverAgents.

Based on Phase 0 discovery and ADR-004 (Pydantic Validation).
"""

from datetime import datetime
from enum import StrEnum

from pydantic import BaseModel, ConfigDict, Field, field_validator


class PlanStatus(StrEnum):
    """Status of a plan."""

    PENDING = "pending"
    BUILDING = "building"
    BUILT = "built"
    APPLIED = "applied"
    ERROR = "error"
    CANCELLED = "cancelled"


class PlanBuild(BaseModel):
    """Information about a plan build."""

    id: int | None = Field(None)
    plan_id: int = Field(...)
    started_at: datetime = Field(default_factory=datetime.now)
    completed_at: datetime | None = Field(None)
    model_used: str = Field(...)
    token_count: int = Field(0, ge=0)
    error_message: str | None = Field(None)

    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
    )


class PlanResult(BaseModel):
    """Result of executing a plan."""

    success: bool = Field(...)
    files_created: int = Field(0, ge=0)
    files_modified: int = Field(0, ge=0)
    files_deleted: int = Field(0, ge=0)
    error_message: str | None = Field(None)
    applied_at: datetime = Field(default_factory=datetime.now)

    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
    )


class Plan(BaseModel):
    """Domain model for a plan.

    A plan represents a set of changes to be made based on user instructions.
    """

    id: int | None = Field(None, description="Plan ID")
    project_id: int = Field(..., gt=0)
    name: str = Field(..., min_length=1, max_length=255)
    prompt: str = Field(..., min_length=1, description="User instructions")
    status: PlanStatus = Field(PlanStatus.PENDING)
    current: bool = Field(False, description="Is this the current plan")
    created_at: datetime = Field(default_factory=datetime.now)
    updated_at: datetime = Field(default_factory=datetime.now)

    # Build information
    build: PlanBuild | None = Field(None)

    # Backward compatibility attributes from build
    build_started_at: datetime | None = Field(None)
    build_completed_at: datetime | None = Field(None)
    model_used: str | None = Field(None)
    token_count: int | None = Field(None)

    # Application result
    result: PlanResult | None = Field(None)

    # Backward compatibility attributes from result
    applied_at: datetime | None = Field(None)
    files_created: int | None = Field(None)
    files_modified: int | None = Field(None)
    files_deleted: int | None = Field(None)

    @field_validator("name")
    @classmethod
    def validate_name(cls: type["Plan"], v: str) -> str:
        """Validate plan name."""
        if not v.replace("-", "").replace("_", "").replace(" ", "").isalnum():
            raise ValueError(
                "Name must be alphanumeric with hyphens, underscores, or spaces"
            )
        return v

    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
        use_enum_values=True,
    )
