"""Pydantic models for database entities."""

from __future__ import annotations

import time
import uuid
from enum import StrEnum
from typing import Any

from pydantic import BaseModel, Field


class TaskStatus(StrEnum):
    PENDING = "pending"
    PLANNING = "planning"
    EXECUTING = "executing"
    AWAITING_APPROVAL = "awaiting_approval"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


class AutonomyLevel(StrEnum):
    FULL = "full"
    SEMI = "semi"
    STEP_BY_STEP = "step_by_step"


class Task(BaseModel):
    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    description: str
    status: TaskStatus = TaskStatus.PENDING
    autonomy: AutonomyLevel = AutonomyLevel.FULL
    priority: int = 0
    budget_limit: float | None = None
    cost_spent: float = 0.0
    result: dict[str, Any] | None = None
    error: str | None = None
    parent_task_id: str | None = None
    created_at: float = Field(default_factory=time.time)
    updated_at: float = Field(default_factory=time.time)


class TaskStep(BaseModel):
    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    task_id: str
    step_number: int
    thought: str = ""
    action_type: str = ""  # tool_call, ask_user, finish
    action_data: dict[str, Any] = Field(default_factory=dict)
    observation: str = ""
    created_at: float = Field(default_factory=time.time)


class ToolCall(BaseModel):
    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    task_id: str
    step_id: str
    tool_name: str
    tool_input: dict[str, Any] = Field(default_factory=dict)
    tool_output: str = ""
    success: bool = True
    duration_ms: float = 0.0
    created_at: float = Field(default_factory=time.time)


class Memory(BaseModel):
    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    content: str
    memory_type: str  # preference, strategy, source, fact
    tags: list[str] = Field(default_factory=list)
    relevance_score: float = 1.0
    access_count: int = 0
    last_accessed: float = Field(default_factory=time.time)
    created_at: float = Field(default_factory=time.time)


class TraceEntry(BaseModel):
    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    task_id: str | None = None
    event_type: str
    data: dict[str, Any] = Field(default_factory=dict)
    parent_id: str | None = None
    timestamp: float = Field(default_factory=time.time)


class PriceSnapshot(BaseModel):
    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    item_name: str
    source: str
    price: float
    currency: str = "USD"
    url: str = ""
    metadata: dict[str, Any] = Field(default_factory=dict)
    captured_at: float = Field(default_factory=time.time)
