from datetime import date
from unittest.mock import create_autospec

from django.test import TestCase

from vbv_lernwelt.core.admin import User
from vbv_lernwelt.shop.invoice.abacus import AbacusInvoiceCreator
from vbv_lernwelt.shop.invoice.creator import Item
from vbv_lernwelt.shop.invoice.repositories import InvoiceRepository
from vbv_lernwelt.shop.models import CheckoutInformation

USER_USERNAME = "testuser"
USER_EMAIL = "test@example.com"
USER_PASSWORD = "testpassword"


class InvoiceTestCase(TestCase):
    def setUp(self) -> None:
        self.user = User.objects.create_user(
            username=USER_USERNAME,
            email=USER_EMAIL,
            password=USER_PASSWORD,
            is_active=True,
        )

    def test_render_invoice(self):
        # GIVEN
        creator = AbacusInvoiceCreator(repository=create_autospec(InvoiceRepository))
        items = [Item(product_number="001", quantity=1, description="Test Item")]
        customer_number = "12345"
        order_date = date(2023, 1, 1)
        reference_purchase_order = "PO12345678"
        unic_id = "UNIC001"

        # WHEN
        invoice_xml = creator.invoice_xml(
            customer_number,
            order_date,
            reference_purchase_order,
            unic_id,
            items,
        )

        # THEN
        assert "<CustomerNumber>12345</CustomerNumber>" in invoice_xml
        assert "<ItemNumber>1</ItemNumber>" in invoice_xml
        assert "<ProductNumber>001</ProductNumber>" in invoice_xml
        assert "<QuantityOrdered>1</QuantityOrdered>" in invoice_xml
        assert "<Text>Test Item</Text>" in invoice_xml

    def test_create_invoice_calls_upload(self):
        # GIVEN
        repository_mock = create_autospec(InvoiceRepository)

        creator = AbacusInvoiceCreator(repository=repository_mock)

        expected_filename = "test.xml"

        checkout_information = CheckoutInformation.objects.create(
            user=self.user,
            transaction_id="12345",
            product_sku="001",
            product_name="Test Product",
            product_description="Test Product Description",
            product_price=1000,
            state="initialized",
        )

        # WHEN
        creator.create_invoice(
            checkout_information=checkout_information,
            filename=expected_filename,
        )

        # THEN
        repository_mock.upload_invoice.assert_called_once()
        uploaded_invoice, uploaded_filename = repository_mock.upload_invoice.call_args[
            0
        ]

        assert uploaded_filename == expected_filename
        assert "<CustomerNumber>12345</CustomerNumber>" in uploaded_invoice
        assert "<ItemNumber>1</ItemNumber>" in uploaded_invoice
        assert "<ProductNumber>001</ProductNumber>" in uploaded_invoice
        assert "<QuantityOrdered>1</QuantityOrdered>" in uploaded_invoice
        assert "<Text>Test Product Description</Text>" in uploaded_invoice
