from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from rest_framework.test import APIClient

from basic_info import models as basic_models
from shipment import models as shipment_models


def tiny_gif(name='photo.gif'):
    return SimpleUploadedFile(
        name,
        (
            b'GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\xff\xff\xff!'
            b'\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00'
            b'\x00\x02\x02D\x01\x00;'
        ),
        content_type='image/gif',
    )


class ShipmentDeliveryPhotoV2APITest(TestCase):
    def setUp(self):
        self.client = APIClient()
        self.merchant = basic_models.Merchant.objects.create(
            name='送货照片商户',
            type=basic_models.MerchantTypeEnum.FACTORY,
        )
        self.other_merchant = basic_models.Merchant.objects.create(
            name='其他送货照片商户',
            type=basic_models.MerchantTypeEnum.FACTORY,
        )
        self.user = get_user_model().objects.create_user(username='shipment-photo-user', password='pass12345')
        self.employee = basic_models.Employee.objects.create(
            merchant=self.merchant,
            sys_user=self.user,
            name='送货照片员工',
        )
        self.customer = basic_models.Customer.objects.create(
            merchant=self.merchant,
            name='照片客户',
            mobile='13800138000',
        )
        self.other_customer = basic_models.Customer.objects.create(
            merchant=self.other_merchant,
            name='其他照片客户',
            mobile='13800138001',
        )
        self.delivery = shipment_models.ShipmentDelivery.objects.create(
            merchant=self.merchant,
            driver_name='张司机',
            vehicle_trip='TRIP-001',
            created_by=self.user,
        )
        self.other_delivery = shipment_models.ShipmentDelivery.objects.create(
            merchant=self.other_merchant,
            driver_name='李司机',
            vehicle_trip='TRIP-002',
            created_by=self.user,
        )
        self.shipment = shipment_models.Shipment.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            shipment_date='2026-04-28',
            created_by=self.user,
            delivery=self.delivery,
        )
        self.shipment2 = shipment_models.Shipment.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            shipment_date='2026-04-29',
            created_by=self.user,
            delivery=self.delivery,
        )
        self.other_shipment = shipment_models.Shipment.objects.create(
            merchant=self.other_merchant,
            customer=self.other_customer,
            shipment_date='2026-04-30',
            created_by=self.user,
            delivery=self.other_delivery,
        )
        self.client.force_authenticate(user=self.user)

    def test_create_shipment_delivery_photo_success(self):
        resp = self.client.post(
            '/api/v2/shipment-delivery-photos/',
            {
                'shipment': str(self.shipment.id),
                'delivery': str(self.delivery.id),
                'remark': '已送达',
                'photo': tiny_gif(),
            },
            format='multipart',
        )

        self.assertEqual(resp.status_code, 201)
        photo = shipment_models.ShipmentDeliveryPhoto.objects.get(id=resp.data['id'])
        self.assertEqual(photo.shipment_id, self.shipment.id)
        self.assertEqual(photo.delivery_id, self.delivery.id)
        self.assertEqual(photo.created_by_id, self.user.id)
        self.assertEqual(resp.data['shipment_id'], self.shipment.id)
        self.assertEqual(resp.data['delivery_id'], self.delivery.id)
        self.assertEqual(resp.data['remark'], '已送达')
        self.assertTrue(resp.data['photo'])

    def test_create_shipment_delivery_photo_rejects_delivery_mismatch(self):
        other_delivery_same_merchant = shipment_models.ShipmentDelivery.objects.create(
            merchant=self.merchant,
            driver_name='王司机',
            vehicle_trip='TRIP-003',
            created_by=self.user,
        )

        resp = self.client.post(
            '/api/v2/shipment-delivery-photos/',
            {
                'shipment': str(self.shipment.id),
                'delivery': str(other_delivery_same_merchant.id),
                'photo': tiny_gif('mismatch.gif'),
            },
            format='multipart',
        )

        self.assertEqual(resp.status_code, 400)
        self.assertIn('delivery', resp.data)

    def test_list_shipment_delivery_photos_supports_shipment_and_delivery_filters(self):
        photo1 = shipment_models.ShipmentDeliveryPhoto.objects.create(
            shipment=self.shipment,
            delivery=self.delivery,
            remark='第一张',
            photo=tiny_gif('one.gif'),
            created_by=self.user,
        )
        shipment_models.ShipmentDeliveryPhoto.objects.create(
            shipment=self.shipment2,
            delivery=self.delivery,
            remark='第二张',
            photo=tiny_gif('two.gif'),
            created_by=self.user,
        )

        resp = self.client.get(
            f'/api/v2/shipment-delivery-photos/?shipment_id={self.shipment.id}&delivery_id={self.delivery.id}'
        )

        self.assertEqual(resp.status_code, 200)
        self.assertEqual([item['id'] for item in resp.data], [photo1.id])

    def test_patch_shipment_delivery_photo_updates_remark(self):
        photo = shipment_models.ShipmentDeliveryPhoto.objects.create(
            shipment=self.shipment,
            delivery=self.delivery,
            remark='初始备注',
            photo=tiny_gif('patch.gif'),
            created_by=self.user,
        )

        resp = self.client.patch(
            f'/api/v2/shipment-delivery-photos/{photo.id}/',
            {'remark': '更新备注'},
            format='multipart',
        )

        self.assertEqual(resp.status_code, 200)
        photo.refresh_from_db()
        self.assertEqual(photo.remark, '更新备注')

    def test_delete_shipment_delivery_photo_success(self):
        photo = shipment_models.ShipmentDeliveryPhoto.objects.create(
            shipment=self.shipment,
            delivery=self.delivery,
            remark='待删除',
            photo=tiny_gif('delete.gif'),
            created_by=self.user,
        )

        resp = self.client.delete(f'/api/v2/shipment-delivery-photos/{photo.id}/')

        self.assertEqual(resp.status_code, 204)
        self.assertFalse(shipment_models.ShipmentDeliveryPhoto.objects.filter(id=photo.id).exists())