from django.test import TestCase
from django.contrib.auth.models import User
from rest_framework.test import APIClient
from rest_framework import status
from basic_info.models import (
    Merchant, MerchantTypeEnum, WareHouse, WarehouseTypeEnum, 
    Employee, EmployeeType, EmployeeStatusEnum
)


class WarehouseAPITestCase(TestCase):
    """测试仓库 API"""

    def setUp(self):
        """设置测试数据"""
        # 创建商户
        self.merchant = Merchant.objects.create(
            name='测试商户',
            type=MerchantTypeEnum.STORE
        )
        
        # 创建用户和员工
        self.user = User.objects.create_user(
            username='testuser',
            password='testpass123'
        )
        self.employee = Employee.objects.create(
            merchant=self.merchant,
            sys_user=self.user,
            name='测试员工'
        )
        
        # 设置 API 客户端
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)

    def test_create_warehouse_with_default_type(self):
        """测试创建仓库时使用默认类型"""
        data = {
            'name': '测试仓库1',
            'location': '测试地址',
        }
        response = self.client.post('/api/backend/warehouses/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['type'], WarehouseTypeEnum.WHOLE.value)
        
        # 验证数据库
        warehouse = WareHouse.objects.get(id=response.data['id'])
        self.assertEqual(warehouse.type, WarehouseTypeEnum.WHOLE)

    def test_create_warehouse_with_whole_type(self):
        """测试创建整仓"""
        data = {
            'name': '整仓测试',
            'type': WarehouseTypeEnum.WHOLE.value,
        }
        response = self.client.post('/api/backend/warehouses/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['type'], WarehouseTypeEnum.WHOLE.value)

    def test_create_warehouse_with_scattered_type(self):
        """测试创建散仓"""
        data = {
            'name': '散仓测试',
            'type': WarehouseTypeEnum.SCATTERED.value,
        }
        response = self.client.post('/api/backend/warehouses/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['type'], WarehouseTypeEnum.SCATTERED.value)

    def test_list_warehouses_includes_type(self):
        """测试列表接口返回类型字段"""
        WareHouse.objects.create(
            merchant=self.merchant,
            name='仓库1',
            type=WarehouseTypeEnum.WHOLE
        )
        WareHouse.objects.create(
            merchant=self.merchant,
            name='仓库2',
            type=WarehouseTypeEnum.SCATTERED
        )
        
        response = self.client.get('/api/backend/warehouses/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        results = response.data['results'] if isinstance(response.data, dict) else response.data
        self.assertEqual(len(results), 2)
        
        # 验证返回的数据包含 type 字段
        for warehouse in results:
            self.assertIn('type', warehouse)
            self.assertIn(warehouse['type'], [WarehouseTypeEnum.WHOLE.value, WarehouseTypeEnum.SCATTERED.value])

    def test_update_warehouse_type(self):
        """测试更新仓库类型"""
        warehouse = WareHouse.objects.create(
            merchant=self.merchant,
            name='待更新仓库',
            type=WarehouseTypeEnum.WHOLE
        )
        
        data = {'type': WarehouseTypeEnum.SCATTERED.value}
        response = self.client.patch(f'/api/backend/warehouses/{warehouse.id}/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['type'], WarehouseTypeEnum.SCATTERED.value)
        
        # 验证数据库
        warehouse.refresh_from_db()
        self.assertEqual(warehouse.type, WarehouseTypeEnum.SCATTERED)

    def test_retrieve_warehouse_includes_type(self):
        """测试检索单个仓库时包含类型字段"""
        warehouse = WareHouse.objects.create(
            merchant=self.merchant,
            name='单个仓库',
            type=WarehouseTypeEnum.SCATTERED
        )
        
        response = self.client.get(f'/api/backend/warehouses/{warehouse.id}/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['type'], WarehouseTypeEnum.SCATTERED.value)
        self.assertEqual(response.data['name'], '单个仓库')


class EmployeeTypeAPITestCase(TestCase):
    """测试员工职位类型 API"""

    def setUp(self):
        """设置测试数据"""
        # 创建商户
        self.merchant = Merchant.objects.create(
            name='测试商户',
            type=MerchantTypeEnum.STORE
        )
        
        # 创建用户和员工
        self.user = User.objects.create_user(
            username='testuser',
            password='testpass123'
        )
        self.employee = Employee.objects.create(
            merchant=self.merchant,
            sys_user=self.user,
            name='测试员工'
        )
        
        # 设置 API 客户端
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)

    def test_create_employee_type(self):
        """测试创建职位类型"""
        data = {
            'title': '打纸工',
            'description': '负责打纸工作'
        }
        response = self.client.post('/api/backend/employee-types/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['title'], '打纸工')
        self.assertEqual(response.data['description'], '负责打纸工作')

    def test_list_employee_types(self):
        """测试列出所有职位类型"""
        EmployeeType.objects.create(merchant=self.merchant, title='打纸工')
        EmployeeType.objects.create(merchant=self.merchant, title='滚筒工')
        
        response = self.client.get('/api/backend/employee-types/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        results = response.data['results'] if isinstance(response.data, dict) else response.data
        self.assertEqual(len(results), 2)

    def test_update_employee_type(self):
        """测试更新职位类型"""
        emp_type = EmployeeType.objects.create(
            merchant=self.merchant,
            title='仓库管理员'
        )
        
        data = {'description': '新的描述'}
        response = self.client.patch(f'/api/backend/employee-types/{emp_type.id}/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['description'], '新的描述')

    def test_delete_employee_type(self):
        """测试删除职位类型"""
        emp_type = EmployeeType.objects.create(
            merchant=self.merchant,
            title='临时工'
        )
        
        response = self.client.delete(f'/api/backend/employee-types/{emp_type.id}/')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertFalse(EmployeeType.objects.filter(id=emp_type.id).exists())


class EmployeeAPITestCase(TestCase):
    """测试员工 API（包含 job_type 兼容性）"""

    def setUp(self):
        """设置测试数据"""
        # 创建商户
        self.merchant = Merchant.objects.create(
            name='测试商户',
            type=MerchantTypeEnum.STORE
        )
        
        # 创建用户和员工
        self.user = User.objects.create_user(
            username='testuser',
            password='testpass123'
        )
        self.employee = Employee.objects.create(
            merchant=self.merchant,
            sys_user=self.user,
            name='测试员工'
        )
        
        # 创建职位类型
        self.emp_type = EmployeeType.objects.create(
            merchant=self.merchant,
            title='打纸工'
        )
        
        # 设置 API 客户端
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)

    def test_create_employee_with_position(self):
        """测试创建带职位的员工"""
        data = {
            'name': '张三',
            'position': self.emp_type.id,
            'mobile': '13800138000'
        }
        response = self.client.post('/api/backend/employees/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['position'], self.emp_type.id)
        self.assertEqual(response.data['job_type'], '打纸工')  # 验证兼容性字段

    def test_create_employee_without_position(self):
        """测试创建不带职位的员工"""
        data = {
            'name': '李四',
            'mobile': '13900139000'
        }
        response = self.client.post('/api/backend/employees/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertIsNone(response.data['position'])
        self.assertEqual(response.data['job_type'], '')  # 验证返回空字符串

    def test_list_employees_includes_job_type(self):
        """测试列表接口包含 job_type 字段"""
        Employee.objects.create(
            merchant=self.merchant,
            name='员工1',
            position=self.emp_type
        )
        Employee.objects.create(
            merchant=self.merchant,
            name='员工2'
        )
        
        response = self.client.get('/api/backend/employees/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        results = response.data['results'] if isinstance(response.data, dict) else response.data
        
        # 验证 job_type 字段存在
        for emp in results:
            self.assertIn('job_type', emp)

    def test_update_employee_position(self):
        """测试更新员工职位"""
        new_type = EmployeeType.objects.create(
            merchant=self.merchant,
            title='滚筒工'
        )
        
        employee = Employee.objects.create(
            merchant=self.merchant,
            name='王五',
            position=self.emp_type
        )
        
        data = {'position': new_type.id}
        response = self.client.patch(f'/api/backend/employees/{employee.id}/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['position'], new_type.id)
        self.assertEqual(response.data['job_type'], '滚筒工')

    def test_job_type_is_read_only(self):
        """测试 job_type 是只读字段"""
        employee = Employee.objects.create(
            merchant=self.merchant,
            name='赵六',
            position=self.emp_type
        )
        
        # 尝试直接更新 job_type（应该被忽略）
        data = {'job_type': '其他职位'}
        response = self.client.patch(f'/api/backend/employees/{employee.id}/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['job_type'], '打纸工')  # 应该保持不变


class UserProfileAPITestCase(TestCase):
    """测试用户资料 API"""

    def setUp(self):
        """设置测试数据"""
        # 创建商户
        self.merchant = Merchant.objects.create(
            name='测试商户',
            type=MerchantTypeEnum.STORE
        )
        
        # 创建用户和员工
        self.user = User.objects.create_user(
            username='testuser',
            password='testpass123',
            email='test@example.com'
        )
        self.employee = Employee.objects.create(
            merchant=self.merchant,
            sys_user=self.user,
            name='测试员工'
        )
        
        # 创建另一个用户用于测试
        self.user2 = User.objects.create_user(
            username='testuser2',
            password='testpass123',
            email='test2@example.com'
        )
        
        # 设置 API 客户端
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)

    def test_create_user_profile(self):
        """测试创建用户资料"""
        data = {
            'user': self.user2.id,
            'description': '测试用户资料描述'
        }
        response = self.client.post('/api/backend/user-profiles/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['user'], self.user2.id)
        self.assertEqual(response.data['merchant'], self.merchant.id)  # 应该由BaseViewSet自动设置
        self.assertEqual(response.data['description'], '测试用户资料描述')

    def test_list_user_profiles(self):
        """测试列出所有用户资料"""
        from basic_info.models import UserProfile
        UserProfile.objects.create(
            user=self.user,
            merchant=self.merchant,
            description='用户1资料'
        )
        UserProfile.objects.create(
            user=self.user2,
            merchant=self.merchant,
            description='用户2资料'
        )
        
        response = self.client.get('/api/backend/user-profiles/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        results = response.data['results'] if isinstance(response.data, dict) else response.data
        self.assertEqual(len(results), 2)  # 应该只返回当前商户的用户资料

    def test_retrieve_user_profile(self):
        """测试检索单个用户资料"""
        from basic_info.models import UserProfile
        profile = UserProfile.objects.create(
            user=self.user,
            merchant=self.merchant,
            description='测试资料'
        )
        
        response = self.client.get(f'/api/backend/user-profiles/{profile.id}/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['id'], profile.id)
        self.assertEqual(response.data['description'], '测试资料')
        self.assertEqual(response.data['user_detail']['username'], 'testuser')  # 检查嵌套用户对象

    def test_update_user_profile(self):
        """测试更新用户资料"""
        from basic_info.models import UserProfile
        profile = UserProfile.objects.create(
            user=self.user,
            merchant=self.merchant,
            description='原始描述'
        )
        
        data = {'description': '更新后的描述'}
        response = self.client.patch(f'/api/backend/user-profiles/{profile.id}/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['description'], '更新后的描述')
        
        # 验证数据库
        profile.refresh_from_db()
        self.assertEqual(profile.description, '更新后的描述')

    def test_delete_user_profile(self):
        """测试删除用户资料"""
        from basic_info.models import UserProfile
        profile = UserProfile.objects.create(
            user=self.user,
            merchant=self.merchant,
            description='待删除资料'
        )
        
        response = self.client.delete(f'/api/backend/user-profiles/{profile.id}/')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertFalse(UserProfile.objects.filter(id=profile.id).exists())

    def test_user_profile_filter_by_merchant(self):
        """测试用户资料按商户过滤"""
        # 创建另一个商户
        other_merchant = Merchant.objects.create(
            name='其他商户',
            type=MerchantTypeEnum.FACTORY
        )
        
        # 创建另一个商户的员工
        other_user = User.objects.create_user(
            username='otheruser',
            password='testpass123'
        )
        other_employee = Employee.objects.create(
            merchant=other_merchant,
            sys_user=other_user,
            name='其他员工'
        )
        
        # 为两个商户分别创建用户资料
        from basic_info.models import UserProfile
        UserProfile.objects.create(
            user=self.user,
            merchant=self.merchant,
            description='本商户用户资料'
        )
        UserProfile.objects.create(
            user=other_user,
            merchant=other_merchant,
            description='其他商户用户资料'
        )
        
        # 使用当前用户（属于self.merchant）访问API
        response = self.client.get('/api/backend/user-profiles/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        results = response.data['results'] if isinstance(response.data, dict) else response.data
        self.assertEqual(len(results), 1)  # 只应该返回当前商户的用户资料
        self.assertEqual(results[0]['description'], '本商户用户资料')
