"""added shopping list label settings

Revision ID: b04a08da2108
Revises: 5ab195a474eb
Create Date: 2023-21-02 22:03:19.837244

"""

from uuid import uuid4

import sqlalchemy as sa
from sqlalchemy import orm

import mealie.db.migration_types
from alembic import op
from mealie.db.models._model_utils.guid import GUID

# revision identifiers, used by Alembic.
revision = "b04a08da2108"
down_revision = "5ab195a474eb"
branch_labels: str | tuple[str, ...] | None = None
depends_on: str | tuple[str, ...] | None = None


# Intermediate table definitions
class SqlAlchemyBase(orm.DeclarativeBase):
    pass


class ShoppingList(SqlAlchemyBase):
    __tablename__ = "shopping_lists"

    id: orm.Mapped[GUID] = orm.mapped_column(GUID, primary_key=True, default=GUID.generate)
    group_id: orm.Mapped[GUID] = orm.mapped_column(GUID, sa.ForeignKey("groups.id"), nullable=False, index=True)


class MultiPurposeLabel(SqlAlchemyBase):
    __tablename__ = "multi_purpose_labels"

    id: orm.Mapped[GUID] = orm.mapped_column(GUID, primary_key=True, default=GUID.generate)
    group_id: orm.Mapped[GUID] = orm.mapped_column(GUID, sa.ForeignKey("groups.id"), nullable=False, index=True)


def populate_shopping_lists_multi_purpose_labels(
    shopping_lists_multi_purpose_labels_table: sa.Table, session: orm.Session
):
    shopping_lists = session.query(ShoppingList).options(orm.load_only(ShoppingList.id, ShoppingList.group_id)).all()

    shopping_lists_labels_data: list[dict] = []
    for shopping_list in shopping_lists:
        labels = session.query(MultiPurposeLabel).filter(MultiPurposeLabel.group_id == ShoppingList.group_id).all()
        for i, label in enumerate(labels):
            shopping_lists_labels_data.append(
                {"id": uuid4(), "shopping_list_id": shopping_list.id, "label_id": label.id, "position": i}
            )

    op.bulk_insert(shopping_lists_multi_purpose_labels_table, shopping_lists_labels_data)
    session.commit()


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    shopping_lists_multi_purpose_labels_table = op.create_table(
        "shopping_lists_multi_purpose_labels",
        sa.Column("created_at", sa.DateTime(), nullable=True),
        sa.Column("update_at", sa.DateTime(), nullable=True),
        sa.Column("id", mealie.db.migration_types.GUID(), nullable=False),
        sa.Column("shopping_list_id", mealie.db.migration_types.GUID(), nullable=False),
        sa.Column("label_id", mealie.db.migration_types.GUID(), nullable=False),
        sa.Column("position", sa.Integer(), nullable=False),
        sa.ForeignKeyConstraint(
            ["label_id"],
            ["multi_purpose_labels.id"],
        ),
        sa.ForeignKeyConstraint(
            ["shopping_list_id"],
            ["shopping_lists.id"],
        ),
        sa.PrimaryKeyConstraint("id", "shopping_list_id", "label_id"),
    )
    # ### end Alembic commands ###

    session = orm.Session(bind=op.get_bind())
    populate_shopping_lists_multi_purpose_labels(shopping_lists_multi_purpose_labels_table, session)


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table("shopping_lists_multi_purpose_labels")
    # ### end Alembic commands ###
