"""ComfyUI workflow templates an administrator saved.

A table rather than a list inside the settings group, for the reason
`McpServer.tools_json` is *not* a table: that one is a cache of somebody else's
document, replaced wholesale on every refresh, where each entry carries one
decision. These are the opposite -- authored by hand, individually named,
edited, reordered and deleted, and referenced by id from a chat. Everything a
table gives for free is exactly what is wanted.

Deliberately **no group access list**, unlike `CustomTool`. The whole feature is
already behind one capability flag and one permission; a second access system
covering which templates a person may pick would be a screen of checkboxes
nobody asked for, and the thing being restricted is the shape of a picture.
"""

from __future__ import annotations

from datetime import datetime
from typing import Any

from sqlalchemy import Boolean, DateTime, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column

from lembas.db.base import Base, Timestamps, UUIDPrimaryKey
from lembas.db.types import JSONDict


class ImageWorkflow(UUIDPrimaryKey, Timestamps, Base):
    """One API-format ComfyUI workflow, with holes where the values go."""

    __tablename__ = "image_workflows"

    # What the *model* names when it picks this one, so it is short and
    # lowercase for the same reason a tool's slug is: it lands in a schema enum
    # and is generated by something that spells inconsistently.
    slug: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
    name: Mapped[str] = mapped_column(String(120), nullable=False)

    # Sent to the model beside the slug, and the only thing it has to choose
    # with. "Photographic, SDXL, slow" is a choice; "workflow 2" is not.
    description: Mapped[str] = mapped_column(Text, default="")

    # The workflow itself, in ComfyUI's API format, with `{{placeholders}}`
    # where the parameters go. Stored parsed rather than as text so the admin
    # form can only ever save something that is valid JSON -- a template that
    # does not parse would fail at generation time, minutes later, in front of
    # somebody who was not editing it.
    workflow_json: Mapped[dict[str, Any]] = mapped_column(JSONDict, default=dict)

    enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
    position: Mapped[int] = mapped_column(Integer, default=0, nullable=False)

    # The result of the last time somebody pressed Test, in the shape
    # `CustomTool` and `McpServer` already use, so the row reads the same way in
    # the list as theirs do.
    last_checked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    last_error: Mapped[str] = mapped_column(Text, default="")

    def __repr__(self) -> str:
        return f"<ImageWorkflow {self.slug}>"
