"""Notifications, preferences, and device push tokens

Revision ID: 010_notifications
Revises: 009_auth_lockout
Create Date: 2026-06-26

"""

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op
from sqlalchemy import inspect

revision: str = "010_notifications"
down_revision: Union[str, None] = "009_auth_lockout"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def _has_table(name: str) -> bool:
    bind = op.get_bind()
    return name in inspect(bind).get_table_names()


def upgrade() -> None:
    if not _has_table("notifications"):
        op.create_table(
            "notifications",
            sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
            sa.Column("user_id", sa.Integer(), nullable=False),
            sa.Column("agency_id", sa.Integer(), nullable=False),
            sa.Column("policy_id", sa.Integer(), nullable=True),
            sa.Column("notification_type", sa.String(length=30), nullable=False),
            sa.Column("title", sa.String(length=255), nullable=False),
            sa.Column("message", sa.Text(), nullable=False),
            sa.Column("link_path", sa.String(length=255), 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("notification_date", sa.Date(), nullable=False),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("CURRENT_TIMESTAMP")),
            sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("CURRENT_TIMESTAMP")),
            sa.ForeignKeyConstraint(["agency_id"], ["agencies.id"]),
            sa.ForeignKeyConstraint(["policy_id"], ["policies.id"]),
            sa.ForeignKeyConstraint(["user_id"], ["users.id"]),
            sa.PrimaryKeyConstraint("id"),
            sa.UniqueConstraint(
                "user_id",
                "policy_id",
                "notification_type",
                "notification_date",
                name="uq_notification_daily",
            ),
        )
        op.create_index("ix_notifications_user_id", "notifications", ["user_id"])
        op.create_index("ix_notifications_agency_id", "notifications", ["agency_id"])
        op.create_index("ix_notifications_is_read", "notifications", ["is_read"])
        op.create_index("ix_notifications_notification_date", "notifications", ["notification_date"])

    if not _has_table("user_notification_preferences"):
        op.create_table(
            "user_notification_preferences",
            sa.Column("user_id", sa.Integer(), nullable=False),
            sa.Column("notify_expiring_today", sa.Boolean(), nullable=False, server_default=sa.text("1")),
            sa.Column("notify_expiring_tomorrow", sa.Boolean(), nullable=False, server_default=sa.text("1")),
            sa.Column("notify_expiring_next_week", sa.Boolean(), nullable=False, server_default=sa.text("1")),
            sa.Column("push_enabled", sa.Boolean(), nullable=False, server_default=sa.text("0")),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("CURRENT_TIMESTAMP")),
            sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("CURRENT_TIMESTAMP")),
            sa.ForeignKeyConstraint(["user_id"], ["users.id"]),
            sa.PrimaryKeyConstraint("user_id"),
        )

    if not _has_table("device_push_tokens"):
        op.create_table(
            "device_push_tokens",
            sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
            sa.Column("user_id", sa.Integer(), nullable=False),
            sa.Column("platform", sa.String(length=10), nullable=False),
            sa.Column("token", sa.String(length=512), nullable=False),
            sa.Column("device_name", sa.String(length=255), nullable=True),
            sa.Column("last_used_at", sa.DateTime(timezone=True), nullable=True),
            sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("CURRENT_TIMESTAMP")),
            sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("CURRENT_TIMESTAMP")),
            sa.ForeignKeyConstraint(["user_id"], ["users.id"]),
            sa.PrimaryKeyConstraint("id"),
            sa.UniqueConstraint("user_id", "token", name="uq_device_push_token"),
        )
        op.create_index("ix_device_push_tokens_user_id", "device_push_tokens", ["user_id"])


def downgrade() -> None:
    if _has_table("device_push_tokens"):
        op.drop_table("device_push_tokens")
    if _has_table("user_notification_preferences"):
        op.drop_table("user_notification_preferences")
    if _has_table("notifications"):
        op.drop_table("notifications")
