# -*- coding: utf-8 -*-
# Generated by Django 1.11.1 on 2017-05-26 17:55
from __future__ import unicode_literals

from datetime import date

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


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("Converting member.Referencing #{} to member.Relationship...".format(ref.pk))
        # 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("Converting member.EmergencyContact #{} to member.Relationship...".format(emgc.pk))
        # 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("Reversing member.Relationship #{} to member.Referencing...".format(rel.pk))
            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("Reversing member.Relationship #{} to member.EmergencyContact...".format(rel.pk))
            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=set([('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',
        ),
    ]
