from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models import Q

from shop_management.models.data.stock import Stock
from shop_management.models.data.stock_transfer import StockTransfer
from shop_management.views.data.stock import StockTransferViewSet


class Command(BaseCommand):
    help = (
        "For Payment-OFF accepted transfers: remove 'Transfer from …' supplier "
        "from destination stock and merge duplicate same-name stock rows."
    )

    def add_arguments(self, parser):
        parser.add_argument(
            "--shop",
            type=int,
            help="Only repair destination shop id (e.g. Takhar Branch).",
        )
        parser.add_argument(
            "--product-name",
            type=str,
            help="Only repair products whose name contains this text.",
        )
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="Show what would change without writing.",
        )

    def handle(self, *args, **options):
        shop_id = options.get("shop")
        product_name = (options.get("product_name") or "").strip()
        dry_run = options.get("dry_run")

        qs = (
            StockTransfer.objects.filter(
                status=StockTransfer.Status.ACCEPTED,
                show_payment_button=False,
                target_stock__isnull=False,
                target_stock__is_deleted=False,
            )
            .select_related(
                "product",
                "currency",
                "supplier_branch",
                "customer_branch",
                "target_stock",
                "target_stock__purchase_item",
                "target_stock__purchase_item__purchase",
                "target_stock__purchase_item__purchase__supplier",
                "target_stock__purchase_item__product",
                "source_stock",
                "accepted_by",
                "created_by",
            )
            .order_by("id")
        )
        if shop_id:
            qs = qs.filter(customer_branch_id=shop_id)
        if product_name:
            qs = qs.filter(
                Q(product__name__icontains=product_name)
                | Q(target_stock__purchase_item__product__name__icontains=product_name)
            )

        view = StockTransferViewSet()
        fixed = 0
        skipped = 0

        for transfer in qs:
            target = transfer.target_stock
            if not target:
                skipped += 1
                continue

            has_transfer_supplier = view._is_transfer_supplier(
                getattr(getattr(target, "purchase_item", None), "purchase", None)
            )
            destination_product = view._resolve_destination_product(
                transfer,
                user=transfer.accepted_by or transfer.created_by,
            )
            transfer_currency = view._resolve_shop_currency(
                transfer.customer_branch_id,
                transfer.currency or (target.currency if target else None),
                user=transfer.accepted_by or transfer.created_by,
                create=False,
            )
            siblings = Stock.objects.filter(
                shop_id=transfer.customer_branch_id,
                is_deleted=False,
            ).exclude(pk=target.pk)
            if transfer_currency:
                currency_ids = view._matching_currency_ids(
                    transfer.customer_branch_id, transfer_currency
                )
                if currency_ids:
                    siblings = view._filter_stock_by_currency_ids(siblings, currency_ids)
            product = destination_product or transfer.product
            if product:
                siblings = siblings.filter(view._same_product_stock_filter(product))
            has_duplicates = siblings.exists()

            if not has_transfer_supplier and not has_duplicates:
                skipped += 1
                continue

            supplier_name = (
                target.purchase_item.purchase.supplier.name
                if has_transfer_supplier
                else "-"
            )
            self.stdout.write(
                f"TRF {transfer.transfer_id or transfer.id}: "
                f"{transfer.product.name if transfer.product else '?'} @ "
                f"{transfer.customer_branch.name if transfer.customer_branch else shop_id} "
                f"| supplier={supplier_name} | duplicates={siblings.count()} "
                f"| qty={target.quantity}"
            )

            if dry_run:
                fixed += 1
                continue

            with transaction.atomic():
                transfer = StockTransfer.objects.select_for_update().get(pk=transfer.pk)
                target = Stock.objects.select_for_update().filter(pk=transfer.target_stock_id).first()
                if not target:
                    skipped += 1
                    continue

                source_stock = transfer.source_stock
                destination_product = view._resolve_destination_product(
                    transfer,
                    user=transfer.accepted_by or transfer.created_by,
                )
                transfer_currency = view._resolve_shop_currency(
                    transfer.customer_branch_id,
                    transfer.currency or (source_stock.currency if source_stock else None),
                    user=transfer.accepted_by or transfer.created_by,
                    create=True,
                )
                transfer_unit = view._resolve_destination_unit(
                    transfer.customer_branch_id,
                    source_stock.unit if source_stock else None,
                    user=transfer.accepted_by or transfer.created_by,
                )
                transfer_buy_price = (
                    transfer.sale_price
                    if transfer.sale_price is not None
                    else (
                        (source_stock.sale_price or source_stock.retail_price or 0)
                        if source_stock
                        else 0
                    )
                )
                user = transfer.accepted_by or transfer.created_by

                target = view._ensure_stock_only_no_transfer_supplier(
                    target,
                    transfer,
                    destination_product,
                    transfer_currency,
                    transfer_unit,
                    transfer_buy_price,
                    source_stock,
                    user,
                )
                target = view._consolidate_duplicate_destination_stocks(
                    target,
                    transfer,
                    destination_product=destination_product,
                    destination_currency=transfer_currency,
                )
                target = view._ensure_stock_only_no_transfer_supplier(
                    target,
                    transfer,
                    destination_product,
                    transfer_currency,
                    transfer_unit,
                    transfer_buy_price,
                    source_stock,
                    user,
                )
                if transfer.target_stock_id != target.id:
                    transfer.target_stock = target
                    transfer.save(update_fields=["target_stock", "updated_at"])
                fixed += 1

        mode = "Would fix" if dry_run else "Fixed"
        self.stdout.write(self.style.SUCCESS(f"{mode} {fixed} transfer(s); skipped {skipped}."))
