from datetime import timedelta

from django.contrib.auth import get_user_model
from django.test import TestCase
from django.utils import timezone
from rest_framework.test import APIClient

from shop_management.models.data.purchase import Purchase, PurchaseItem
from shop_management.models.data.purchase_return import PurchaseReturn, PurchaseReturnItem
from shop_management.models.data.shop import Shop
from shop_management.models.data.supplier import Supplier
from shop_management.models.data.supplier_payment import SupplierPayment, SupplierPaymentAllocation
from shop_management.models.data.shop_account import Account
from shop_management.models.data.utils import Currency


class PurchaseAnalysisReportTests(TestCase):
    def setUp(self):
        self.user = get_user_model().objects.create_user(username="purchase-report-user", password="x", is_staff=True)
        self.user.allowed_tabs = ["reports"]
        self.user.save(update_fields=["allowed_tabs"])
        self.shop = Shop.objects.create(owner=self.user, name="Kabul")
        self.currency = Currency.objects.create(shop=self.shop, title="AFN")
        self.supplier = Supplier.objects.create(shop=self.shop, name="Medical Supply")
        self.account = Account.objects.create(shop=self.shop, name="Cash", currency=self.currency)
        self.today = timezone.localdate()
        self.purchase = Purchase.objects.create(shop=self.shop, supplier=self.supplier, currency=self.currency, purchase_date=self.today, amount=100, exchange_rate_used=1, uses_inventory_engine=True, document_status="POSTED", purchase_number="KAB-PUR-1")
        self.item = PurchaseItem.objects.create(purchase=self.purchase, quantity=10, buy_price=100)
        returned = PurchaseReturn.objects.create(shop=self.shop, purchase=self.purchase, uses_inventory_engine=True, document_status="POSTED")
        PurchaseReturnItem.objects.create(purchase_return=returned, purchase_item=self.item, return_quantity=1, refund_amount=90)
        payment = SupplierPayment.objects.create(shop=self.shop, supplier=self.supplier, financial_account=self.account, currency=self.currency, amount=300, base_amount=300, status="POSTED", payment_date=self.today)
        SupplierPaymentAllocation.objects.create(payment=payment, purchase=self.purchase, allocated_amount=300)
        self.client = APIClient(); self.client.force_authenticate(self.user)

    def test_report_uses_posted_purchase_returns_and_allocations(self):
        response = self.client.get("/api/shop/purchase-analysis-report/", {"shop": self.shop.pk, "start_date": self.today - timedelta(days=1), "end_date": self.today})
        self.assertEqual(response.status_code, 200, response.data)
        self.assertEqual(response.data["summary"]["gross_purchases"], "900.00")
        self.assertEqual(response.data["summary"]["returns"], "90.00")
        self.assertEqual(response.data["summary"]["net_purchases"], "810.00")
        self.assertEqual(response.data["summary"]["paid"], "300.00")
        self.assertEqual(response.data["invoices"][0]["outstanding"], "510.00")

    def test_other_branch_is_rejected(self):
        other = get_user_model().objects.create_user(username="other")
        other_shop = Shop.objects.create(owner=other, name="Herat")
        response = self.client.get("/api/shop/purchase-analysis-report/", {"shop": other_shop.pk})
        self.assertEqual(response.status_code, 400)
