# Generated by Django 1.11.1 on 2017-05-26 17:55

from datetime import date

import annoying.fields
import django.db.models.deletion
from django.core.exceptions import ObjectDoesNotExist
from django.db import migrations, models


def migrate_relationships(apps, schema_editor):
    """
    Referencing --> Relationship
    EmergencyContact --> Relationship
    """
    Relationship = apps.get_model("member", "Relationship")
    Referencing = apps.get_model("member", "Referencing")
    EmergencyContact = apps.get_model("member", "EmergencyContact")

    from souschef.member.models import Relationship as _ref_Relationship  # noqa

    for ref in Referencing.objects.all().order_by("pk"):
        print(
            f"Converting member.Referencing #{ref.pk} to member.Relationship..."
        )
        # Attention: the Rel object may exist because a member can be both Ref and Emgc
        try:
            rel = Relationship.objects.get(member=ref.referent, client=ref.client)
        except ObjectDoesNotExist:
            rel = Relationship(member=ref.referent, client=ref.client, type=[])

        if _ref_Relationship.REFERENT not in rel.type:
            rel.type.append(_ref_Relationship.REFERENT)
        rel.nature = rel.nature or "??? (migration 0032)"
        rel.extra_fields = rel.extra_fields or {}
        rel.extra_fields["referral_date"] = ref.date
        rel.extra_fields["referral_reason"] = ref.referral_reason
        rel.save()

    for emgc in EmergencyContact.objects.all().order_by("pk"):
        print(
            f"Converting member.EmergencyContact #{emgc.pk} to member.Relationship..."
        )
        # Attention: the Rel object may exist because a member can be both Ref and Emgc
        try:
            rel = Relationship.objects.get(member=emgc.member, client=emgc.client)
        except ObjectDoesNotExist:
            rel = Relationship(member=emgc.member, client=emgc.client, type=[])

        if _ref_Relationship.EMERGENCY not in rel.type:
            rel.type.append(_ref_Relationship.EMERGENCY)
        rel.nature = emgc.relationship or rel.nature or "??? (migration 0032)"
        rel.save()

    print(
        "All converted. Deleting all member.Referencing and "
        "member.EmergencyContact objects..."
    )
    Referencing.objects.all().delete()
    EmergencyContact.objects.all().delete()


def reverse_migrate_relationships(apps, schema_editor):
    """
    Relationship --> Referencing / Emergency Contact
    """
    Relationship = apps.get_model("member", "Relationship")
    Referencing = apps.get_model("member", "Referencing")
    EmergencyContact = apps.get_model("member", "EmergencyContact")

    from souschef.member.models import Relationship as _ref_Relationship  # noqa

    for rel in Relationship.objects.all().order_by("pk"):
        if _ref_Relationship.REFERENT in rel.type:
            print(
                f"Reversing member.Relationship #{rel.pk} to member.Referencing..."
            )
            try:
                ref = Referencing.objects.get(referent=rel.member, client=rel.client)
            except Referencing.DoesNotExist:
                ref = Referencing(
                    referent=rel.member,
                    client=rel.client,
                    referral_reason="??? (reverse migration 0032)",
                    date=date(1970, 1, 1),
                )

            if isinstance(rel.extra_fields, dict):
                ref.referral_reason = rel.extra_fields.get(
                    "referral_reason", ref.referral_reason
                )
                ref.date = rel.extra_fields.get("referral_date", ref.date)
            ref.save()

        if _ref_Relationship.EMERGENCY in rel.type:
            print(
                f"Reversing member.Relationship #{rel.pk} to "
                "member.EmergencyContact..."
            )
            try:
                emgc = EmergencyContact.objects.get(
                    member=rel.member, client=rel.client
                )
            except EmergencyContact.DoesNotExist:
                emgc = EmergencyContact(member=rel.member, client=rel.client)
            emgc.relationship = rel.nature
            emgc.save()

    print("All reversed. Deleting all member.Relationship objects...")
    Relationship.objects.all().delete()


class Migration(migrations.Migration):
    dependencies = [
        ("member", "0031_client_option_allow_reverse_relation"),
    ]

    operations = [
        # Add Relationship
        migrations.CreateModel(
            name="Relationship",
            options={"verbose_name_plural": "relationships"},
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("nature", models.CharField(max_length=100)),
                ("type", annoying.fields.JSONField(default=[])),
                ("extra_fields", annoying.fields.JSONField(default={})),
                ("remark", models.TextField()),
                (
                    "client",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE, to="member.Client"
                    ),
                ),
                (
                    "member",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE, to="member.Member"
                    ),
                ),
            ],
        ),
        migrations.AlterUniqueTogether(
            name="relationship",
            unique_together={("client", "member")},
        ),
        # Migrate
        migrations.RunPython(migrate_relationships, reverse_migrate_relationships),
        # Delete Referencing and EmergencyContact
        migrations.AlterUniqueTogether(
            name="emergencycontact",
            unique_together=set(),
        ),
        migrations.RemoveField(
            model_name="emergencycontact",
            name="client",
        ),
        migrations.RemoveField(
            model_name="emergencycontact",
            name="member",
        ),
        migrations.RemoveField(
            model_name="referencing",
            name="client",
        ),
        migrations.RemoveField(
            model_name="referencing",
            name="referent",
        ),
        migrations.RemoveField(
            model_name="client",
            name="emergency_contacts",
        ),
        migrations.DeleteModel(
            name="EmergencyContact",
        ),
        migrations.DeleteModel(
            name="Referencing",
        ),
    ]
