"""add notifications + announcements

Revision ID: 048_notifications
Revises: 047_promo_code_advanced_rules
Create Date: 2026-06-19
"""

import sqlalchemy as sa
from alembic import op


revision = "048_notifications"
down_revision = "047_promo_code_advanced_rules"
branch_labels = None
depends_on = None


def _table_names(bind) -> set[str]:
    return set(sa.inspect(bind).get_table_names())


def upgrade() -> None:
    bind = op.get_bind()
    tables = _table_names(bind)

    if "notifications" not in tables:
        op.create_table(
            "notifications",
            sa.Column("user_id", sa.BigInteger(), nullable=False),
            sa.Column("category", sa.String(length=24), nullable=False, server_default=sa.text("'system'")),
            sa.Column("title", sa.String(length=128), nullable=False),
            sa.Column("content", sa.Text(), nullable=False),
            sa.Column("link", sa.String(length=256), nullable=True),
            sa.Column("is_read", sa.Boolean(), nullable=False, server_default=sa.text("0")),
            sa.Column("read_at", sa.DateTime(timezone=True), nullable=True),
            sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
            sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
            sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
            sa.PrimaryKeyConstraint("id"),
        )
        op.create_index("ix_notifications_user_id", "notifications", ["user_id"])
        op.create_index("ix_notifications_category", "notifications", ["category"])
        op.create_index("ix_notifications_is_read", "notifications", ["is_read"])
        op.create_index("ix_notifications_user_read", "notifications", ["user_id", "is_read"])

    if "announcements" not in tables:
        op.create_table(
            "announcements",
            sa.Column("title", sa.String(length=128), nullable=False),
            sa.Column("content", sa.Text(), nullable=False),
            sa.Column("category", sa.String(length=24), nullable=False, server_default=sa.text("'announcement'")),
            sa.Column("target_type", sa.String(length=16), nullable=False, server_default=sa.text("'all'")),
            sa.Column("target_user_ids", sa.JSON(), nullable=True),
            sa.Column("is_published", sa.Boolean(), nullable=False, server_default=sa.text("1")),
            sa.Column("published_at", sa.DateTime(timezone=True), nullable=True),
            sa.Column("created_by", sa.BigInteger(), nullable=True),
            sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
            sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
            sa.PrimaryKeyConstraint("id"),
        )
        op.create_index("ix_announcements_is_published", "announcements", ["is_published"])

    if "announcement_reads" not in tables:
        op.create_table(
            "announcement_reads",
            sa.Column("announcement_id", sa.Integer(), nullable=False),
            sa.Column("user_id", sa.BigInteger(), nullable=False),
            sa.Column("read_at", sa.DateTime(timezone=True), nullable=False),
            sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
            sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
            sa.ForeignKeyConstraint(["announcement_id"], ["announcements.id"], ondelete="CASCADE"),
            sa.PrimaryKeyConstraint("id"),
            sa.UniqueConstraint("announcement_id", "user_id", name="uq_announcement_user"),
        )
        op.create_index("ix_announcement_reads_announcement_id", "announcement_reads", ["announcement_id"])
        op.create_index("ix_announcement_reads_user_id", "announcement_reads", ["user_id"])


def downgrade() -> None:
    bind = op.get_bind()
    tables = _table_names(bind)
    if "announcement_reads" in tables:
        op.drop_table("announcement_reads")
    if "announcements" in tables:
        op.drop_table("announcements")
    if "notifications" in tables:
        op.drop_table("notifications")
