"""Add qr_codes table

Revision ID: 0013
Revises: 0012
Create Date: 2026-06-25 00:00:00.000000

Changes:
  1. CREATE qr_codes — tenant-scoped QR code registry for entrances,
     sections, plots, and contracts.
  2. Unique constraint: (tenant_id, qr_type, reference_id).
  3. Index on tenant_id.
  4. Row Level Security policy for tenant isolation.
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

revision: str = "0014"
down_revision: Union[str, None] = "0013"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


# ---------------------------------------------------------------------------
# upgrade
# ---------------------------------------------------------------------------


def upgrade() -> None:

    # ── 1. Create qr_codes table ──────────────────────────────────────────────

    op.create_table(
        "qr_codes",
        sa.Column(
            "id",
            postgresql.UUID(as_uuid=True),
            primary_key=True,
            server_default=sa.text("gen_random_uuid()"),
            nullable=False,
        ),
        sa.Column(
            "tenant_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("accounts.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("qr_type", sa.String(50), nullable=False),
        sa.Column("reference_id", sa.String(255), nullable=False),
        sa.Column("display_label", sa.String(255), nullable=True),
        sa.Column("content_url", sa.Text(), nullable=False),
        sa.Column("svg_s3_key", sa.Text(), nullable=True),
        sa.Column("pdf_s3_key", sa.Text(), nullable=True),
        sa.Column(
            "is_active",
            sa.Boolean(),
            nullable=False,
            server_default=sa.text("true"),
        ),
        sa.Column("generated_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("NOW()"),
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("NOW()"),
        ),
        sa.UniqueConstraint(
            "tenant_id",
            "qr_type",
            "reference_id",
            name="uq_qr_codes_tenant_type_ref",
        ),
    )

    # ── 2. Index ──────────────────────────────────────────────────────────────

    op.create_index(
        "ix_qr_codes_tenant",
        "qr_codes",
        ["tenant_id"],
    )

    # ── 3. Row Level Security ─────────────────────────────────────────────────

    op.execute("ALTER TABLE qr_codes ENABLE ROW LEVEL SECURITY")
    op.execute("ALTER TABLE qr_codes FORCE ROW LEVEL SECURITY")
    op.execute(
        """
        CREATE POLICY tenant_isolation ON qr_codes
            USING (
                tenant_id = NULLIF(current_setting('app.tenant', TRUE), '')::uuid
            )
        """
    )


# ---------------------------------------------------------------------------
# downgrade
# ---------------------------------------------------------------------------


def downgrade() -> None:

    # ── Drop RLS ──────────────────────────────────────────────────────────────

    op.execute("DROP POLICY IF EXISTS tenant_isolation ON qr_codes")
    op.execute("ALTER TABLE qr_codes DISABLE ROW LEVEL SECURITY")

    # ── Drop index ────────────────────────────────────────────────────────────

    op.drop_index("ix_qr_codes_tenant", table_name="qr_codes")

    # ── Drop table (unique constraint dropped automatically) ──────────────────

    op.drop_table("qr_codes")
