"""Conversation domain models for CleverAgents.

Based on Phase 0 discovery stubs from data_models.py.
These models represent the conversation state and history for plans.
"""

from __future__ import annotations

from datetime import datetime
from enum import Enum, StrEnum

from pydantic import BaseModel, ConfigDict, Field


def _empty_string_list() -> list[str]:
    return []


def _empty_subtask_list() -> list[Subtask]:
    return []


def _default_convo_message_flags() -> ConvoMessageFlags:
    return ConvoMessageFlags(
        didMakePlan=False,
        didRemoveTasks=False,
        didMakeDebuggingPlan=False,
        didLoadContext=False,
        currentStage=None,
        isChat=False,
        didWriteCode=False,
        didCompleteTask=False,
        didCompletePlan=False,
        hasUnfinishedSubtasks=False,
        isApplyDebug=False,
        isUserDebug=False,
        hasError=False,
    )


__all__ = [
    "ConvoMessage",
    "ConvoMessageFlags",
    "ConvoSummary",
    "CurrentStage",
    "PlanningPhase",
    "Subtask",
    "TellStage",
]


class TellStage(StrEnum):
    """Stage of the tell operation."""

    PLANNING = "planning"
    IMPLEMENTATION = "implementation"


class PlanningPhase(StrEnum):
    """Phase of the planning stage."""

    CONTEXT = "context"
    TASKS = "tasks"


class CurrentStage(BaseModel):
    """Current stage of plan execution."""

    tell_stage: TellStage = Field(TellStage.PLANNING, alias="tellStage")
    planning_phase: PlanningPhase = Field(PlanningPhase.CONTEXT, alias="planningPhase")

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


class ConvoMessageFlags(BaseModel):
    """Flags indicating what happened during a conversation message."""

    did_make_plan: bool = Field(False, alias="didMakePlan")
    did_remove_tasks: bool = Field(False, alias="didRemoveTasks")
    did_make_debugging_plan: bool = Field(False, alias="didMakeDebuggingPlan")
    did_load_context: bool = Field(False, alias="didLoadContext")
    current_stage: CurrentStage | None = Field(default=None, alias="currentStage")
    is_chat: bool = Field(False, alias="isChat")
    did_write_code: bool = Field(False, alias="didWriteCode")
    did_complete_task: bool = Field(False, alias="didCompleteTask")
    did_complete_plan: bool = Field(False, alias="didCompletePlan")
    has_unfinished_subtasks: bool = Field(False, alias="hasUnfinishedSubtasks")
    is_apply_debug: bool = Field(False, alias="isApplyDebug")
    is_user_debug: bool = Field(False, alias="isUserDebug")
    has_error: bool = Field(False, alias="hasError")

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


class Subtask(BaseModel):
    """A subtask within a plan."""

    title: str = Field(...)
    description: str = Field(...)
    uses_files: list[str] = Field(default_factory=_empty_string_list, alias="usesFiles")
    is_finished: bool = Field(False, alias="isFinished")

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


class ConvoMessage(BaseModel):
    """A single message in a conversation."""

    id: str = Field(...)
    user_id: str = Field(..., alias="userId")
    role: str = Field(...)
    tokens: int = Field(0, ge=0)
    num: int = Field(0, ge=0)
    message: str = Field(...)
    stopped: bool = Field(False)
    flags: ConvoMessageFlags = Field(default_factory=_default_convo_message_flags)
    subtask: Subtask | None = Field(None)
    added_subtasks: list[Subtask] = Field(
        default_factory=_empty_subtask_list, alias="addedSubtasks"
    )
    removed_subtasks: list[str] = Field(
        default_factory=_empty_string_list, alias="removedSubtasks"
    )
    active_context_ids: list[str] = Field(
        default_factory=_empty_string_list, alias="activeContextIds"
    )
    created_at: datetime = Field(default_factory=datetime.now, alias="createdAt")

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


class ConvoSummary(BaseModel):
    """Summary of a conversation."""

    id: str = Field(...)
    latest_convo_message_created_at: datetime = Field(
        ..., alias="latestConvoMessageCreatedAt"
    )
    latest_convo_message_id: str = Field(..., alias="latestConvoMessageId")
    summary: str = Field(...)
    tokens: int = Field(0, ge=0)
    num_messages: int = Field(0, ge=0, alias="numMessages")
    created_at: datetime = Field(default_factory=datetime.now, alias="createdAt")

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