from __future__ import annotations

from datetime import datetime, timezone
from enum import Enum

from pydantic import BaseModel, Field


def utc_now() -> datetime:
    return datetime.now(timezone.utc)


class TaskStatus(str, Enum):
    idle = "idle"
    running = "running"
    paused = "paused"
    waiting_approval = "waiting_approval"
    blocked = "blocked"


class TaskNote(BaseModel):
    created_at: datetime = Field(default_factory=utc_now)
    author: str
    text: str
    processed_at: datetime | None = None
    result_summary: str | None = None


class CommandRecord(BaseModel):
    created_at: datetime = Field(default_factory=utc_now)
    command: str
    exit_code: int
    output_preview: str


class ChatEntry(BaseModel):
    created_at: datetime = Field(default_factory=utc_now)
    author: str
    text: str


class DesktopBridgeMessage(BaseModel):
    message_id: str
    created_at: datetime = Field(default_factory=utc_now)
    author: str
    text: str
    status: str = "pending"
    mirrored_to_project: bool = False


class DesktopBridgeState(BaseModel):
    messages: list[DesktopBridgeMessage] = Field(default_factory=list)
    updated_at: datetime = Field(default_factory=utc_now)


class TaskSummary(BaseModel):
    task_id: str
    title: str
    status: TaskStatus
    updated_at: datetime
    pending_items: int = 0
    completed_steps: int = 0


class StoreIndex(BaseModel):
    active_task_id: str = "default"
    tasks: list[TaskSummary] = Field(default_factory=list)


class TaskState(BaseModel):
    task_id: str = "default"
    title: str = "目前沒有任務"
    status: TaskStatus = TaskStatus.idle
    workdir: str | None = None
    agent_enabled: bool = True
    summary: str = "尚未開始任何任務。"
    latest_update: str = "目前閒置。"
    notes: list[TaskNote] = Field(default_factory=list)
    requires_approval: bool = False
    pending_approval_command: str | None = None
    pending_approval_reason: str | None = None
    pending_voice_command: str | None = None
    approved_command: str | None = None
    last_command: str | None = None
    last_command_output: str | None = None
    planner_last_summary: str | None = None
    command_history: list[CommandRecord] = Field(default_factory=list)
    chat_log: list[ChatEntry] = Field(default_factory=list)
    desktop_bridge_last_mirrored_chat_at: datetime | None = None
    completed_steps: int = 0
    updated_at: datetime = Field(default_factory=utc_now)

    def touch(self, update: str | None = None) -> None:
        self.updated_at = utc_now()
        if update:
            self.latest_update = update
