from decimal import Decimal

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 ShipperProfile, TransporterProfile, UserRole, Vehicle
from core.models import Bid, Shipment, Trip

User = get_user_model()


class ShipperTripsListPayloadTests(TestCase):
    def setUp(self):
        self.shipper = User.objects.create_user(
            'ship-trips@test.com', email='ship-trips@test.com', password='secret',
        )
        UserRole.objects.create(user=self.shipper, role=UserRole.Role.SHIPPER, phone='111', language='en')
        ShipperProfile.objects.create(user=self.shipper, account_type=ShipperProfile.AccountType.INDIVIDUAL)

        self.owner = User.objects.create_user(
            'fleet-trips@test.com', email='fleet-trips@test.com', password='secret',
            first_name='Fleet', last_name='Owner',
        )
        UserRole.objects.create(user=self.owner, role=UserRole.Role.TRANSPORTER, phone='222', language='en')
        TransporterProfile.objects.create(
            user=self.owner,
            account_type=TransporterProfile.AccountType.FLEET_OWNER,
            company_name='Fleet Co',
            documents_verified=True,
            local=True,
        )

        self.driver = User.objects.create_user(
            'drv-trips@test.com', email='drv-trips@test.com', password='secret',
            first_name='Trip', last_name='Driver',
        )
        UserRole.objects.create(user=self.driver, role=UserRole.Role.TRANSPORTER, phone='333', language='en')
        TransporterProfile.objects.create(
            user=self.driver,
            account_type=TransporterProfile.AccountType.TRANSPORTER_DRIVER,
            documents_verified=True,
            local=True,
        )

        Vehicle.objects.create(
            owner=self.owner,
            assigned_driver=self.driver,
            vehicle_type='Flat Bed 12m',
            vehicle_types=['Flat Bed 12m'],
            registration_number='TRIPS-1',
            load_capacity=Decimal('5000'),
            is_verified=True,
            is_active=True,
        )

        self.shipment = Shipment.objects.create(
            shipper=self.shipper,
            pickup_address='Karachi Port',
            pickup_company='Acme Pickup',
            pickup_lat=Decimal('24.8607000'),
            pickup_lon=Decimal('67.0011000'),
            pickup_country_code='PK',
            delivery_address='Lahore Depot Rd',
            dropoff_company='Acme Drop',
            delivery_lat=Decimal('31.5204000'),
            delivery_lon=Decimal('74.3587000'),
            delivery_country_code='PK',
            cargo_type='Electronics',
            weight='500 kg',
            vehicle_type_required='Flat Bed 12m',
            distance_km=Decimal('1250.00'),
            status=Shipment.Status.ASSIGNED,
            local=True,
        )
        bid = Bid.objects.create(
            shipment=self.shipment,
            transporter=self.owner,
            amount=Decimal('4500.00'),
            status=Bid.Status.ACCEPTED,
        )
        self.trip = Trip.objects.create(
            shipment=self.shipment,
            accepted_bid=bid,
            transporter=self.owner,
            assigned_driver=self.driver,
            status=Trip.Status.ASSIGNED,
            agreed_price=Decimal('4500.00'),
        )

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

    def test_list_returns_pickup_dropoff_transporter_and_driver(self):
        response = self.client.get('/api/shipper/trips/')
        self.assertEqual(response.status_code, 200)
        row = response.json()['data'][0]

        self.assertEqual(row['pickup']['address'], 'Karachi Port')
        self.assertEqual(row['pickup']['company'], 'Acme Pickup')
        self.assertEqual(row['pickup']['country_code'], 'PK')
        self.assertEqual(row['dropoff']['address'], 'Lahore Depot Rd')
        self.assertEqual(row['dropoff']['company'], 'Acme Drop')

        self.assertEqual(row['transporter']['id'], self.owner.id)
        self.assertEqual(row['transporter']['account_type'], 'FLEET_OWNER')
        self.assertEqual(row['transporter']['company_name'], 'Fleet Co')
        self.assertEqual(row['transporter']['phone'], '222')

        self.assertEqual(row['assigned_driver']['id'], self.driver.id)
        self.assertEqual(row['assigned_driver']['email'], 'drv-trips@test.com')
        self.assertEqual(row['individual_driver']['id'], self.driver.id)

        self.assertEqual(row['cargo_type'], 'Electronics')
        self.assertEqual(row['weight'], '500 kg')
        self.assertEqual(row['vehicle_type_required'], 'Flat Bed 12m')
        self.assertIsNotNone(row['created_at'])
        self.assertIsNotNone(row['updated_at'])
        self.assertIn('status_timeline', row)
        self.assertEqual(row['assigned_vehicle']['registration_number'], 'TRIPS-1')

    def test_detail_returns_transporter_object_and_route_summaries(self):
        response = self.client.get(f'/api/shipper/trips/{self.trip.id}/')
        self.assertEqual(response.status_code, 200)
        data = response.json()['data']
        self.assertEqual(data['transporter']['id'], self.owner.id)
        self.assertEqual(data['assigned_driver']['id'], self.driver.id)
        self.assertEqual(data['individual_driver']['id'], self.driver.id)
        self.assertEqual(data['pickup']['address'], 'Karachi Port')
        self.assertEqual(data['dropoff']['address'], 'Lahore Depot Rd')
