import uuid
from datetime import datetime
from typing import Literal

from pydantic import BaseModel, ConfigDict

AiTargetType = Literal["master", "form", "task_custom_code", "page"]


class AuditLogEntryRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    tenant_id: uuid.UUID
    actor_id: uuid.UUID | None
    action: str
    entity_type: str | None
    entity_id: uuid.UUID | None
    details: dict | None
    occurred_at: datetime


class AiChatMessage(BaseModel):
    role: Literal["user", "assistant"]
    content: str
    at: datetime | None = None


class AiAssistantSessionCreate(BaseModel):
    target_type: AiTargetType
    target_id: uuid.UUID | None = None


class AiAssistantSessionRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    tenant_id: uuid.UUID
    user_id: uuid.UUID
    target_type: AiTargetType
    target_id: uuid.UUID | None
    prompts: list[dict]
    resulting_schema: dict | None
    model_name: str
    created_at: datetime
    updated_at: datetime


class AiAssistantMessageCreate(BaseModel):
    message: str
    # task_custom_code sessions only — which of the Custom Node's two
    # runtimes to generate for (see app/crud/tasks.py's _run_custom_code_sync).
    # Sent per-message rather than stored on the session since a user can
    # switch the node's language after the session was already started.
    language: Literal["python", "node"] | None = None
    # "page" sessions only — an UploadedFile id (see app/routers/uploads.py)
    # for a screenshot to translate into PageBlockDef[]. Only meaningful on
    # the first message of a session; a later refinement turn should omit it
    # and just send more text against the same session's prompt history.
    image_file_id: uuid.UUID | None = None


class AiAssistantMessageResult(BaseModel):
    session: AiAssistantSessionRead
    reply: str
    ollama_error: str | None = None
