# Generated by ChatGPT on behalf of GitHub Copilot

from __future__ import annotations

# Django
from django.db import migrations, models

BP_TYPE_REACTION = "REACTION"
BP_TYPE_ORIGINAL = "ORIGINAL"
BP_TYPE_COPY = "COPY"
BP_TYPE_STACK = "STACK"


def classify_bp(bp, reaction_ids: set[int]) -> str:
    if reaction_ids and bp.type_id in reaction_ids:
        return BP_TYPE_REACTION

    quantity = bp.quantity
    if quantity == -2:
        return BP_TYPE_COPY
    if quantity == -1:
        return BP_TYPE_ORIGINAL
    if quantity and quantity > 0:
        return BP_TYPE_STACK

    name = (bp.type_name or "").lower()
    if "formula" in name or "reaction" in name:
        return BP_TYPE_REACTION

    return BP_TYPE_ORIGINAL


def populate_bp_type(apps, schema_editor):
    Blueprint = apps.get_model("indy_hub", "Blueprint")

    try:
        EveIndustryActivityProduct = apps.get_model(
            "eveuniverse", "EveIndustryActivityProduct"
        )
    except LookupError:
        EveIndustryActivityProduct = None

    reaction_ids: set[int] = set()
    if EveIndustryActivityProduct is not None:
        reaction_ids = set(
            EveIndustryActivityProduct.objects.filter(
                activity_id__in=[9, 11]
            ).values_list("eve_type_id", flat=True)
        )

    to_update: list = []
    batch_size = 500
    for bp in Blueprint.objects.all().iterator():
        desired_type = classify_bp(bp, reaction_ids)
        if bp.bp_type != desired_type:
            bp.bp_type = desired_type
            to_update.append(bp)
        if len(to_update) >= batch_size:
            Blueprint.objects.bulk_update(to_update, ["bp_type"])
            to_update.clear()

    if to_update:
        Blueprint.objects.bulk_update(to_update, ["bp_type"])


class Migration(migrations.Migration):

    dependencies = [
        ("indy_hub", "0020_charactersettings_sharing_scope"),
    ]

    operations = [
        migrations.AlterModelTable(
            name="blueprint",
            table="indy_hub_indyblueprint",
        ),
        migrations.AddField(
            model_name="blueprint",
            name="bp_type",
            field=models.CharField(
                choices=[
                    (BP_TYPE_REACTION, "Reaction"),
                    (BP_TYPE_ORIGINAL, "Original"),
                    (BP_TYPE_COPY, "Copy"),
                    (BP_TYPE_STACK, "Stack"),
                ],
                default=BP_TYPE_ORIGINAL,
                max_length=16,
            ),
        ),
        migrations.RunPython(populate_bp_type, migrations.RunPython.noop),
    ]
