from __future__ import annotations

from typing import Any

from pydantic import Field

from app.models.common import StrictModel


class TurnMessage(StrictModel):
    role: str
    content: str


class SkillPayload(StrictModel):
    name: str
    path: str
    allowed_tools: list[str] = Field(default_factory=list)
    content: str


class AgentPayload(StrictModel):
    name: str
    path: str
    model: str | None = None
    allowed_tools: list[str] = Field(default_factory=list)
    content: str


class InstructionPayload(StrictModel):
    name: str
    path: str
    apply_to: list[str] = Field(default_factory=list)
    content: str


class RepoRulePayload(StrictModel):
    path: str
    kind: str | None = None
    content: str


class CustomizationsPayload(StrictModel):
    skill: SkillPayload | None = None
    agent: AgentPayload | None = None
    instructions: list[InstructionPayload] = Field(default_factory=list)
    repo_rules: list[RepoRulePayload] = Field(default_factory=list)


class ToolCallIntent(StrictModel):
    tool_call_id: str
    tool_name: str
    arguments: dict[str, Any] = Field(default_factory=dict)
    reason: str = ""
    risk_level: str = "low"
    requires_permission: bool = False


class AgentTurnRequest(StrictModel):
    task_id: str
    messages: list[TurnMessage] = Field(default_factory=list)
    local_context_summary: dict[str, str] = Field(default_factory=dict)
    tool_observations: list[dict[str, Any]] = Field(default_factory=list)
    retrieval_context: dict[str, Any] = Field(default_factory=dict)
    budget: dict[str, Any] = Field(default_factory=dict)
    customizations: CustomizationsPayload | None = None


class AgentTurnResponse(StrictModel):
    text_deltas: list[str] = Field(default_factory=list)
    tool_intents: list[ToolCallIntent] = Field(default_factory=list)
    done: bool = False
    finish_reason: str = ""
    summary: str = ""
