import uuid

from sqlalchemy import ForeignKey, Integer, String, Text
from sqlalchemy.dialects.postgresql import ENUM as PGEnum
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column

from app.models.base import Base, TenantScopedMixin, TimestampMixin, UUIDPKMixin

workspace_status = PGEnum("provisioning", "active", "failed", name="workspace_status", create_type=False)


class Workspace(UUIDPKMixin, TenantScopedMixin, TimestampMixin, Base):
    """A tenant-owned, dynamically provisioned Postgres database — NOT the
    App Management export/import bundle (app/models/app_bundle.py); see
    that model's own docstring for the unrelated, pre-existing meaning of
    "App" this deliberately avoids colliding with. Creating one runs
    app/core/db_provisioning.py::provision_workspace_database, which applies
    the same db/schema.sql to a brand-new database. db_password_encrypted is
    Fernet ciphertext (app/core/crypto.py) — the plaintext is never stored
    and never returned by the API (see schemas/workspace.py::WorkspaceRead)."""

    __tablename__ = "workspaces"

    name: Mapped[str] = mapped_column(String(200), nullable=False)
    db_host: Mapped[str] = mapped_column(String(255), nullable=False)
    db_port: Mapped[int] = mapped_column(Integer, nullable=False, server_default="5432")
    db_name: Mapped[str] = mapped_column(String(63), nullable=False)
    db_username: Mapped[str] = mapped_column(String(63), nullable=False)
    db_password_encrypted: Mapped[str] = mapped_column(Text, nullable=False)
    status: Mapped[str] = mapped_column(workspace_status, nullable=False, server_default="provisioning")
    status_detail: Mapped[str | None] = mapped_column(Text)
    created_by: Mapped[uuid.UUID | None] = mapped_column(PGUUID(as_uuid=True), ForeignKey("users.id"))
