"""active workout flow

Revision ID: 0002_active_workout_flow
Revises: 0001_initial
Create Date: 2026-05-29 08:40:00.000000
"""

from collections.abc import Sequence

import sqlalchemy as sa
from alembic import op

revision: str = "0002_active_workout_flow"
down_revision: str | None = "0001_initial"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
    op.add_column(
        "logic_workouts",
        sa.Column("status", sa.String(length=20), nullable=False, server_default="active"),
    )
    op.add_column(
        "logic_workouts",
        sa.Column("total_sets", sa.Integer(), nullable=False, server_default="0"),
    )
    op.add_column(
        "logic_workouts",
        sa.Column("total_volume", sa.Numeric(12, 2), nullable=False, server_default="0"),
    )
    op.create_index("ix_logic_workouts_status", "logic_workouts", ["status"])
    op.create_check_constraint(
        "ck_workout_status",
        "logic_workouts",
        "status IN ('active', 'finished', 'discarded')",
    )
    op.execute(
        "UPDATE logic_workouts SET status = 'finished' WHERE finished_at IS NOT NULL"
    )

    op.add_column(
        "logic_workout_items",
        sa.Column("source_kind", sa.String(length=20), nullable=True),
    )
    op.add_column(
        "logic_workout_items",
        sa.Column("title_snapshot", sa.String(length=160), nullable=True),
    )
    op.add_column(
        "logic_workout_items",
        sa.Column("image_s3_url_snapshot", sa.Text(), nullable=True),
    )
    op.execute(
        """
        UPDATE logic_workout_items AS item
        SET
            source_kind = 'exercise',
            title_snapshot = exercise.name,
            image_s3_url_snapshot = exercise.image_s3_url
        FROM logic_exercises AS exercise
        WHERE item.exercise_id = exercise.id
        """
    )
    op.execute(
        """
        UPDATE logic_workout_items AS item
        SET
            source_kind = 'equipment',
            title_snapshot = equipment.name,
            image_s3_url_snapshot = equipment.image_s3_url
        FROM logic_equipment AS equipment
        WHERE item.equipment_id = equipment.id
        """
    )
    op.alter_column("logic_workout_items", "source_kind", nullable=False)
    op.alter_column("logic_workout_items", "title_snapshot", nullable=False)
    op.create_check_constraint(
        "ck_workout_item_source_kind",
        "logic_workout_items",
        "source_kind IN ('exercise', 'equipment')",
    )

    op.execute(
        """
        UPDATE logic_workouts AS workout
        SET
            total_sets = totals.total_sets,
            total_volume = totals.total_volume,
            estimated_calories = totals.estimated_calories
        FROM (
            SELECT
                item.workout_id,
                COUNT(set_row.id) AS total_sets,
                COALESCE(SUM(set_row.weight * set_row.reps), 0) AS total_volume,
                COALESCE(SUM(set_row.calories), 0) AS estimated_calories
            FROM logic_workout_items AS item
            LEFT JOIN logic_workout_sets AS set_row ON set_row.workout_item_id = item.id
            GROUP BY item.workout_id
        ) AS totals
        WHERE workout.id = totals.workout_id
        """
    )


def downgrade() -> None:
    op.drop_constraint("ck_workout_item_source_kind", "logic_workout_items", type_="check")
    op.drop_column("logic_workout_items", "image_s3_url_snapshot")
    op.drop_column("logic_workout_items", "title_snapshot")
    op.drop_column("logic_workout_items", "source_kind")

    op.drop_constraint("ck_workout_status", "logic_workouts", type_="check")
    op.drop_index("ix_logic_workouts_status", table_name="logic_workouts")
    op.drop_column("logic_workouts", "total_volume")
    op.drop_column("logic_workouts", "total_sets")
    op.drop_column("logic_workouts", "status")
