"""
Find stockrecords that have allocations that do not match the unshipped order lines
"""

from django.core.management.base import BaseCommand
from django.db import models
from django.db.models.functions import Coalesce

from oscar.core.loading import get_model

from ocyan.plugin.oscar_shipping.shipping.constants import SHIPPING_EVENT_SHIPPED

ShippingEventType = get_model("order", "ShippingEventType")
StockRecord = get_model("partner", "StockRecord")
Line = get_model("order", "Line")


class Command(BaseCommand):
    help = __doc__

    def add_arguments(self, parser):
        parser.add_argument(
            "--no-dry-run", action="store_true", help="Really commit to the database"
        )
        parser.add_argument(
            "--ask", action="store_true", help="Ask for updating allocations"
        )
        parser.add_argument(
            "--shipping-event-code",
            default=SHIPPING_EVENT_SHIPPED,
            help="To check for a certain shipping event, specify the code",
        )

    def handle(self, *args, **options):
        et = ShippingEventType.objects.get(code=options["shipping_event_code"])

        lines_with_unshipped_items = Line.objects.filter(
            shipping_event_quantities__event__event_type=et,
            stockrecord=models.OuterRef("pk"),
        ).annotate(
            quantity_shipped=Coalesce(
                models.Sum("shipping_event_quantities__quantity"), 0
            ),
            total_quantity=models.Sum("quantity"),
            total_unshipped_quantity=models.F("total_quantity")
            - models.F("quantity_shipped"),
        )

        for sr in StockRecord.objects.annotate(
            total_unshipped_quantity=models.Subquery(
                lines_with_unshipped_items.values("total_unshipped_quantity")[:1]
            ),
        ).filter(~models.Q(total_unshipped_quantity=Coalesce("num_allocated", 0))):
            if sr.product.get_product_class().track_stock:
                self.stdout.write(
                    self.style.ERROR(
                        "Dit product heeft niet dezelfde aantal openstaande order items dan er allocated is %s, open: %i, allocated: %i"
                        % (sr, sr.total_unshipped_quantity, sr.num_allocated)
                    )
                )
                if options["no_dry_run"]:
                    sr.num_allocated = sr.total_unshipped_quantity
                    sr.save()
                elif options["ask"]:
                    result = input("Wil je je de allocated updaten? (y/n) ")
                    if result.lower() == "y":
                        sr.num_allocated = sr.total_unshipped_quantity
                        sr.save()
