"""v0.13.0-RC1 migration

Revision ID: d9a77cb243c8
Revises: 72e2079576d3
Create Date: 2025-06-16 21:43:35.246009

"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision: str = "d9a77cb243c8"
down_revision: Union[str, None] = "72e2079576d3"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "gear_components",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column(
            "user_id",
            sa.Integer(),
            nullable=False,
            comment="User ID that the gear component belongs to",
        ),
        sa.Column(
            "gear_id",
            sa.Integer(),
            nullable=False,
            comment="Gear ID associated with this component",
        ),
        sa.Column(
            "type",
            sa.String(length=250),
            nullable=False,
            comment="Type of gear component",
        ),
        sa.Column(
            "brand",
            sa.String(length=250),
            nullable=False,
            comment="Gear component brand (May include spaces)",
        ),
        sa.Column(
            "model",
            sa.String(length=250),
            nullable=False,
            comment="Gear component model (May include spaces)",
        ),
        sa.Column(
            "purchase_date",
            sa.DateTime(),
            nullable=False,
            comment="Gear component purchase date (DateTime)",
        ),
        sa.Column(
            "retired_date",
            sa.DateTime(),
            nullable=True,
            comment="Gear component retired date (DateTime)",
        ),
        sa.Column(
            "is_active",
            sa.Boolean(),
            nullable=False,
            comment="Is gear component active",
        ),
        sa.Column(
            "expected_kms",
            sa.Integer(),
            nullable=True,
            comment="Expected kilometers of the gear component",
        ),
        sa.Column(
            "purchase_value",
            sa.DECIMAL(precision=11, scale=2),
            nullable=True,
            comment="Purchase value of the gear component",
        ),
        sa.ForeignKeyConstraint(["gear_id"], ["gear.id"], ondelete="CASCADE"),
        sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_gear_components_gear_id"), "gear_components", ["gear_id"], unique=False
    )
    # Add new column to gear table
    op.add_column(
        "gear",
        sa.Column(
            "purchase_value",
            sa.DECIMAL(precision=11, scale=2),
            nullable=True,
            comment="Gear purchase value",
        ),
    )
    op.alter_column(
        "gear",
        "initial_kms",
        existing_type=sa.DECIMAL(precision=11, scale=3),
        type_=sa.DECIMAL(precision=11, scale=2),
        existing_comment="Initial kilometers of the gear",
        existing_nullable=False,
    )
    op.alter_column(
        "gear",
        "gear_type",
        existing_type=sa.INTEGER(),
        comment="Gear type (1 - bike, 2 - shoes, 3 - wetsuit, 4 - racquet, 5 - skis, 6 - snowboard, 7 - windsurf)",
        existing_comment="Gear type (1 - bike, 2 - shoes, 3 - wetsuit, 4 - racquet, 5 - skis, 6 - snowboard)",
        existing_nullable=False,
    )
    # Add new columns to server_settings table
    op.add_column(
        "server_settings",
        sa.Column(
            "currency",
            sa.Integer(),
            nullable=True,
            comment="Currency (one digit)(1 - euro, 2 - dollar, 3 - pound)",
        ),
    )
    op.add_column(
        "server_settings",
        sa.Column(
            "num_records_per_page",
            sa.Integer(),
            nullable=True,
            comment="Number of records per page in lists",
        ),
    )
    op.execute(
        """
        UPDATE server_settings
        SET currency = 1, num_records_per_page = 25
        WHERE id = 1;
    """
    )
    op.alter_column(
        "server_settings",
        "currency",
        nullable=False,
        comment="Currency (one digit)(1 - euro, 2 - dollar, 3 - pound)",
        existing_type=sa.Integer(),
    )
    op.alter_column(
        "server_settings",
        "num_records_per_page",
        nullable=False,
        comment="Number of records per page in lists",
        existing_type=sa.Integer(),
    )
    op.alter_column(
        "server_settings",
        "units",
        existing_type=sa.INTEGER(),
        comment="Units (one digit)(1 - metric, 2 - imperial)",
        existing_comment="User units (one digit)(1 - metric, 2 - imperial)",
        existing_nullable=False,
    )
    # Add new column to users table
    op.add_column(
        "users",
        sa.Column(
            "currency",
            sa.Integer(),
            nullable=True,
            comment="User currency (one digit)(1 - euro, 2 - dollar, 3 - pound)",
        ),
    )
    op.execute(
        """
        UPDATE users
        SET currency = 1
        WHERE currency IS NULL;
    """
    )
    op.alter_column(
        "users",
        "currency",
        nullable=False,
        comment="User currency (one digit)(1 - euro, 2 - dollar, 3 - pound)",
        existing_type=sa.Integer(),
    )
    op.add_column(
        "users",
        sa.Column(
            "first_day_of_week",
            sa.Integer(),
            nullable=True,
            comment="User first day of week (0 - Sunday, 1 - Monday, etc.)",
        ),
    )
    op.execute(
        """
        UPDATE users
        SET first_day_of_week = 1
        WHERE first_day_of_week IS NULL;
    """
    )
    op.alter_column(
        "users",
        "first_day_of_week",
        nullable=False,
        comment="User first day of week (0 - Sunday, 1 - Monday, etc.)",
        existing_type=sa.Integer(),
    )
    # Create notifications table
    op.create_table(
        "notifications",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column(
            "user_id",
            sa.Integer(),
            nullable=False,
            comment="User ID that the gear belongs to",
        ),
        sa.Column(
            "type",
            sa.Integer(),
            nullable=False,
            comment="Notification type",
        ),
        sa.Column(
            "options",
            sa.JSON(),
            nullable=True,
            comment="Notification options (JSON)",
        ),
        sa.Column(
            "read",
            sa.Boolean(),
            nullable=False,
            comment="Has the notification been read (True) or not (False)",
        ),
        sa.Column(
            "created_at",
            sa.DateTime(),
            nullable=False,
            comment="Notification creation date (DateTime)",
        ),
        sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
        # Add a comment to the table
        op.alter_column(
            "activities_streams",
            "stream_waypoints",
            existing_type=sa.JSON(),
            comment="Store waypoints data",
            existing_nullable=False,
        ),
    )
    # Add new column to activities table
    op.add_column(
        "activities",
        sa.Column(
            "private_notes",
            sa.String(length=2500),
            nullable=True,
            comment="Activity private notes (May include spaces)",
        ),
    )
    op.add_column(
        "activities",
        sa.Column(
            "is_hidden",
            sa.Boolean(),
            nullable=True,
            default=False,
            comment="Indicates if the activity is hidden (e.g., duplicate activity waiting to be reviewed by the user)",
        ),
    )
    # Set default value for existing records
    op.execute(
        """
        UPDATE activities
        SET is_hidden = FALSE
        """
    )
    # Make the column non-nullable now that all rows have a value
    op.alter_column(
        "activities",
        "is_hidden",
        existing_type=sa.Boolean(),
        nullable=False,
    )
    # Add new column to users_default_gear table
    op.add_column(
        "users_default_gear",
        sa.Column(
            "windsurf_gear_id",
            sa.Integer(),
            nullable=True,
            comment="Gear ID that the default windsurf activity type belongs",
        ),
    )
    op.create_index(
        op.f("ix_users_default_gear_windsurf_gear_id"),
        "users_default_gear",
        ["windsurf_gear_id"],
        unique=False,
    )
    op.create_foreign_key(
        None,
        "users_default_gear",
        "gear",
        ["windsurf_gear_id"],
        ["id"],
        ondelete="SET NULL",
    )
    # Create activity_media table
    op.create_table(
        "activity_media",
        sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
        sa.Column(
            "activity_id",
            sa.Integer(),
            nullable=False,
            comment="Activity ID that the activity media belongs",
        ),
        sa.Column(
            "media_path", sa.String(length=250), nullable=True, comment="Media path"
        ),
        sa.Column(
            "media_type", sa.Integer(), nullable=False, comment="Media type (1 - photo)"
        ),
        sa.ForeignKeyConstraint(["activity_id"], ["activities.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_activity_media_activity_id"),
        "activity_media",
        ["activity_id"],
        unique=False,
    )
    op.create_unique_constraint(None, "activity_media", ["media_path"])
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, "activity_media", type_="unique")
    op.drop_table("activity_media")
    op.drop_constraint(None, "users_default_gear", type_="foreignkey")
    op.drop_index(
        op.f("ix_users_default_gear_windsurf_gear_id"), table_name="users_default_gear"
    )
    op.drop_column("users_default_gear", "windsurf_gear_id")
    op.drop_column("activities", "is_hidden")
    op.drop_column("activities", "private_notes")
    op.alter_column(
        "activities_streams",
        "stream_waypoints",
        existing_type=sa.JSON(),
        comment=None,
        existing_comment="Store waypoints data",
        existing_nullable=False,
    )
    op.drop_table("notifications")
    op.drop_index(op.f("ix_gear_components_gear_id"), table_name="gear_components")
    op.drop_table("gear_components")
    op.alter_column(
        "server_settings",
        "units",
        existing_type=sa.INTEGER(),
        comment="User units (one digit)(1 - metric, 2 - imperial)",
        existing_comment="Units (one digit)(1 - metric, 2 - imperial)",
        existing_nullable=False,
    )
    op.alter_column(
        "gear",
        "gear_type",
        existing_type=sa.INTEGER(),
        comment="Gear type (1 - bike, 2 - shoes, 3 - wetsuit, 4 - racquet, 5 - skis, 6 - snowboard)",
        existing_comment="Gear type (1 - bike, 2 - shoes, 3 - wetsuit, 4 - racquet, 5 - skis, 6 - snowboard, 7 - windsurf)",
        existing_nullable=False,
    )
    op.alter_column(
        "gear",
        "initial_kms",
        existing_type=sa.DECIMAL(precision=11, scale=2),
        type_=sa.DECIMAL(precision=11, scale=3),
        existing_comment="Initial kilometers of the gear",
        existing_nullable=False,
    )
    op.drop_column("gear", "purchase_value")
    op.drop_column("server_settings", "currency")
    op.drop_column("server_settings", "num_records_per_page")
    op.drop_column("users", "first_day_of_week")
    op.drop_column("users", "currency")
    # ### end Alembic commands ###
