"""Create one repeatable sample invoice in an existing branch."""
from datetime import timedelta
from decimal import Decimal

from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.utils import timezone
from rest_framework.test import APIRequestFactory, force_authenticate

from shop_management.models.data.customer import Customer
from shop_management.models.data.inventory import InventoryBatch
from shop_management.models.data.organization import CompanySetting, Warehouse
from shop_management.models.data.product import Product
from shop_management.models.data.sale import Sale
from shop_management.models.data.shop import Shop
from shop_management.models.data.utils import Currency, Unit
from shop_management.services.inventory import receive_stock
from shop_management.views.data.sale import SaleViewSet


class Command(BaseCommand):
    help = "Seed one sample sale, customer, and product stock in Main (or --shop ID). Safe to rerun."

    def add_arguments(self, parser):
        parser.add_argument("--sector", choices=["poultry", "agriculture"], default="poultry", help="Sample product sector.")
        parser.add_argument("--shop", type=int, default=1, help="Existing branch ID (default: 1, Main).")

    @transaction.atomic
    def handle(self, *args, **options):
        try:
            shop = Shop.objects.select_for_update().select_related("owner").get(pk=options["shop"])
        except Shop.DoesNotExist as exc:
            raise CommandError("Branch does not exist.") from exc
        marker = "Sample invoice created by seed_sample_sale."
        existing = Sale.objects.filter(shop=shop, notes=marker).first()
        if existing:
            self.stdout.write(f"Sample sale already exists: {existing.sale_number or existing.pk}")
            return
        setting = CompanySetting.objects.filter(shop=shop).first()
        currency = setting.base_currency if setting else Currency.objects.filter(shop=shop).first()
        if not currency:
            raise CommandError("Configure a branch currency before seeding a sale.")
        user = shop.owner
        warehouse, _ = Warehouse.objects.get_or_create(
            shop=shop, code="SAMPLE", defaults={"name": "Sample Warehouse", "created_by": user},
        )
        if not warehouse.is_active:
            raise CommandError("The sample warehouse is inactive.")
        unit, _ = Unit.objects.get_or_create(shop=shop, title="Piece", defaults={"created_by": user})
        customer, _ = Customer.objects.get_or_create(
            shop=shop, name="Sample Agriculture Customer" if options["sector"] == "agriculture" else "Sample Poultry Customer",
            defaults={"address": "Jalalabad — sample customer", "created_by": user},
        )
        items = []
        sample_products = [
            ("SEED-FERTILIZER", "Sample Agriculture Fertilizer", "300", "500", 2),
            ("SEED-SPRAYER", "Sample Agriculture Hand Sprayer", "200", "350", 3),
            ("SEED-AGRI-GLOVES", "Sample Agriculture Gloves", "120", "220", 1),
        ] if options["sector"] == "agriculture" else [
            ("SEED-VACCINE", "Sample Poultry Vaccine", "300", "500", 2),
            ("SEED-VITAMIN", "Sample Poultry Vitamins", "200", "350", 3),
            ("SEED-GLOVES", "Sample Medical Gloves", "120", "220", 1),
        ]
        for code, name, cost, price, quantity in sample_products:
            product, _ = Product.objects.get_or_create(
                shop=shop, code=code,
                defaults={"name": name, "default_unit": unit, "created_by": user},
            )
            if not product.default_unit_id:
                raise CommandError(f"Sample product {code} has no default unit.")
            batch, _ = InventoryBatch.objects.get_or_create(
                product=product, batch_number="SAMPLE-001",
                defaults={"expiry_date": timezone.localdate() + timedelta(days=365), "created_by": user},
            )
            receive_stock(
                warehouse=warehouse, product=product, batch=batch, quantity=20,
                unit_cost=Decimal(cost), currency=currency,
                reference_type="SampleSeed", reference_id=f"{shop.pk}:{code}",
                remarks=marker, created_by=user,
            )
            items.append({"product": product.pk, "unit": product.default_unit_id, "quantity": quantity, "sale_price": price})
        payload = {
            "shop": shop.pk, "warehouse": warehouse.pk, "currency": currency.pk,
            "customer": customer.pk, "sales_type": "CREDIT",
            "invoice_date": str(timezone.localdate()), "received_amount": "0",
            "discount_type": "FIXED", "discount_value": "0",
            "complete_immediately": True, "notes": marker, "items": items,
        }
        request = APIRequestFactory().post("/api/shop/sales/", payload, format="json")
        force_authenticate(request, user=user)
        response = SaleViewSet.as_view({"post": "create"})(request)
        if response.status_code != 201:
            raise CommandError(f"Sample sale could not be created: {response.data}")
        sale = Sale.objects.get(pk=response.data["id"])
        if sale.document_status != Sale.DocumentStatus.POSTED:
            raise CommandError("Sample sale was not posted; seed rolled back.")
        self.stdout.write(self.style.SUCCESS(
            f"Created {sale.sale_number} in {shop.name}: {sale.calculated_total} {currency.title}, "
            f"{sale.sale_items.count()} items. Invoice: /shop/sales/{sale.pk}/invoice/"
        ))
