"""booking access link and participants

Revision ID: 299053c6f7b8
Revises: 149d70424ae0
Create Date: 2026-07-15 16:52:55.554576

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '299053c6f7b8'
down_revision: Union[str, Sequence[str], None] = '149d70424ae0'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    """Upgrade schema."""
    op.create_table(
        'booking_participants',
        sa.Column('booking_id', sa.UUID(), nullable=False),
        sa.Column('user_id', sa.UUID(), nullable=False),
        sa.ForeignKeyConstraint(['booking_id'], ['room_bookings.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
        sa.PrimaryKeyConstraint('booking_id', 'user_id'),
    )

    # Колонка добавляется nullable, чтобы не упасть на уже существующих
    # строках; backfill генерирует уникальный slug каждой существующей
    # брони, после чего ограничение NOT NULL накладывается отдельным шагом.
    op.add_column('room_bookings', sa.Column('access_link', sa.String(length=43), nullable=True))
    # gen_random_bytes живёт в pgcrypto (в отличие от gen_random_uuid,
    # встроенного в ядро с PG13) — расширение включается здесь же.
    op.execute("CREATE EXTENSION IF NOT EXISTS pgcrypto")
    op.execute("UPDATE room_bookings SET access_link = encode(gen_random_bytes(16), 'hex')")
    op.alter_column('room_bookings', 'access_link', nullable=False)
    op.create_unique_constraint(
        'uq_room_bookings_access_link', 'room_bookings', ['access_link']
    )


def downgrade() -> None:
    """Downgrade schema."""
    op.drop_constraint('uq_room_bookings_access_link', 'room_bookings', type_='unique')
    op.drop_column('room_bookings', 'access_link')
    op.drop_table('booking_participants')
