# Generated by Django 3.2.20 on 2023-07-27 11:28

from django.db import migrations, models
import django.db.models.deletion
import leprikon.models.fields


def update_current_subject_variants(apps, schema_editor):
    Subject = apps.get_model("leprikon", "Subject")
    for subject in Subject.objects.all():
        subject.variants.filter(available=True).update(reg_from=subject.reg_from, reg_to=subject.reg_to)
        for attr in [
            "min_participants_count",
            "max_participants_count",
            "registration_price",
            "participant_price",
        ]:
            subject.variants.filter(**{attr: None}).update(**{attr: getattr(subject, attr)})


def create_default_subject_variants(apps, schema_editor):
    Subject = apps.get_model("leprikon", "Subject")
    SubjectVariant = apps.get_model("leprikon", "SubjectVariant")
    SubjectRegistration = apps.get_model("leprikon", "SubjectRegistration")

    subject_variants = {
        subject_variant.subject_id: subject_variant
        for subject_variant in SubjectVariant.objects.bulk_create(
            SubjectVariant(
                subject=subject,
                name="",
                description="",
                reg_from=subject.reg_from,
                reg_to=subject.reg_to,
                min_participants_count=subject.min_participants_count,
                max_participants_count=subject.max_participants_count,
                registration_price=subject.registration_price,
                participant_price=subject.participant_price,
                school_year_division_id=subject.school_year_division_id,
                allow_period_selection=subject.allow_period_selection or False,
            )
            for subject in Subject.objects.annotate(
                num_variants=models.Count("variants"),
                school_year_division_id=models.F("course__school_year_division_id"),
                allow_period_selection=models.F("course__allow_period_selection"),
            )
            if subject.num_variants == 0
        )
    }

    for subject_variant in subject_variants.values():
        subject_variant.age_groups.set(subject_variant.subject.age_groups.all())
        subject_variant.target_groups.set(subject_variant.subject.target_groups.all())

        SubjectRegistration.objects.filter(subject=subject_variant.subject, subject_variant=None).update(
            subject_variant=subject_variant
        )

    for reg in (
        SubjectRegistration.objects.filter(subject_variant=None)
        .annotate(
            school_year_division_id=models.F("subject__course__school_year_division_id"),
            allow_period_selection=models.F("subject__course__allow_period_selection"),
        )
        .select_related("subject")
    ):
        if reg.subject_id not in subject_variants:
            subject_variants[reg.subject_id] = SubjectVariant.objects.create(
                subject=reg.subject,
                name="",
                description="",
                reg_from=reg.subject.reg_from,
                reg_to=reg.subject.reg_to,
                min_participants_count=reg.subject.min_participants_count,
                max_participants_count=reg.subject.max_participants_count,
                registration_price=reg.subject.registration_price,
                participant_price=reg.subject.participant_price,
                school_year_division_id=reg.school_year_division_id,
                allow_period_selection=reg.allow_period_selection,
            )
            subject_variants[reg.subject_id].age_groups.set(reg.subject.age_groups.all())
            subject_variants[reg.subject_id].target_groups.set(reg.subject.target_groups.all())
        reg.subject_variant = subject_variants[reg.subject_id]
        reg.save()


def update_registration_links(apps, schema_editor):
    RegistrationLink = apps.get_model("leprikon", "RegistrationLink")
    SubjectVariant = apps.get_model("leprikon", "SubjectVariant")

    for registration_link in RegistrationLink.objects.all():
        registration_link.subject_variants.set(
            SubjectVariant.objects.filter(subject__in=registration_link.subjects.all())
        )


class Migration(migrations.Migration):
    dependencies = [
        ("leprikon", "0078_delete_coursevariant"),
    ]

    operations = [
        # migrate SubjectVariant
        migrations.AddField(
            model_name="subjectvariant",
            name="reg_from",
            field=models.DateTimeField(blank=True, null=True, verbose_name="registration active from"),
        ),
        migrations.AddField(
            model_name="subjectvariant",
            name="reg_to",
            field=models.DateTimeField(blank=True, null=True, verbose_name="registration active to"),
        ),
        migrations.RunPython(update_current_subject_variants),
        migrations.RunPython(create_default_subject_variants),
        migrations.AlterField(
            model_name="subjectregistration",
            name="subject_variant",
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.PROTECT,
                related_name="registrations",
                to="leprikon.subjectvariant",
                verbose_name="variant",
            ),
        ),
        migrations.AlterField(
            model_name="subjectvariant",
            name="max_participants_count",
            field=models.PositiveIntegerField(
                default=1, verbose_name="maximal participants / group members count per registration"
            ),
        ),
        migrations.AlterField(
            model_name="subjectvariant",
            name="min_participants_count",
            field=models.PositiveIntegerField(
                default=1, verbose_name="minimal participants / group members count per registration"
            ),
        ),
        migrations.AlterField(
            model_name="subjectvariant",
            name="name",
            field=models.CharField(blank=True, default="", max_length=150, verbose_name="variant name"),
        ),
        migrations.AlterField(
            model_name="subjectvariant",
            name="participant_price",
            field=leprikon.models.fields.PriceField(
                decimal_places=0, default=0, max_digits=10, verbose_name="price per participant"
            ),
        ),
        migrations.AlterField(
            model_name="subjectvariant",
            name="registration_price",
            field=leprikon.models.fields.PriceField(
                decimal_places=0, default=0, max_digits=10, verbose_name="price per registration"
            ),
        ),
        migrations.RemoveField(
            model_name="course",
            name="allow_period_selection",
        ),
        migrations.RemoveField(
            model_name="course",
            name="school_year_division",
        ),
        migrations.RemoveField(
            model_name="subject",
            name="max_participants_count",
        ),
        migrations.RemoveField(
            model_name="subject",
            name="min_participants_count",
        ),
        migrations.RemoveField(
            model_name="subject",
            name="participant_price",
        ),
        migrations.RemoveField(
            model_name="subject",
            name="reg_from",
        ),
        migrations.RemoveField(
            model_name="subject",
            name="reg_to",
        ),
        migrations.RemoveField(
            model_name="subject",
            name="registration_price",
        ),
        migrations.RemoveField(
            model_name="subjectvariant",
            name="available",
        ),
        migrations.RemoveField(
            model_name="courseregistration",
            name="school_year_division",
        ),
        # migrate RegistrationLink
        migrations.AddField(
            model_name="registrationlink",
            name="subject_variants",
            field=models.ManyToManyField(
                related_name="registration_links", to="leprikon.SubjectVariant", verbose_name="subjects"
            ),
        ),
        migrations.RunPython(update_registration_links),
        migrations.RemoveField(
            model_name="registrationlink",
            name="subjects",
        ),
    ]
