import uuid
from datetime import datetime

from sqlalchemy import Boolean, ForeignKey, Integer, String, Text, text
from sqlalchemy.dialects.postgresql import JSONB, TIMESTAMP, UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column

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


class RecordAccessPolicy(UUIDPKMixin, TenantScopedMixin, TimestampMixin, Base):
    """Which records of one Master or Form each role may see, edit and delete
    — see app/crud/access_policy.py and db/schema.sql."""

    __tablename__ = "record_access_policies"

    source_type: Mapped[str] = mapped_column(String(10), nullable=False)
    source_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), nullable=False)
    enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="false")
    rules: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="[]")
    updated_by: Mapped[uuid.UUID | None] = mapped_column(PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"))


class PageVersion(UUIDPKMixin, TenantScopedMixin, Base):
    """One publish of a Page — the snapshot visitors see (Page.published_version)."""

    __tablename__ = "page_versions"

    page_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("pages.id", ondelete="CASCADE"), nullable=False)
    version: Mapped[int] = mapped_column(Integer, nullable=False)
    name: Mapped[str] = mapped_column(String(200), nullable=False)
    blocks: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="[]")
    parameters: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="[]")
    events: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="[]")
    variables: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="[]")
    canvas_width: Mapped[int] = mapped_column(Integer, nullable=False, server_default="1200")
    fit_mode: Mapped[str] = mapped_column(String(10), nullable=False, server_default="scale")
    content_mode: Mapped[str] = mapped_column(String(10), nullable=False, server_default="blocks")
    html_document: Mapped[str | None] = mapped_column(Text)
    seo: Mapped[dict] = mapped_column(JSONB, nullable=False, server_default="{}")
    note: Mapped[str | None] = mapped_column(String(500))
    published_by: Mapped[uuid.UUID | None] = mapped_column(PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"))
    published_at: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), server_default=text("now()"))
