# Generated by Django 5.2.3 on 2025-06-21 21:59

import django.db.models.deletion
from django.db import migrations, models
from django.db.migrations.state import StateApps
from django.db.models import Case, When

PRESIDENCY_ROLES = [10, 9]
MAXIMUM_FREE_ROLE = 1
SITH_CLUB_ROLES = {
    10: "Président⸱e",
    9: "Vice-Président⸱e",
    7: "Trésorier⸱e",
    5: "Responsable communication",
    4: "Secrétaire",
    3: "Responsable info",
    2: "Membre du bureau",
    1: "Membre actif⸱ve",
    0: "Curieux⸱euse",
}


def migrate_roles(apps: StateApps, schema_editor):
    ClubRole = apps.get_model("club", "ClubRole")
    Membership = apps.get_model("club", "Membership")

    updates = []
    for club_id, role in Membership.objects.values_list("club", "role").distinct():
        new_role = ClubRole.objects.create(
            name=SITH_CLUB_ROLES[role],
            is_board=role > MAXIMUM_FREE_ROLE,
            is_presidency=role in PRESIDENCY_ROLES,
            club_id=club_id,
            order=max(SITH_CLUB_ROLES) - role,
        )
        updates.append(When(club_id=club_id, role=role, then=new_role.id))
    # all updates must happen at the same time
    # otherwise, the 10 first created ClubRole would be
    # re-modified after their initial creation, and it would
    # result in an incoherent state.
    # To avoid that, all updates are wrapped in a single giant Case(When) statement
    # cf. https://docs.djangoproject.com/fr/stable/ref/models/conditional-expressions/#conditional-update
    Membership.objects.update(role=Case(*updates))


class Migration(migrations.Migration):
    dependencies = [
        ("club", "0014_alter_club_options_rename_unix_name_club_slug_name_and_more"),
        ("core", "0047_alter_notification_date_alter_notification_type"),
    ]

    operations = [
        migrations.AlterField(
            model_name="club",
            name="page",
            field=models.OneToOneField(
                blank=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="club",
                to="core.page",
            ),
        ),
        migrations.CreateModel(
            name="ClubRole",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "order",
                    models.PositiveIntegerField(
                        db_index=True, editable=False, verbose_name="order"
                    ),
                ),
                (
                    "club",
                    models.ForeignKey(
                        help_text="The club with which this role is associated",
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="roles",
                        to="club.club",
                        verbose_name="club",
                    ),
                ),
                ("name", models.CharField(max_length=50, verbose_name="name")),
                (
                    "description",
                    models.TextField(
                        default="", blank=True, verbose_name="description"
                    ),
                ),
                (
                    "is_board",
                    models.BooleanField(default=False, verbose_name="Board role"),
                ),
                (
                    "is_presidency",
                    models.BooleanField(default=False, verbose_name="Presidency role"),
                ),
                (
                    "is_active",
                    models.BooleanField(
                        default=True,
                        help_text=(
                            "If the role is inactive, people joining the club "
                            "won't be able to get it."
                        ),
                        verbose_name="is active",
                    ),
                ),
            ],
            options={
                "ordering": ("order",),
                "verbose_name": "club role",
                "verbose_name_plural": "club roles",
            },
        ),
        migrations.AlterField(
            model_name="club",
            name="board_group",
            field=models.OneToOneField(
                editable=False,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="club_board",
                to="core.group",
            ),
        ),
        migrations.AlterField(
            model_name="club",
            name="members_group",
            field=models.OneToOneField(
                editable=False,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="club",
                to="core.group",
            ),
        ),
        migrations.AddConstraint(
            model_name="clubrole",
            constraint=models.CheckConstraint(
                condition=models.Q(
                    ("is_presidency", False), ("is_board", True), _connector="OR"
                ),
                name="clubrole_presidency_implies_board",
                violation_error_message=(
                    "A role cannot be in the presidency while not being in the board"
                ),
            ),
        ),
        migrations.RunPython(migrate_roles, migrations.RunPython.noop),
        # because Postgres migrations run in a single transaction,
        # we cannot change the actual values of Membership.role
        # and apply the FOREIGN KEY constraint in the same migration.
        # The constraint is created in the next migration
    ]
