"""loyalty 010 - add terminal_devices table

Pairs Android (or other) POS tablets to a single store. Stores only the
JWT id (`jti`); the token itself is shown once at pairing and never
persisted. Multiple devices per store are allowed.

Revision ID: loyalty_010
Revises: loyalty_009
Create Date: 2026-05-04
"""
import sqlalchemy as sa

from alembic import op

revision = "loyalty_010"
down_revision = "loyalty_009"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.create_table(
        "loyalty_terminal_devices",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column(
            "merchant_id",
            sa.Integer(),
            sa.ForeignKey("merchants.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column(
            "store_id",
            sa.Integer(),
            sa.ForeignKey("stores.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("label", sa.String(length=100), nullable=False),
        sa.Column("jti", sa.String(length=36), nullable=False),
        sa.Column("expires_at", sa.DateTime(timezone=True), nullable=False),
        sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("last_seen_ip", sa.String(length=45), nullable=True),
        sa.Column("revoked_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column(
            "revoked_by_id",
            sa.Integer(),
            sa.ForeignKey("users.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column("revoked_reason", sa.String(length=255), nullable=True),
        sa.Column(
            "created_by_id",
            sa.Integer(),
            sa.ForeignKey("users.id", ondelete="SET NULL"),
            nullable=True,
        ),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("CURRENT_TIMESTAMP"),
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.text("CURRENT_TIMESTAMP"),
        ),
        sa.CheckConstraint(
            "expires_at > created_at",
            name="ck_loyalty_terminal_devices_expiry_after_creation",
        ),
    )

    op.create_index(
        "ix_loyalty_terminal_devices_merchant_id",
        "loyalty_terminal_devices",
        ["merchant_id"],
    )
    op.create_index(
        "ix_loyalty_terminal_devices_store_id",
        "loyalty_terminal_devices",
        ["store_id"],
    )
    op.create_index(
        "ix_loyalty_terminal_devices_revoked_at",
        "loyalty_terminal_devices",
        ["revoked_at"],
    )
    op.create_index(
        "ix_loyalty_terminal_devices_jti",
        "loyalty_terminal_devices",
        ["jti"],
        unique=True,
    )
    op.create_index(
        "idx_loyalty_terminal_devices_store_active",
        "loyalty_terminal_devices",
        ["store_id", "revoked_at"],
    )


def downgrade() -> None:
    op.drop_index(
        "idx_loyalty_terminal_devices_store_active",
        table_name="loyalty_terminal_devices",
    )
    op.drop_index(
        "ix_loyalty_terminal_devices_jti",
        table_name="loyalty_terminal_devices",
    )
    op.drop_index(
        "ix_loyalty_terminal_devices_revoked_at",
        table_name="loyalty_terminal_devices",
    )
    op.drop_index(
        "ix_loyalty_terminal_devices_store_id",
        table_name="loyalty_terminal_devices",
    )
    op.drop_index(
        "ix_loyalty_terminal_devices_merchant_id",
        table_name="loyalty_terminal_devices",
    )
    op.drop_table("loyalty_terminal_devices")
