"""
Show why one product's stock qty is what it is.

Prints every stock row, purchase, sale, and transfer, and whether a
transfer purchase/sale is money-only (must not add qty again).

Example:

  python manage.py explain_stock_qty --shop-name "Takhar Branch" --product-name "SECTION FILTER"
  python manage.py explain_stock_qty --shop-name "Kabul Main Branch" --product-name "SECTION FILTER"
"""

from django.core.management.base import BaseCommand

from shop_management.management.commands.heal_stock_quantities import (
    Command as HealCommand,
    _is_transfer_sale,
    _is_transfer_supplier,
    _norm_name,
)
from shop_management.models.data.purchase import PurchaseItem
from shop_management.models.data.sale import SaleItem
from shop_management.models.data.shop import Shop
from shop_management.models.data.stock import Stock
from shop_management.models.data.stock_transfer import StockTransfer
from shop_management.views.data.stock import normalize_currency_code


class Command(BaseCommand):
    help = "Explain one product stock qty vs purchase / sale / transfer. Report only."

    def add_arguments(self, parser):
        parser.add_argument("--shop-name", required=True, type=str)
        parser.add_argument("--product-name", required=True, type=str)

    def handle(self, *args, **options):
        shop_name = (options.get("shop_name") or "").strip()
        product_name = (options.get("product_name") or "").strip()
        shop = Shop.objects.filter(name__iexact=shop_name).first()
        if not shop:
            shop = Shop.objects.filter(name__icontains=shop_name).first()
        if not shop:
            available = ", ".join(Shop.objects.values_list("name", flat=True))
            self.stderr.write(self.style.ERROR(f"Shop not found: {shop_name}. Available: {available}"))
            return

        key = _norm_name(product_name)
        healer = HealCommand()
        skip_ids = healer._transfer_generated_purchase_item_ids(shop)

        self.stdout.write(self.style.MIGRATE_HEADING(f"{shop.name} | {product_name}"))
        self.stdout.write("Transfer purchases/sales are money only. Qty must move once.")
        self.stdout.write("")

        buy = 0
        skipped_buy = 0
        self.stdout.write(self.style.NOTICE("PURCHASES"))
        items = (
            PurchaseItem.objects.filter(
                purchase__shop=shop,
                product__name__iexact=product_name,
                is_deleted=False,
                purchase__is_deleted=False,
            )
            .select_related("purchase", "purchase__supplier", "currency", "product")
            .order_by("purchase__purchase_date", "id")
        )
        if not items:
            self.stdout.write("  (none)")
        for item in items:
            supplier = getattr(getattr(item.purchase, "supplier", None), "name", "") or "--"
            qty = int(item.quantity or 0)
            date = item.purchase.purchase_date
            skipped = item.id in skip_ids or _is_transfer_supplier(supplier)
            if skipped:
                skipped_buy += qty
                tag = "SKIP money-only (do not add to stock again)"
            else:
                buy += qty
                tag = "COUNT as buy"
            self.stdout.write(f"  {date} | qty={qty} | {supplier} | {tag}")

        self.stdout.write("")
        self.stdout.write(self.style.NOTICE("SALES"))
        sold = 0
        skipped_sold = 0
        sales = (
            SaleItem.objects.filter(sale__shop=shop, product__name__iexact=product_name)
            .select_related("sale", "sale__customer", "product")
            .order_by("sale__sale_date", "id")
        )
        if not sales:
            self.stdout.write("  (none)")
        for item in sales:
            customer = getattr(getattr(item.sale, "customer", None), "name", "") or "--"
            qty = int(item.quantity or 0)
            date = item.sale.sale_date
            if _is_transfer_sale(item.sale):
                skipped_sold += qty
                tag = "SKIP money-only (do not remove from stock again)"
            else:
                sold += qty
                tag = "COUNT as sold"
            self.stdout.write(f"  {date} | qty={qty} | {customer} | {tag}")

        self.stdout.write("")
        self.stdout.write(self.style.NOTICE("TRANSFERS IN (this branch received)"))
        transfer_in = 0
        incoming = (
            StockTransfer.objects.filter(
                customer_branch=shop,
                status=StockTransfer.Status.ACCEPTED,
            )
            .select_related(
                "product",
                "supplier_branch",
                "target_stock__purchase_item__product",
            )
            .order_by("transfer_date", "id")
        )
        in_rows = []
        for transfer in incoming:
            name = healer._preferred_name(transfer, "in") or getattr(transfer.product, "name", "")
            if _norm_name(name) != key:
                continue
            qty = int(transfer.transfer_quantity or 0)
            transfer_in += qty
            in_rows.append(transfer)
            self.stdout.write(
                f"  {transfer.transfer_date} | qty={qty} | from {transfer.supplier_branch} "
                f"| Payment={'ON' if transfer.show_payment_button else 'OFF'}"
            )
        if not in_rows:
            self.stdout.write("  (none)")

        self.stdout.write("")
        self.stdout.write(self.style.NOTICE("TRANSFERS OUT (this branch sent)"))
        transfer_out = 0
        outgoing = (
            StockTransfer.objects.filter(
                supplier_branch=shop,
                status=StockTransfer.Status.ACCEPTED,
            )
            .select_related(
                "product",
                "customer_branch",
                "source_stock__purchase_item__product",
            )
            .order_by("transfer_date", "id")
        )
        out_rows = []
        for transfer in outgoing:
            name = healer._preferred_name(transfer, "out") or getattr(transfer.product, "name", "")
            if _norm_name(name) != key:
                continue
            qty = int(transfer.transfer_quantity or 0)
            transfer_out += qty
            out_rows.append(transfer)
            self.stdout.write(
                f"  {transfer.transfer_date} | qty={qty} | to {transfer.customer_branch} "
                f"| Payment={'ON' if transfer.show_payment_button else 'OFF'}"
            )
        if not out_rows:
            self.stdout.write("  (none)")

        self.stdout.write("")
        self.stdout.write(self.style.NOTICE("STOCK ROWS (what Stock page shows)"))
        stocks = (
            Stock.objects.filter(
                shop=shop,
                is_deleted=False,
                purchase_item__product__name__iexact=product_name,
            )
            .select_related(
                "purchase_item__product",
                "purchase_item__purchase__supplier",
                "purchase_item__currency",
                "purchase_item__purchase__currency",
            )
            .order_by("-quantity", "id")
        )
        current = 0
        if not stocks:
            self.stdout.write("  (none)")
        for stock in stocks:
            qty = int(stock.quantity or 0)
            current += qty
            currency = normalize_currency_code(
                stock.currency.title if stock.currency else ""
            ) or "?"
            supplier = getattr(
                getattr(getattr(stock.purchase_item, "purchase", None), "supplier", None),
                "name",
                "",
            ) or "--"
            hidden = " HIDDEN qty 0" if qty <= 0 else ""
            self.stdout.write(
                f"  #{stock.id} | qty={qty} | {currency} | {supplier}{hidden}"
            )

        should = buy + transfer_in - sold - transfer_out
        self.stdout.write("")
        self.stdout.write(self.style.MIGRATE_HEADING("RESULT"))
        self.stdout.write(f"  Real buy (not transfer purchase): {buy}")
        self.stdout.write(f"  Transfer purchase skipped (money only): {skipped_buy}")
        self.stdout.write(f"  Transfer IN: {transfer_in}")
        self.stdout.write(f"  Real sold (not transfer sale): {sold}")
        self.stdout.write(f"  Transfer sale skipped (money only): {skipped_sold}")
        self.stdout.write(f"  Transfer OUT: {transfer_out}")
        self.stdout.write(f"  Should be in stock: {buy} + {transfer_in} - {sold} - {transfer_out} = {should}")
        self.stdout.write(f"  Stock page total: {current}")
        if current == should:
            self.stdout.write(self.style.SUCCESS("  OK — qty counted once. Not duplicated."))
            if skipped_buy:
                self.stdout.write(
                    "  You still see a Purchase 'Transfer from …'. That is money, not a second stock qty."
                )
        elif current == should + transfer_in and transfer_in > 0:
            self.stdout.write(
                self.style.ERROR(
                    f"  DOUBLE — transfer IN {transfer_in} was added twice. "
                    f"Stock should be {should}, now {current}."
                )
            )
            self.stdout.write(
                f"  Fix with:\n"
                f'    python manage.py heal_stock_quantities --shop-name "{shop.name}" '
                f'--product-name "{product_name}" --exact --apply'
            )
        elif current > should:
            extra = current - should
            self.stdout.write(
                self.style.WARNING(
                    f"  HIGH — extra {extra} (opening leftover). Not a transfer double."
                )
            )
        else:
            self.stdout.write(
                self.style.WARNING(
                    f"  LOW — stock {current} is less than bills {should}."
                )
            )
            self.stdout.write(
                f"  Fix with:\n"
                f'    python manage.py heal_stock_quantities --shop-name "{shop.name}" '
                f'--product-name "{product_name}" --apply'
            )
