"""
Products API 测试
"""
from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient
from rest_framework import status
from basic_info.models import Product, Merchant, MerchantTypeEnum, ProductCategory

User = get_user_model()


class ProductQuickAPITestCase(TestCase):
    """产品快速查询 API 测试"""
    
    def setUp(self):
        """设置测试数据"""
        # 创建用户
        self.user = User.objects.create_user(username='testuser', password='testpass123')
        
        # 创建商户
        self.merchant = Merchant.objects.create(
            name='测试商户',
            type=MerchantTypeEnum.FACTORY
        )
        
        # 创建产品类别
        self.category = ProductCategory.objects.create(
            name='布料类',
            merchant=self.merchant
        )
        
        # 创建多个产品
        self.product1 = Product.objects.create(
            name='纯棉布料',
            merchant=self.merchant,
            category=self.category
        )
        self.product2 = Product.objects.create(
            name='涤纶布料',
            merchant=self.merchant,
            category=self.category
        )
        self.product3 = Product.objects.create(
            name='丝绸布料',
            merchant=self.merchant,
            category=self.category
        )
        self.product4 = Product.objects.create(
            name='麻布',
            merchant=self.merchant,
            category=self.category
        )
        self.product5 = Product.objects.create(
            name='牛仔布',
            merchant=self.merchant,
            category=self.category
        )
        
        # 配置 API 客户端
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)
    
    def test_list_products_without_pagination(self):
        """测试获取产品列表 - 无分页"""
        response = self.client.get('/api/v1/products/quick/')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertIn('count', response.data)
        self.assertIn('results', response.data)
        self.assertEqual(response.data['count'], 5)
        self.assertEqual(len(response.data['results']), 5)
        
        # 验证返回的数据结构
        for item in response.data['results']:
            self.assertIn('id', item)
            self.assertIn('name', item)
            self.assertIn('image', item)  # 新增：验证图片字段
            self.assertEqual(len(item), 3)  # 现在有 id, name 和 image 三个字段
    
    def test_list_products_with_pagination(self):
        """测试获取产品列表 - 带分页"""
        response = self.client.get('/api/v1/products/quick/?limit=2&offset=0')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertIn('count', response.data)
        self.assertIn('results', response.data)
        self.assertIn('next', response.data)
        self.assertIn('previous', response.data)
        
        self.assertEqual(response.data['count'], 5)
        self.assertEqual(len(response.data['results']), 2)
        
        # 验证第二页
        response2 = self.client.get('/api/v1/products/quick/?limit=2&offset=2')
        self.assertEqual(response2.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response2.data['results']), 2)
    
    def test_search_products_by_name(self):
        """测试按名称搜索产品"""
        response = self.client.get('/api/v1/products/quick/?search=布料')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 3)  # 纯棉布料、涤纶布料、丝绸布料
        
        # 验证搜索结果
        names = [item['name'] for item in response.data['results']]
        self.assertIn('纯棉布料', names)
        self.assertIn('涤纶布料', names)
        self.assertIn('丝绸布料', names)
        self.assertNotIn('麻布', names)
        self.assertNotIn('牛仔布', names)
    
    def test_search_by_name(self):
        """测试按名称搜索产品"""
        response = self.client.get('/api/v1/products/quick/?search=布')
        
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['count'], 5)  # 布料, 棉布, 亚麻布, 丝绸布, 牛仔布 - all contain "布"
    
    def test_search_with_pagination(self):
        """测试搜索 + 分页"""
        response = self.client.get('/api/v1/products/quick/?search=布料&limit=2&offset=0')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 3)
        self.assertEqual(len(response.data['results']), 2)
        
        # 验证有下一页
        self.assertIsNotNone(response.data['next'])
        self.assertIsNone(response.data['previous'])
    
    def test_search_no_results(self):
        """测试搜索无结果"""
        response = self.client.get('/api/v1/products/quick/?search=不存在的产品')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 0)
        self.assertEqual(len(response.data['results']), 0)
    
    def test_unauthorized_access(self):
        """测试未认证访问"""
        client = APIClient()  # 未认证的客户端
        response = client.get('/api/v1/products/quick/')
        
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
    
    def test_response_format(self):
        """测试响应格式"""
        response = self.client.get('/api/v1/products/quick/?limit=1')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        # 验证返回的产品包含 id, name 和 image
        product = response.data['results'][0]
        self.assertIn('id', product)
        self.assertIn('name', product)
        self.assertIn('image', product)  # 新增：验证图片字段
        self.assertIsInstance(product['id'], int)
        self.assertIsInstance(product['name'], str)
        # image 可能是 None 或字符串
        self.assertTrue(product['image'] is None or isinstance(product['image'], str))
        
        # 确保没有其他不需要的字段
        self.assertNotIn('merchant', product)
        self.assertNotIn('created_at', product)
        self.assertNotIn('updated_at', product)
    
    def test_empty_database(self):
        """测试空数据库"""
        # 删除所有产品
        Product.objects.all().delete()
        
        response = self.client.get('/api/v1/products/quick/')
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], 0)
        self.assertEqual(len(response.data['results']), 0)
    
    def test_case_insensitive_search(self):
        """测试大小写不敏感搜索"""
        # 创建一个带大写的产品
        Product.objects.create(
            name='SPECIAL布料',
            merchant=self.merchant,
            category=self.category
        )
        
        # 小写搜索
        response = self.client.get('/api/v1/products/quick/?search=special')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertGreater(response.data['count'], 0)
        
        # 大写搜索
        response2 = self.client.get('/api/v1/products/quick/?search=SPECIAL')
        self.assertEqual(response2.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['count'], response2.data['count'])
    
    def test_pagination_edge_cases(self):
        """测试分页边界情况"""
        # offset 超出范围
        response = self.client.get('/api/v1/products/quick/?limit=10&offset=100')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 0)
        
        # limit = 0
        response2 = self.client.get('/api/v1/products/quick/?limit=0&offset=0')
        self.assertEqual(response2.status_code, status.HTTP_200_OK)
        
        # 负数 limit（DRF 会自动处理）
        response3 = self.client.get('/api/v1/products/quick/?limit=-1')
        self.assertEqual(response3.status_code, status.HTTP_200_OK)
