from django.db import migrations, models


def forwards(apps, schema_editor):
    Condition = apps.get_model("atlas", "Condition")
    # Build connected components using existing M2M 'synonym' links
    visited = set()

    for cond in Condition.objects.all():
        if cond.pk in visited:
            continue
        # BFS/DFS to collect component
        stack = [cond]
        comp = []
        while stack:
            c = stack.pop()
            if c.pk in visited:
                continue
            visited.add(c.pk)
            comp.append(c)
            # access existing M2M relations
            for s in c.synonym.all():
                if s.pk not in visited:
                    stack.append(s)

        # choose canonical: prefer primary==True else lowest pk
        canon = None
        for c in comp:
            if getattr(c, "primary", False):
                canon = c
                break
        if not canon:
            canon = min(comp, key=lambda x: x.pk)

        # set canonical for all non-canonical members
        for c in comp:
            if c.pk != canon.pk:
                c.canonical_id = canon.pk
                c.save()


def backwards(apps, schema_editor):
    Condition = apps.get_model("atlas", "Condition")
    for c in Condition.objects.all():
        if c.canonical_id:
            c.canonical_id = None
            c.save()


class Migration(migrations.Migration):

    dependencies = [
        ("atlas", "0085_rename_case_detail_caseprior_casedetail_and_more"),
    ]

    operations = [
        migrations.AddField(
            model_name="condition",
            name="canonical",
            field=models.ForeignKey(
                related_name="aliases",
                null=True,
                on_delete=models.SET_NULL,
                to="atlas.condition",
                blank=True,
            ),
        ),
        migrations.RunPython(forwards, backwards),
    ]
