from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse

from accounts.forms import DeliveryPreferencesForm

User = get_user_model()


class AccountRegistrationTests(TestCase):
    def test_registration_creates_profile_with_delivery_location(self):
        response = self.client.post(
            reverse('register'),
            {
                'username': 'newbuyer',
                'first_name': 'New',
                'last_name': 'Buyer',
                'email': 'newbuyer@example.com',
                'password': 'strongpass123',
                'confirm_password': 'strongpass123',
                'phone': '+9779800000001',
                'location_label': 'Boudha, Kathmandu',
                'default_address': 'Boudha Stupa Gate\nKathmandu',
                'latitude': '27.721900',
                'longitude': '85.361100',
                'location_accuracy_m': '14.50',
            },
        )

        self.assertEqual(response.status_code, 302)
        self.assertEqual(response['Location'], reverse('login'))

        user = User.objects.get(username='newbuyer')
        self.assertEqual(user.first_name, 'New')
        self.assertEqual(user.last_name, 'Buyer')
        self.assertEqual(user.profile.phone, '+9779800000001')
        self.assertEqual(user.profile.location_label, 'Boudha, Kathmandu')
        self.assertEqual(user.profile.default_address, 'Boudha Stupa Gate\nKathmandu')
        self.assertIsNotNone(user.profile.latitude)
        self.assertIsNotNone(user.profile.longitude)
        self.assertIsNotNone(user.profile.location_updated_at)

    def test_registration_defaults_location_label_from_address_when_blank(self):
        self.client.post(
            reverse('register'),
            {
                'username': 'autolabel',
                'first_name': 'Auto',
                'last_name': 'Label',
                'email': 'autolabel@example.com',
                'password': 'strongpass123',
                'confirm_password': 'strongpass123',
                'phone': '+9779800000002',
                'location_label': '',
                'default_address': 'Imadol Height\nLalitpur',
            },
        )

        user = User.objects.get(username='autolabel')
        self.assertEqual(user.profile.location_label, 'Imadol Height')

    def test_registration_requires_phone_and_address(self):
        response = self.client.post(
            reverse('register'),
            {
                'username': 'missinglocation',
                'password': 'strongpass123',
                'confirm_password': 'strongpass123',
                'phone': '',
                'default_address': '',
            },
        )

        self.assertEqual(response.status_code, 200)
        self.assertContains(response, 'Please correct the highlighted fields and try again.')
        self.assertFalse(User.objects.filter(username='missinglocation').exists())


class DeliveryPreferencesFormTests(TestCase):
    def test_saving_manual_address_clears_stale_gps_from_profile(self):
        user = User.objects.create_user(username='gpsuser', password='password123')
        profile = user.profile
        profile.phone = '+9779811111111'
        profile.location_label = 'Old Baneshwor'
        profile.default_address = 'Old Address\nKathmandu'
        profile.latitude = '27.700000'
        profile.longitude = '85.300000'
        profile.location_accuracy_m = '9.50'
        profile.save()

        form = DeliveryPreferencesForm(
            data={
                'phone': '+9779801234567',
                'location_label': 'Manual only',
                'default_address': 'New Road\nBhaktapur',
            },
            instance=profile,
        )

        self.assertTrue(form.is_valid(), form.errors)
        form.save()
        profile.refresh_from_db()

        self.assertEqual(profile.phone, '+9779801234567')
        self.assertEqual(profile.default_address, 'New Road\nBhaktapur')
        self.assertIsNone(profile.latitude)
        self.assertIsNone(profile.longitude)
        self.assertIsNone(profile.location_accuracy_m)
        self.assertIsNone(profile.location_updated_at)
