from unittest.mock import patch

from django.contrib.auth import get_user_model
from django.test import TestCase
from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient

from accounts.models import TransporterDriverLink, TransporterProfile, UserRole

User = get_user_model()


class FleetDriverCurrentLocationApiTests(TestCase):
    def setUp(self):
        self.fleet_owner = User.objects.create_user(
            'fleet-loc-owner@test.com',
            email='fleet-loc-owner@test.com',
            password='secret',
        )
        UserRole.objects.create(
            user=self.fleet_owner,
            role=UserRole.Role.TRANSPORTER,
            phone='',
            language='en',
        )
        TransporterProfile.objects.create(
            user=self.fleet_owner,
            account_type=TransporterProfile.AccountType.FLEET_OWNER,
            local=True,
            country_to_country=False,
            documents_verified=True,
        )

        self.fleet_driver = User.objects.create_user(
            'fleet-loc-driver@test.com',
            email='fleet-loc-driver@test.com',
            password='secret',
        )
        UserRole.objects.create(
            user=self.fleet_driver,
            role=UserRole.Role.TRANSPORTER,
            phone='555-0100',
            language='en',
        )
        self.driver_profile = TransporterProfile.objects.create(
            user=self.fleet_driver,
            account_type=TransporterProfile.AccountType.TRANSPORTER_DRIVER,
            local=True,
            country_to_country=False,
            documents_verified=True,
            tc_id='driver-device-42',
            tc_u_id='DRV42',
        )
        TransporterDriverLink.objects.create(
            transporter=self.fleet_owner,
            driver=self.fleet_driver,
            is_active=True,
        )

        self.other_driver = User.objects.create_user(
            'fleet-loc-other@test.com',
            email='fleet-loc-other@test.com',
            password='secret',
        )
        UserRole.objects.create(
            user=self.other_driver,
            role=UserRole.Role.TRANSPORTER,
            phone='',
            language='en',
        )
        TransporterProfile.objects.create(
            user=self.other_driver,
            account_type=TransporterProfile.AccountType.TRANSPORTER_DRIVER,
            local=True,
            country_to_country=False,
            documents_verified=True,
            tc_id='other-device',
        )

        token, _ = Token.objects.get_or_create(user=self.fleet_owner)
        self.client = APIClient()
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token.key}')

    def _url(self, driver_id):
        return f'/api/transporter/drivers/{driver_id}/current-location/'

    @patch('api.views.get_latest_device_position')
    def test_returns_driver_current_location(self, mock_latest_position):
        mock_latest_position.return_value = {
            'latitude': 25.2048,
            'longitude': 55.2708,
            'raw': {
                'id': 99,
                'deviceId': 42,
                'fixTime': '2026-07-27T10:00:00.000Z',
            },
        }

        r = self.client.get(self._url(self.fleet_driver.id))

        self.assertEqual(r.status_code, 200)
        data = r.json()['data']
        self.assertEqual(data['driver']['id'], self.fleet_driver.id)
        self.assertEqual(data['driver']['email'], self.fleet_driver.email)
        self.assertEqual(data['tc_id'], 'driver-device-42')
        self.assertEqual(data['tc_u_id'], 'DRV42')
        self.assertEqual(data['position']['lat'], 25.2048)
        self.assertEqual(data['position']['lon'], 55.2708)
        self.assertEqual(data['recorded_at'], '2026-07-27T10:00:00.000Z')
        mock_latest_position.assert_called_once_with('driver-device-42')

    def test_returns_404_for_unlinked_driver(self):
        r = self.client.get(self._url(self.other_driver.id))
        self.assertEqual(r.status_code, 404)
        self.assertEqual(r.json()['error'], 'Not found.')

    def test_returns_400_when_tc_id_missing(self):
        self.driver_profile.tc_id = ''
        self.driver_profile.save(update_fields=['tc_id'])

        r = self.client.get(self._url(self.fleet_driver.id))

        self.assertEqual(r.status_code, 400)
        self.assertEqual(r.json()['error'], 'Missing tc_id on driver profile.')

    def test_returns_404_for_inactive_link(self):
        TransporterDriverLink.objects.filter(
            transporter=self.fleet_owner,
            driver=self.fleet_driver,
        ).update(is_active=False)

        r = self.client.get(self._url(self.fleet_driver.id))
        self.assertEqual(r.status_code, 404)
