"""Settlement API 测试"""
from datetime import date, datetime

from django.test import TestCase
from django.utils import timezone
from rest_framework.test import APIClient
from rest_framework import status
from django.contrib.auth import get_user_model

from basic_info import models as basic_models
from printing import models as printing_models

User = get_user_model()


class PlateOrderSummaryAPITestCase(TestCase):
    """测试开版订单统计 API"""
    
    def setUp(self):
        self.client = APIClient()
        
        self.merchant = basic_models.Merchant.objects.create(
            name='测试商户',
            type=basic_models.MerchantTypeEnum.FACTORY
        )
        
        self.user = User.objects.create_user(
            username='testuser',
            password='testpass123'
        )
        self.employee = basic_models.Employee.objects.create(
            sys_user=self.user,
            merchant=self.merchant,
            name='测试员工'
        )
        
        self.customer = basic_models.Customer.objects.create(
            merchant=self.merchant,
            name='测试客户',
            created_by=self.employee
        )
        
        self.client.force_authenticate(user=self.user)
    
    def test_requires_date_parameter(self):
        """测试必须提供 date 参数"""
        response = self.client.get('/api/v1/settlement/plate-orders/summary/')
        
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertIn('缺少 date 参数', response.data['error'])
    
    def test_invalid_date_format(self):
        """测试无效的日期格式"""
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026/02/08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertIn('日期格式错误', response.data['error'])
    
    def test_invalid_date(self):
        """测试不存在的日期"""
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-30'
        )
        
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        self.assertIn('日期不存在', response.data['error'])
    
    def test_requires_merchant(self):
        """测试用户必须关联商户"""
        user_without_merchant = User.objects.create_user(
            username='no-merchant',
            password='pass123'
        )
        self.client.force_authenticate(user=user_without_merchant)
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        self.assertIn('用户未关联商户', response.data['error'])
    
    def test_returns_summary_for_valid_date(self):
        """测试返回有效的统计数据"""
        today = date(2026, 2, 8)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertIn('data', response.data)
        self.assertEqual(len(response.data['data']), 1)
        self.assertEqual(response.data['data'][0]['client_id'], self.customer.id)
        self.assertEqual(response.data['data'][0]['client_name'], '测试客户')
        self.assertEqual(len(response.data['data'][0]['plate_order_count']), 1)
        self.assertEqual(
            response.data['data'][0]['plate_order_count'][0]['type'],
            '首版-定位'
        )
        self.assertEqual(
            response.data['data'][0]['plate_order_count'][0]['today'],
            1
        )
    
    def test_calculates_current_month(self):
        """测试计算本月累计数量"""
        today = date(2026, 2, 8)
        month_start = date(2026, 2, 1)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(month_start, datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            response.data['data'][0]['plate_order_count'][0]['current_month'],
            2
        )
    
    def test_filters_null_plate_type(self):
        """测试过滤 plate_type 为空的订单"""
        today = date(2026, 2, 8)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type=None,
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            response.data['data'][0]['plate_order_count'][0]['today'],
            1
        )
    
    def test_filters_null_production_method(self):
        """测试过滤 production_method 为空的订单"""
        today = date(2026, 2, 8)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method=None,
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['data']), 1)
        self.assertEqual(
            response.data['data'][0]['plate_order_count'][0]['type'],
            '首版-定位'
        )
        self.assertEqual(
            response.data['data'][0]['plate_order_count'][0]['today'],
            1
        )
    
    def test_filters_zero_data(self):
        """测试过滤全0数据"""
        today = date(2026, 2, 8)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(date(2026, 1, 1), datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['data']), 0)
    
    def test_applies_merchant_isolation(self):
        """测试应用商户隔离"""
        other_merchant = basic_models.Merchant.objects.create(
            name='其他商户',
            type=basic_models.MerchantTypeEnum.FACTORY
        )
        other_customer = basic_models.Customer.objects.create(
            merchant=other_merchant,
            name='其他客户'
        )
        
        today = date(2026, 2, 8)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=self.customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        printing_models.PlateOrder.objects.create(
            merchant=other_merchant,
            customer=other_customer,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['data']), 1)
        self.assertEqual(response.data['data'][0]['client_id'], self.customer.id)
        self.assertEqual(response.data['data'][0]['client_name'], '测试客户')
    
    def test_applies_customer_visibility(self):
        """测试应用客户可见性过滤"""
        other_employee = basic_models.Employee.objects.create(
            sys_user=User.objects.create_user('other', 'pass123'),
            merchant=self.merchant,
            name='其他员工'
        )
        
        customer_visible = basic_models.Customer.objects.create(
            merchant=self.merchant,
            name='可见客户',
            created_by=other_employee
        )
        customer_visible.visible_employees.set([self.employee])
        
        customer_invisible = basic_models.Customer.objects.create(
            merchant=self.merchant,
            name='不可见客户',
            created_by=other_employee
        )
        
        today = date(2026, 2, 8)
        
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=customer_visible,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        printing_models.PlateOrder.objects.create(
            merchant=self.merchant,
            customer=customer_invisible,
            plate_type='首版',
            production_method='定位',
            plate_date=timezone.make_aware(datetime.combine(today, datetime.min.time()))
        )
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['data']), 1)
        self.assertEqual(response.data['data'][0]['client_id'], customer_visible.id)
        self.assertEqual(response.data['data'][0]['client_name'], '可见客户')
    
    def test_requires_authentication(self):
        """测试需要认证"""
        self.client.force_authenticate(user=None)
        
        response = self.client.get(
            '/api/v1/settlement/plate-orders/summary/?date=2026-02-08'
        )
        
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
