"""

Revision ID: f089dfb7e3ba
Revises:
Create Date: 2025-06-23 17:48:32.842030

"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from lecrapaud.config import LECRAPAUD_TABLE_PREFIX


# revision identifiers, used by Alembic.
revision: str = "f089dfb7e3ba"
down_revision: Union[str, None] = None
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(
        f"{LECRAPAUD_TABLE_PREFIX}_experiments",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("path", sa.String(length=255), nullable=True),
        sa.Column("type", sa.String(length=50), nullable=False),
        sa.Column("size", sa.Integer(), nullable=False),
        sa.Column("train_size", sa.Integer(), nullable=True),
        sa.Column("val_size", sa.Integer(), nullable=True),
        sa.Column("test_size", sa.Integer(), nullable=True),
        sa.Column("corr_threshold", sa.Float(), nullable=False),
        sa.Column("max_features", sa.Integer(), nullable=False),
        sa.Column("percentile", sa.Float(), nullable=False),
        sa.Column("number_of_groups", sa.Integer(), nullable=True),
        sa.Column("list_of_groups", sa.JSON(), nullable=True),
        sa.Column("start_date", sa.DateTime(), nullable=True),
        sa.Column("end_date", sa.DateTime(), nullable=True),
        sa.Column("train_start_date", sa.DateTime(), nullable=True),
        sa.Column("train_end_date", sa.DateTime(), nullable=True),
        sa.Column("val_start_date", sa.DateTime(), nullable=True),
        sa.Column("val_end_date", sa.DateTime(), nullable=True),
        sa.Column("test_start_date", sa.DateTime(), nullable=True),
        sa.Column("test_end_date", sa.DateTime(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("name", name="uq_experiments_composite"),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_experiments_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_experiments",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_features",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("type", sa.String(length=50), nullable=True),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("name"),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_features_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_features",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_models",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("type", sa.String(length=50), nullable=False),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("name", "type", name="uq_model_composite"),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_models_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_models",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_targets",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("type", sa.String(length=50), nullable=False),
        sa.Column("description", sa.String(length=255), nullable=True),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("name", "type", name="uq_target_composite"),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_targets_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_targets",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_experiment_target_association",
        sa.Column("experiment_id", sa.BigInteger(), nullable=False),
        sa.Column("target_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["experiment_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_experiments.id"],
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["target_id"], [f"{LECRAPAUD_TABLE_PREFIX}_targets.id"], ondelete="CASCADE"
        ),
        sa.PrimaryKeyConstraint("experiment_id", "target_id"),
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_feature_selections",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("training_time", sa.Integer(), nullable=True),
        sa.Column("best_features_path", sa.String(length=255), nullable=True),
        sa.Column("experiment_id", sa.BigInteger(), nullable=False),
        sa.Column("target_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["experiment_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_experiments.id"],
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["target_id"], [f"{LECRAPAUD_TABLE_PREFIX}_targets.id"], ondelete="CASCADE"
        ),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint(
            "experiment_id", "target_id", name="uq_feature_selection_composite"
        ),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_feature_selections_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_feature_selections",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_model_selections",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("best_model_params", sa.JSON(), nullable=True),
        sa.Column("best_model_path", sa.String(length=255), nullable=True),
        sa.Column("best_model_id", sa.BigInteger(), nullable=True),
        sa.Column("target_id", sa.BigInteger(), nullable=False),
        sa.Column("experiment_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["best_model_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_models.id"],
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["experiment_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_experiments.id"],
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["target_id"], [f"{LECRAPAUD_TABLE_PREFIX}_targets.id"], ondelete="CASCADE"
        ),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint(
            "target_id", "experiment_id", name="uq_model_selection_composite"
        ),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_model_selections_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_model_selections",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_feature_selection_association",
        sa.Column("feature_selection_id", sa.BigInteger(), nullable=False),
        sa.Column("feature_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["feature_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_features.id"],
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["feature_selection_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_feature_selections.id"],
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("feature_selection_id", "feature_id"),
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_feature_selection_ranks",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("score", sa.Float(), nullable=True),
        sa.Column("pvalue", sa.Float(), nullable=True),
        sa.Column("support", sa.Integer(), nullable=True),
        sa.Column("rank", sa.Integer(), nullable=True),
        sa.Column("method", sa.String(length=50), nullable=True),
        sa.Column("training_time", sa.Integer(), nullable=True),
        sa.Column("feature_id", sa.BigInteger(), nullable=True),
        sa.Column("feature_selection_id", sa.BigInteger(), nullable=True),
        sa.ForeignKeyConstraint(
            ["feature_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_features.id"],
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["feature_selection_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_feature_selections.id"],
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint(
            "feature_id",
            "feature_selection_id",
            "method",
            name="uq_feature_selection_rank_composite",
        ),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_feature_selection_ranks_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_feature_selection_ranks",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_model_trainings",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("best_params", sa.JSON(), nullable=True),
        sa.Column("model_path", sa.String(length=255), nullable=True),
        sa.Column("training_time", sa.Integer(), nullable=True),
        sa.Column("model_id", sa.BigInteger(), nullable=False),
        sa.Column("model_selection_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["model_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_models.id"],
        ),
        sa.ForeignKeyConstraint(
            ["model_selection_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_model_selections.id"],
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint(
            "model_id", "model_selection_id", name="uq_model_training_composite"
        ),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_model_trainings_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_model_trainings",
        ["id"],
        unique=False,
    )
    op.create_table(
        f"{LECRAPAUD_TABLE_PREFIX}_scores",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column(
            "created_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            sa.TIMESTAMP(timezone=True),
            server_default=sa.text("now()"),
            nullable=False,
        ),
        sa.Column("type", sa.String(length=50), nullable=False),
        sa.Column("training_time", sa.Integer(), nullable=True),
        sa.Column("eval_data_std", sa.Float(), nullable=True),
        sa.Column("rmse", sa.Float(), nullable=True),
        sa.Column("rmse_std_ratio", sa.Float(), nullable=True),
        sa.Column("mae", sa.Float(), nullable=True),
        sa.Column("mape", sa.Float(), nullable=True),
        sa.Column("mam", sa.Float(), nullable=True),
        sa.Column("mad", sa.Float(), nullable=True),
        sa.Column("mae_mam_ratio", sa.Float(), nullable=True),
        sa.Column("mae_mad_ratio", sa.Float(), nullable=True),
        sa.Column("r2", sa.Float(), nullable=True),
        sa.Column("logloss", sa.Float(), nullable=True),
        sa.Column("accuracy", sa.Float(), nullable=True),
        sa.Column("precision", sa.Float(), nullable=True),
        sa.Column("recall", sa.Float(), nullable=True),
        sa.Column("f1", sa.Float(), nullable=True),
        sa.Column("roc_auc", sa.Float(), nullable=True),
        sa.Column("threshold", sa.Float(), nullable=True),
        sa.Column("precision_at_threshold", sa.Float(), nullable=True),
        sa.Column("recall_at_threshold", sa.Float(), nullable=True),
        sa.Column("model_training_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["model_training_id"],
            [f"{LECRAPAUD_TABLE_PREFIX}_model_trainings.id"],
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_scores_id"),
        f"{LECRAPAUD_TABLE_PREFIX}_scores",
        ["id"],
        unique=False,
    )
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_scores_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_scores",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_scores")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_model_trainings_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_model_trainings",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_model_trainings")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_feature_selection_ranks_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_feature_selection_ranks",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_feature_selection_ranks")
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_feature_selection_association")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_model_selections_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_model_selections",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_model_selections")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_feature_selections_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_feature_selections",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_feature_selections")
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_experiment_target_association")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_targets_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_targets",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_targets")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_models_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_models",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_models")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_features_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_features",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_features")
    op.drop_index(
        op.f(f"ix_{LECRAPAUD_TABLE_PREFIX}_experiments_id"),
        table_name=f"{LECRAPAUD_TABLE_PREFIX}_experiments",
    )
    op.drop_table(f"{LECRAPAUD_TABLE_PREFIX}_experiments")
    # ### end Alembic commands ###
