import { describe, it, expect, beforeEach } from 'vitest';
import { testClient } from 'hono/testing';
import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
import { JWTUtil } from '@d8d/shared-utils';
import { UserType } from '@d8d/shared-types';
import { UserEntity, Role } from '@d8d/user-module';
import { File } from '@d8d/file-module';
import { DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit } from '@d8d/allin-disability-module/entities';
import { Company } from '@d8d/allin-company-module/entities';
import { Platform } from '@d8d/allin-platform-module/entities';
import { BankName } from '@d8d/bank-names-module';
import talentEmploymentRoutes from '../../src/routes/talent-employment.routes';
import { EmploymentOrder } from '../../src/entities/employment-order.entity';
import { OrderPerson } from '../../src/entities/order-person.entity';
import { OrderPersonAsset } from '../../src/entities/order-person-asset.entity';
import { AssetType, AssetFileType } from '../../src/schemas/order.schema';
import { OrderStatus, WorkStatus } from '@d8d/allin-enums';

// 设置集成测试钩子
setupIntegrationDatabaseHooksWithEntities([
  UserEntity, Role, File, Platform, Company,
  DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit,
  BankName,
  EmploymentOrder, OrderPerson, OrderPersonAsset
]);

describe('人才就业信息API集成测试 - 故事015.005', () => {
  let client: ReturnType<typeof testClient<typeof talentEmploymentRoutes>>;
  let testToken: string;
  let testTalentUser: UserEntity;
  let testDisabledPerson: DisabledPerson;
  let testCompany: Company;
  let testPlatform: Platform;
  let testFile: File;

  beforeEach(async () => {
    // 创建测试客户端
    client = testClient(talentEmploymentRoutes);

    // 获取数据源
    const dataSource = await IntegrationTestDatabase.getDataSource();

    // 创建测试银行
    const bankNameRepository = dataSource.getRepository(BankName);
    const testBankName = bankNameRepository.create({
      name: '测试银行',
      code: 'TEST001',
      remark: '测试银行',
      status: 1
    });
    await bankNameRepository.save(testBankName);

    // 创建测试残疾人 - 使用正确的字段名
    const personRepository = dataSource.getRepository(DisabledPerson);
    testDisabledPerson = personRepository.create({
      name: '李四',
      gender: '1',
      disabilityType: '肢体残疾',
      disabilityLevel: '三级',
      idCard: `110101${Date.now() % 100000000}`,
      disabilityId: `D${Date.now() % 100000000}`,
      idAddress: '北京市朝阳区',
      phone: '13900139000',
      province: '北京市',
      city: '北京市',
      district: '朝阳区',
      jobStatus: 0,  // 0-未在职，1-已在职
      canDirectContact: 1,
      isInBlackList: 0,
      birthDate: new Date('1990-01-01'),
      idValidDate: new Date('2030-01-01'),
      disabilityValidDate: new Date('2025-12-31'),
      specificDisability: '左腿轻微残疾'
    });
    await personRepository.save(testDisabledPerson);

    // 创建测试人才用户（残疾人已经创建，可以用作personId）
    const userRepository = dataSource.getRepository(UserEntity);
    testTalentUser = userRepository.create({
      username: `talent_${Date.now()}`,
      password: 'test_password',
      nickname: '测试人才',
      userType: UserType.TALENT,
      personId: testDisabledPerson.id,
      registrationSource: 'mini',
      isDisabled: 0,
      isDeleted: 0
    });
    await userRepository.save(testTalentUser);

    // 生成测试用户的token
    testToken = JWTUtil.generateToken({
      id: testTalentUser.id,
      username: testTalentUser.username,
      roles: [{ name: 'talent' }]
    }, {
      personId: testDisabledPerson.id,
      userType: UserType.TALENT
    });

    // 创建测试平台
    const platformRepository = dataSource.getRepository(Platform);
    testPlatform = platformRepository.create({
      platformName: '测试平台',
      status: 1
    });
    await platformRepository.save(testPlatform);

    // 创建测试企业
    const companyRepository = dataSource.getRepository(Company);
    testCompany = companyRepository.create({
      platformId: testPlatform.id,
      companyName: '测试科技有限公司',
      contactPerson: '张三',
      contactPhone: '13800138000',
      status: 1
    });
    await companyRepository.save(testCompany);

    // 创建测试文件（用于视频资产）
    const fileRepository = dataSource.getRepository(File);
    testFile = fileRepository.create({
      name: '工资视频_2025-01.mp4',
      type: 'video/mp4',
      size: 1024000,
      path: `videos/${Date.now()}_salary_video.mp4`,
      uploadUserId: testTalentUser.id,
      uploadTime: new Date()
    });
    await fileRepository.save(testFile);
  });

  describe('GET /employment/status - 当前就业状态查询', () => {
    it('应该成功查询当前就业状态 - 在职状态', async () => {
      // 创建测试订单
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const orderRepository = dataSource.getRepository(EmploymentOrder);
      const testOrder = orderRepository.create({
        platformId: testPlatform.id,
        companyId: testCompany.id,
        orderName: '包装工',
        expectedStartDate: new Date('2025-01-01'),
        actualStartDate: new Date('2025-01-15'),
        orderStatus: OrderStatus.IN_PROGRESS,
        workStatus: WorkStatus.WORKING
      });
      await orderRepository.save(testOrder);

      // 创建订单人员关联
      const orderPersonRepository = dataSource.getRepository(OrderPerson);
      const orderPerson = orderPersonRepository.create({
        orderId: testOrder.id,
        personId: testDisabledPerson.id,
        joinDate: new Date('2025-01-15'),
        actualStartDate: new Date('2025-01-15'),
        workStatus: WorkStatus.WORKING,
        salaryDetail: 3500.00
      });
      await orderPersonRepository.save(orderPerson);

      // 查询当前就业状态
      const response = await client.employment.status.$get(undefined, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.companyName).toBe('测试科技有限公司');
        expect(data.orderId).toBe(testOrder.id);
        expect(data.orderName).toBe('包装工');
        expect(data.workStatus).toBe('working');
        expect(data.salaryLevel).toBe(3500.00);
      }
    });

    it('应该返回404当用户无就业记录时', async () => {
      const response = await client.employment.status.$get(undefined, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(404);

      if (response.status === 404) {
        const error = await response.json();
        expect(error.code).toBe(404);
        expect(error.message).toContain('用户不存在');
      }
    });

    it('应该返回404当用户未关联残疾人信息时', async () => {
      // 创建一个没有personId的用户
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const userRepository = dataSource.getRepository(UserEntity);
      const userWithoutPerson = userRepository.create({
        username: `no_person_${Date.now()}`,
        password: 'test_password',
        nickname: '无残疾人关联用户',
        userType: UserType.TALENT,
        registrationSource: 'mini',
        isDisabled: 0,
        isDeleted: 0
      });
      await userRepository.save(userWithoutPerson);

      const token = JWTUtil.generateToken({
        id: userWithoutPerson.id,
        username: userWithoutPerson.username,
        roles: [{ name: 'talent' }]
      }, {
        userType: UserType.TALENT
      });

      const response = await client.employment.status.$get(undefined, {
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });

      expect(response.status).toBe(404);

      if (response.status === 404) {
        const error = await response.json();
        expect(error.code).toBe(404);
        expect(error.message).toContain('用户不存在');
      }
    });
  });

  describe('GET /employment/salary-records - 薪资记录查询', () => {
    beforeEach(async () => {
      // 创建测试订单和人员关联
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const orderRepository = dataSource.getRepository(EmploymentOrder);
      const testOrder = orderRepository.create({
        platformId: testPlatform.id,
        companyId: testCompany.id,
        orderName: '包装工',
        expectedStartDate: new Date('2025-01-01'),
        actualStartDate: new Date('2025-01-15'),
        orderStatus: OrderStatus.IN_PROGRESS,
        workStatus: WorkStatus.WORKING
      });
      await orderRepository.save(testOrder);

      const orderPersonRepository = dataSource.getRepository(OrderPerson);
      const orderPerson = orderPersonRepository.create({
        orderId: testOrder.id,
        personId: testDisabledPerson.id,
        joinDate: new Date('2025-01-15'),
        actualStartDate: new Date('2025-01-15'),
        workStatus: WorkStatus.WORKING,
        salaryDetail: 3500.00
      });
      await orderPersonRepository.save(orderPerson);
    });

    it('应该成功查询薪资记录', async () => {
      const response = await client.employment['salary-records'].$get({
        query: {
          skip: 0,
          take: 10
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      if (response.status !== 200) {
        const error = await response.json();
        console.debug('查询薪资记录失败:', JSON.stringify(error, null, 2));
      }
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
        expect(data.total).toBeGreaterThanOrEqual(0);
      }
    });

    it('应该支持按月份过滤薪资记录', async () => {
      const response = await client.employment['salary-records'].$get({
        query: {
          month: '2025-01',
          skip: 0,
          take: 10
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
      }
    });
  });

  describe('GET /employment/history - 就业历史查询', () => {
    beforeEach(async () => {
      // 创建多个测试订单来模拟就业历史
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const orderRepository = dataSource.getRepository(EmploymentOrder);

      const order1 = orderRepository.create({
        platformId: testPlatform.id,
        companyId: testCompany.id,
        orderName: '包装工',
        expectedStartDate: new Date('2024-06-01'),
        actualStartDate: new Date('2024-06-15'),
        actualEndDate: new Date('2024-12-31'),
        orderStatus: OrderStatus.COMPLETED,
        workStatus: WorkStatus.RESIGNED
      });
      await orderRepository.save(order1);

      const orderPersonRepository = dataSource.getRepository(OrderPerson);
      const orderPerson1 = orderPersonRepository.create({
        orderId: order1.id,
        personId: testDisabledPerson.id,
        joinDate: new Date('2024-06-15'),
        leaveDate: new Date('2024-12-31'),
        workStatus: WorkStatus.RESIGNED,
        salaryDetail: 3000.00
      });
      await orderPersonRepository.save(orderPerson1);

      const order2 = orderRepository.create({
        platformId: testPlatform.id,
        companyId: testCompany.id,
        orderName: '组装工',
        expectedStartDate: new Date('2025-01-01'),
        actualStartDate: new Date('2025-01-15'),
        orderStatus: OrderStatus.IN_PROGRESS,
        workStatus: WorkStatus.WORKING
      });
      await orderRepository.save(order2);

      const orderPerson2 = orderPersonRepository.create({
        orderId: order2.id,
        personId: testDisabledPerson.id,
        joinDate: new Date('2025-01-15'),
        workStatus: WorkStatus.WORKING,
        salaryDetail: 3500.00
      });
      await orderPersonRepository.save(orderPerson2);
    });

    it('应该成功查询就业历史，按时间倒序排列', async () => {
      const response = await client.employment['history'].$get({
        query: {
          skip: 0,
          take: 20
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      if (response.status !== 200) {
        const error = await response.json();
        console.debug('查询就业历史失败:', JSON.stringify(error, null, 2));
      }
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
        expect(data.total).toBeGreaterThanOrEqual(0);
        // 验证按时间倒序排列（最新的在前）
        if (data.data.length > 1) {
          expect(new Date(data.data[0].joinDate).getTime())
            .toBeGreaterThanOrEqual(new Date(data.data[1].joinDate).getTime());
        }
      }
    });

    it('应该支持分页查询就业历史', async () => {
      const response = await client.employment['history'].$get({
        query: {
          skip: 0,
          take: 1
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
        expect(data.total).toBe(2);
      }
    });
  });

  describe('GET /employment/salary-videos - 薪资视频查询', () => {
    beforeEach(async () => {
      // 创建测试订单和人员关联
      const dataSource = await IntegrationTestDatabase.getDataSource();
      const orderRepository = dataSource.getRepository(EmploymentOrder);
      const testOrder = orderRepository.create({
        platformId: testPlatform.id,
        companyId: testCompany.id,
        orderName: '包装工',
        expectedStartDate: new Date('2025-01-01'),
        orderStatus: OrderStatus.IN_PROGRESS,
        workStatus: WorkStatus.WORKING
      });
      await orderRepository.save(testOrder);

      const orderPersonRepository = dataSource.getRepository(OrderPerson);
      const orderPerson = orderPersonRepository.create({
        orderId: testOrder.id,
        personId: testDisabledPerson.id,
        joinDate: new Date('2025-01-15'),
        workStatus: WorkStatus.WORKING,
        salaryDetail: 3500.00
      });
      await orderPersonRepository.save(orderPerson);

      // 创建薪资视频资产
      const assetRepository = dataSource.getRepository(OrderPersonAsset);
      const salaryVideo = assetRepository.create({
        orderId: testOrder.id,
        personId: testDisabledPerson.id,
        fileId: testFile.id,
        assetType: AssetType.SALARY_VIDEO,
        assetFileType: AssetFileType.VIDEO,
        status: 'verified',
        relatedTime: new Date('2025-01-15')
      });
      await assetRepository.save(salaryVideo);
    });

    it('应该成功查询薪资视频', async () => {
      const response = await client.employment['salary-videos'].$get({
        query: {
          skip: 0,
          take: 10
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      if (response.status !== 200) {
        const error = await response.json();
        console.debug('查询薪资视频失败:', JSON.stringify(error, null, 2));
      }
      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
        expect(data.total).toBeGreaterThanOrEqual(0);
      }
    });

    it('应该支持按类型过滤薪资视频', async () => {
      const response = await client.employment['salary-videos'].$get({
        query: {
          assetType: 'salary_video',
          skip: 0,
          take: 10
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
      }
    });

    it('应该支持按月份过滤薪资视频', async () => {
      const response = await client.employment['salary-videos'].$get({
        query: {
          month: '2025-01',
          skip: 0,
          take: 10
        }
      }, {
        headers: {
          'Authorization': `Bearer ${testToken}`
        }
      });

      expect(response.status).toBe(200);

      if (response.status === 200) {
        const data = await response.json();
        expect(data.data).toBeInstanceOf(Array);
      }
    });
  });

  describe('认证和权限验证', () => {
    it('应该返回401当未提供token时', async () => {
      const response = await client.employment.status.$get(undefined, {
        headers: {}
      });

      expect(response.status).toBe(401);
    });

    it('应该返回401当token无效时', async () => {
      const response = await client.employment.status.$get(undefined, {
        headers: {
          'Authorization': 'Bearer invalid_token'
        }
      });

      expect(response.status).toBe(401);
    });
  });
});
