# Generated by Django 3.2.2 on 2021-05-18 13:57
from decimal import Decimal

from django.db import migrations


def populate_refund_amounts_in_fulfillments(apps, schema_editor):
    Order = apps.get_model("order", "Order")

    orders = Order.objects.filter(events__type="fulfillment_refunded")
    for order in orders.iterator():
        fulfillments = order.fulfillments.filter(
            status__in=["refunded", "refunded_and_returned"]
        )
        refunded_fulfillments = order.fulfillments.filter(status="refunded")
        refunded_and_replaced_fulfillments = order.fulfillments.filter(
            status="refunded_and_returned"
        )
        refunded_events = order.events.filter(type="fulfillment_refunded")
        refunded_events = [
            event for event in refunded_events if "lines" in event.parameters
        ]
        total_amount = sum(
            [Decimal(event.parameters.get("amount", 0)) for event in refunded_events]
        )
        included_shipping_costs = any(
            [
                event.parameters.get("shipping_costs_included", False)
                for event in refunded_events
            ]
        )

        fulfillment_count = fulfillments.count()
        refunded_events_count = len(refunded_events)
        if fulfillment_count == refunded_events_count:
            for fulfillment, event in zip(fulfillments, refunded_events):
                amount = event.parameters.get("amount") or 0
                included_shipping_costs = event.parameters.get(
                    "shipping_costs_included", False
                )
                fulfillment.total_refund_amount = amount
                if included_shipping_costs:
                    fulfillment.shipping_refund_amount = (
                        order.shipping_price_gross_amount
                    )
                fulfillment.save(
                    update_fields=["total_refund_amount", "shipping_refund_amount"]
                )
        elif (
            refunded_fulfillments.count() == 1
            and not refunded_and_replaced_fulfillments
        ):
            refunded_fulfillment = refunded_fulfillments.first()
            if included_shipping_costs:
                refunded_fulfillment.shipping_refund_amount = (
                    order.shipping_price_gross_amount
                )
            refunded_fulfillment.total_refund_amount = total_amount
            refunded_fulfillment.save(
                update_fields=["total_refund_amount", "shipping_refund_amount"]
            )
        elif (
            not refunded_fulfillments
            and refunded_and_replaced_fulfillments.count() == 1
        ):
            refunded_and_replaced_fulfillment = (
                refunded_and_replaced_fulfillments.first()
            )
            if included_shipping_costs:
                refunded_and_replaced_fulfillment.shipping_refund_amount = (
                    order.shipping_price_gross_amount
                )
            refunded_and_replaced_fulfillment.total_refund_amount = total_amount
            refunded_and_replaced_fulfillment.save(
                update_fields=["total_refund_amount", "shipping_refund_amount"]
            )
        else:
            fulfillment = fulfillments.first()
            if fulfillment:
                fulfillment.total_refund_amount = total_amount
                if included_shipping_costs:
                    fulfillment.shipping_refund_amount = (
                        order.shipping_price_gross_amount
                    )
                fulfillment.save(
                    update_fields=["total_refund_amount", "shipping_refund_amount"]
                )


class Migration(migrations.Migration):

    dependencies = [
        ("order", "0110_auto_20210518_0918"),
    ]

    operations = [
        migrations.RunPython(
            populate_refund_amounts_in_fulfillments, migrations.RunPython.noop
        )
    ]
