"""Pydantic models for ccontext data structures."""

from datetime import datetime, timezone
from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field


class TaskStatus(str, Enum):
    """Task status values."""
    PLANNED = "planned"
    ACTIVE = "active"
    DONE = "done"


class StepStatus(str, Enum):
    """Step status values."""
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    DONE = "done"


class EntryType(str, Enum):
    """Entry type values."""
    NOTE = "note"
    REFERENCE = "reference"


class Step(BaseModel):
    """A step within a task."""
    id: str = Field(..., description="Step ID (S1, S2...)")
    name: str = Field(..., description="Step name")
    done: str = Field(..., description="Completion criteria")
    status: StepStatus = Field(default=StepStatus.PENDING, description="Step status")


class Task(BaseModel):
    """A task with steps."""
    id: str = Field(..., description="Task ID (T001, T002...)")
    name: str = Field(..., description="Task name")
    goal: str = Field(..., description="Completion criteria")
    status: TaskStatus = Field(default=TaskStatus.PLANNED, description="Task status")
    assignee: Optional[str] = Field(default=None, description="Agent ID")
    created_at: str = Field(
        default_factory=lambda: datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
        description="Creation timestamp (ISO format)"
    )
    steps: list[Step] = Field(default_factory=list, description="Task steps (2-8)")

    @property
    def current_step(self) -> Optional[Step]:
        """Get the first non-done step."""
        for step in self.steps:
            if step.status != StepStatus.DONE:
                return step
        return None

    @property
    def progress(self) -> float:
        """Calculate progress as done steps / total steps."""
        if not self.steps:
            return 0.0
        done_count = sum(1 for s in self.steps if s.status == StepStatus.DONE)
        return done_count / len(self.steps)


class Note(BaseModel):
    """A note entry (lesson, concern, discovery, etc.)."""
    id: str = Field(..., description="Note ID (N001, N002...)")
    score: int = Field(default=15, ge=-100, le=100, description="Score (10-100 initial, decays by 1 per get_context)")
    content: str = Field(..., description="Note content (natural language)")

    @property
    def expiring(self) -> bool:
        """Check if the note is expiring (score <= 0)."""
        return self.score <= 0


class Reference(BaseModel):
    """A reference entry (useful file/location)."""
    id: str = Field(..., description="Reference ID (R001, R002...)")
    score: int = Field(default=15, ge=-100, le=100, description="Score (10-100 initial, decays by 1 per get_context)")
    uri: str = Field(..., description="File path or URI (e.g., src/file.py:10-20)")
    note: str = Field(..., description="Description of why this is useful")

    @property
    def expiring(self) -> bool:
        """Check if the reference is expiring (score <= 0)."""
        return self.score <= 0


class Context(BaseModel):
    """The main context structure stored in context.yaml."""
    version: str = Field(default="1", description="Schema version")
    goal: Optional[str] = Field(default=None, description="Current execution goal")
    why: Optional[str] = Field(default=None, description="Decision rationale")
    agents: dict[str, str] = Field(default_factory=dict, description="Agent statuses (natural language)")
    notes: list[Note] = Field(default_factory=list, description="Notes (lessons, concerns, discoveries)")
    references: list[Reference] = Field(default_factory=list, description="References (useful files/locations)")


class TasksSummary(BaseModel):
    """Summary of tasks for get_context response."""
    total: int = Field(default=0, description="Total number of tasks")
    done: int = Field(default=0, description="Number of done tasks")
    active: int = Field(default=0, description="Number of active tasks")
    planned: int = Field(default=0, description="Number of planned tasks")


class ContextResponse(BaseModel):
    """Response structure for get_context tool."""
    goal: Optional[str] = None
    why: Optional[str] = None
    agents: dict[str, str] = Field(default_factory=dict)
    notes: list[dict] = Field(default_factory=list)
    references: list[dict] = Field(default_factory=list)
    tasks_summary: TasksSummary = Field(default_factory=TasksSummary)
    active_task: Optional[Task] = None


class StepInput(BaseModel):
    """Input for creating a step."""
    name: str
    done: str


class StepUpdate(BaseModel):
    """Input for updating a step (with optional fields)."""
    id: str
    name: Optional[str] = None
    done: Optional[str] = None
    status: Optional[StepStatus] = None
