from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase

from vbv_lernwelt.core.admin import User
from vbv_lernwelt.shop.models import BillingAddress


class BillingAddressViewTest(APITestCase):
    def setUp(self) -> None:
        self.user = User.objects.create_user(
            "testuser", "test@example.com", "testpassword"
        )
        self.client.login(username="testuser", password="testpassword")

        self.billing_address = BillingAddress.objects.create(
            user=self.user,
            first_name="John",
            last_name="Doe",
            street="123 Main St",
            street_number="45A",
            postal_code="12345",
            city="Test City",
            country="Test Country",
            company_name="Test Company",
            company_street="456 Company St",
            company_street_number="67B",
            company_postal_code="67890",
            company_city="Company City",
            company_country="Company Country",
        )

    def test_get_billing_address(self) -> None:
        # GIVEN
        # user is logged in and has a billing address

        # WHEN
        url = reverse("get-billing-address")
        response = self.client.get(url)

        # THEN
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data["first_name"], "John")
        self.assertEqual(response.data["last_name"], "Doe")
        self.assertEqual(response.data["street"], "123 Main St")
        self.assertEqual(response.data["street_number"], "45A")
        self.assertEqual(response.data["postal_code"], "12345")
        self.assertEqual(response.data["city"], "Test City")
        self.assertEqual(response.data["country"], "Test Country")
        self.assertEqual(response.data["company_name"], "Test Company")
        self.assertEqual(response.data["company_street"], "456 Company St")
        self.assertEqual(response.data["company_street_number"], "67B")
        self.assertEqual(response.data["company_postal_code"], "67890")
        self.assertEqual(response.data["company_city"], "Company City")
        self.assertEqual(response.data["company_country"], "Company Country")

    def test_update_billing_address(self) -> None:
        # GIVEN
        new_data = {
            "first_name": "Jane",
            "last_name": "Smith",
            "street": "789 New St",
            "street_number": "101C",
            "postal_code": "54321",
            "city": "New City",
            "country": "New Country",
            "company_name": "New Company",
            "company_street": "789 Company St",
            "company_street_number": "102D",
            "company_postal_code": "98765",
            "company_city": "New Company City",
            "company_country": "New Company Country",
        }

        # WHEN
        url = reverse("update-billing-address")
        response = self.client.put(url, new_data)

        # THEN
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        updated_address = BillingAddress.objects.get(user=self.user)
        self.assertEqual(updated_address.first_name, "Jane")
        self.assertEqual(updated_address.last_name, "Smith")
        self.assertEqual(updated_address.street, "789 New St")
        self.assertEqual(updated_address.street_number, "101C")
        self.assertEqual(updated_address.postal_code, "54321")
        self.assertEqual(updated_address.city, "New City")
        self.assertEqual(updated_address.country, "New Country")
        self.assertEqual(updated_address.company_name, "New Company")
        self.assertEqual(updated_address.company_street, "789 Company St")
        self.assertEqual(updated_address.company_street_number, "102D")
        self.assertEqual(updated_address.company_postal_code, "98765")
        self.assertEqual(updated_address.company_city, "New Company City")
        self.assertEqual(updated_address.company_country, "New Company Country")

    def test_unauthenticated_access(self) -> None:
        # GIVEN
        self.client.logout()

        # WHEN
        get_response = self.client.get(reverse("get-billing-address"))
        put_response = self.client.put(reverse("update-billing-address"), {})

        # THEN
        self.assertTrue(get_response["Location"], "/login/")
        self.assertTrue(put_response["Location"], "/login/")
