import { EmployeeInfoSyncService } from '../../../../src/modules/organization/dingtalk/sync/employee-info-sync.service';
import { EMPLOYEE_INFO_FIELDS, FORM_UUIDS, OLD_EMPLOYEE_INFO_FIELDS } from '../../../../src/modules/organization/dingtalk/constants';

describe('EmployeeInfoSyncService', () => {
  const buildEmployee = (departmentIds: string, overrides: Record<string, string> = {}) => ({
    field_data_list: [
      { field_name: '部门id', field_value_list: [{ value: departmentIds }] },
      { field_name: '工号', field_value_list: [{ value: overrides['工号'] || 'E001' }] },
      { field_name: '姓名', field_value_list: [{ value: overrides['姓名'] || '张三' }] },
      { field_name: '国家', field_value_list: [{ value: overrides['国家'] || '中国' }] },
      { field_name: '办公地点', field_value_list: [{ value: overrides['办公地点'] || '上海' }] },
      { field_name: '合同公司', field_value_list: [{ value: overrides['合同公司'] || 'FFOA' }] },
      { field_name: '开户行', field_value_list: [{ value: overrides['开户行'] || '招商银行' }] },
      { field_name: '银行卡号后四位', field_value_list: [{ value: overrides['银行卡号后四位'] || '1234' }] },
      { field_name: '职位', field_value_list: [{ value: overrides['职位'] || '工程师' }] },
      { field_name: '岗位职级', field_value_list: [{ value: overrides['岗位职级'] || 'P5' }] },
      { field_name: '入职时间', field_value_list: [{ value: overrides['入职时间'] || '2024-01-01' }] },
      { field_name: '全月标准工时', field_value_list: [{ value: overrides['全月标准工时'] || '174' }] },
      { field_name: '工时上限', field_value_list: [{ value: overrides['工时上限'] || '220' }] },
      { field_name: '司龄（系统计算）', field_value_list: [{ value: overrides['司龄（系统计算）'] || '2' }] },
      { field_name: '工龄（系统计算）', field_value_list: [{ value: overrides['工龄（系统计算）'] || '8' }] },
      { field_name: '首次参加工作时间', field_value_list: [{ value: overrides['首次参加工作时间'] || '2018-01-01' }] },
      { field_name: '手机号', field_value_list: [{ value: overrides['手机号'] || '13800000000' }] },
    ],
  });

  it('新表应同步全月标准工时和工时上限', async () => {
    const yidaService = {
      searchForm: jest.fn().mockResolvedValue([]),
      createOrUpdateForm: jest.fn().mockResolvedValue({ success: true }),
    };
    const hrmService = {
      getDepartmentFullNames: jest.fn().mockResolvedValue({
        1001: { name: '研发中心#研发一部', firstLevel: '研发中心' },
      }),
      getOnJobEmployeeIds: jest.fn().mockResolvedValue(['user001']),
      getEmployeeInfoByIds: jest.fn().mockResolvedValue({
        user001: buildEmployee('1001', { 全月标准工时: '167.4', 工时上限: '200' }),
      }),
    };

    const service = new EmployeeInfoSyncService(yidaService as any, hrmService as any);
    const result = await service.syncNewTable();

    expect(result.success).toBe(true);
    expect(result.processedCount).toBe(1);
    expect(yidaService.createOrUpdateForm).toHaveBeenCalledWith(
      FORM_UUIDS.EMPLOYEE_INFO_WEEKLY,
      expect.stringContaining('user001'),
      expect.stringContaining(`"${EMPLOYEE_INFO_FIELDS.MONTHLY_STANDARD_HOURS}":"167.4"`),
    );
    expect(yidaService.createOrUpdateForm).toHaveBeenCalledWith(
      FORM_UUIDS.EMPLOYEE_INFO_WEEKLY,
      expect.stringContaining('user001'),
      expect.stringContaining(`"${EMPLOYEE_INFO_FIELDS.WORK_HOUR_LIMIT}":"200"`),
    );
  });

  it('新表更新时应记录字段变更明细', async () => {
    const yidaService = {
      searchForm: jest.fn().mockResolvedValue([
        {
          formData: {
            [EMPLOYEE_INFO_FIELDS.USER_ID]: 'user001',
            [EMPLOYEE_INFO_FIELDS.NUMBER]: 'E001',
            [EMPLOYEE_INFO_FIELDS.NAME]: '张三',
            [EMPLOYEE_INFO_FIELDS.COUNTRY]: '中国',
            [EMPLOYEE_INFO_FIELDS.DEPARTMENT]: '研发中心#研发一部',
            [EMPLOYEE_INFO_FIELDS.WORK_PLACE]: '上海',
            [EMPLOYEE_INFO_FIELDS.CONTRACT_COMPANY]: 'FFOA',
            [EMPLOYEE_INFO_FIELDS.BANK]: '招商银行',
            [EMPLOYEE_INFO_FIELDS.BANK_NO]: '1234',
            [EMPLOYEE_INFO_FIELDS.TITLE]: '工程师',
            [EMPLOYEE_INFO_FIELDS.RANK]: 'P5',
            [EMPLOYEE_INFO_FIELDS.START_DATE]: '2024-01-01',
            [EMPLOYEE_INFO_FIELDS.MONTHLY_STANDARD_HOURS]: '167.4',
            [EMPLOYEE_INFO_FIELDS.WORK_HOUR_LIMIT]: '200',
            [EMPLOYEE_INFO_FIELDS.COMPANY_YEAR]: '2',
            [EMPLOYEE_INFO_FIELDS.WORK_YEAR]: '8',
            [EMPLOYEE_INFO_FIELDS.WORK_DATE]: '2018-01-01',
            [EMPLOYEE_INFO_FIELDS.PHONE]: '13800000000',
            [EMPLOYEE_INFO_FIELDS.STATUS]: '正常',
          },
        },
      ]),
      createOrUpdateForm: jest.fn().mockResolvedValue({ success: true }),
    };
    const hrmService = {
      getDepartmentFullNames: jest.fn().mockResolvedValue({
        1001: { name: '研发中心#研发一部', firstLevel: '研发中心' },
      }),
      getOnJobEmployeeIds: jest.fn().mockResolvedValue(['user001']),
      getEmployeeInfoByIds: jest.fn().mockResolvedValue({
        user001: buildEmployee('1001', {
          全月标准工时: '174',
          工时上限: '220',
          手机号: '13900000000',
          '司龄（系统计算）': '3',
          '工龄（系统计算）': '9',
        }),
      }),
    };

    const service = new EmployeeInfoSyncService(yidaService as any, hrmService as any);
    const result = await service.syncNewTable();

    expect(result.success).toBe(true);
    expect(result.processedCount).toBe(1);
    expect(result.logs).toContain('新表更新: 张三 (user001); 变更:');
    expect(result.logs).toContain('全月标准工时:167.4->174');
    expect(result.logs).toContain('工时上限:200->220');
    expect(result.logs).toContain('手机号:13800000000->13900000000');
  });

  it('旧表数据未变化时不应重复写入', async () => {
    const yidaService = {
      searchForm: jest.fn().mockResolvedValue([
        {
          formData: {
            [OLD_EMPLOYEE_INFO_FIELDS.USER_ID]: 'user001',
            [OLD_EMPLOYEE_INFO_FIELDS.DEPARTMENT]: '研发中心',
            [OLD_EMPLOYEE_INFO_FIELDS.NUMBER]: 'E001',
            [OLD_EMPLOYEE_INFO_FIELDS.NAME]: '张三',
            [OLD_EMPLOYEE_INFO_FIELDS.COUNTRY]: '中国',
            [OLD_EMPLOYEE_INFO_FIELDS.WORK_PLACE]: '上海',
            [OLD_EMPLOYEE_INFO_FIELDS.CONTRACT_COMPANY]: 'FFOA',
            [OLD_EMPLOYEE_INFO_FIELDS.BANK]: '招商银行',
            [OLD_EMPLOYEE_INFO_FIELDS.BANK_NO]: '1234',
            [OLD_EMPLOYEE_INFO_FIELDS.TITLE]: '工程师',
            [OLD_EMPLOYEE_INFO_FIELDS.RANK]: 'P5',
            [OLD_EMPLOYEE_INFO_FIELDS.START_DATE]: '2024-01-01',
            [OLD_EMPLOYEE_INFO_FIELDS.PHONE]: '13800000000',
            [OLD_EMPLOYEE_INFO_FIELDS.STATUS]: '正常',
          },
        },
        {
          formData: {
            [OLD_EMPLOYEE_INFO_FIELDS.USER_ID]: 'user001',
            [OLD_EMPLOYEE_INFO_FIELDS.DEPARTMENT]: '产品中心',
            [OLD_EMPLOYEE_INFO_FIELDS.NUMBER]: 'E001',
            [OLD_EMPLOYEE_INFO_FIELDS.NAME]: '张三',
            [OLD_EMPLOYEE_INFO_FIELDS.COUNTRY]: '中国',
            [OLD_EMPLOYEE_INFO_FIELDS.WORK_PLACE]: '上海',
            [OLD_EMPLOYEE_INFO_FIELDS.CONTRACT_COMPANY]: 'FFOA',
            [OLD_EMPLOYEE_INFO_FIELDS.BANK]: '招商银行',
            [OLD_EMPLOYEE_INFO_FIELDS.BANK_NO]: '1234',
            [OLD_EMPLOYEE_INFO_FIELDS.TITLE]: '工程师',
            [OLD_EMPLOYEE_INFO_FIELDS.RANK]: 'P5',
            [OLD_EMPLOYEE_INFO_FIELDS.START_DATE]: '2024-01-01',
            [OLD_EMPLOYEE_INFO_FIELDS.PHONE]: '13800000000',
            [OLD_EMPLOYEE_INFO_FIELDS.STATUS]: '正常',
          },
        },
      ]),
      createOrUpdateForm: jest.fn(),
    };
    const hrmService = {
      getDepartmentParents: jest.fn().mockResolvedValue({
        1001: { name: '研发一部', firstLevel: '研发中心' },
        1002: { name: '产品一部', firstLevel: '产品中心' },
      }),
      getOnJobEmployeeIds: jest.fn().mockResolvedValue(['user001']),
      getEmployeeInfoByIds: jest.fn().mockResolvedValue({
        user001: buildEmployee('1001|1002'),
      }),
    };

    const service = new EmployeeInfoSyncService(yidaService as any, hrmService as any);
    const result = await service.syncOldTable();

    expect(result.success).toBe(true);
    expect(result.processedCount).toBe(0);
    expect(yidaService.createOrUpdateForm).not.toHaveBeenCalled();
  });

  it('旧表字段或部门变化时才应写入对应记录', async () => {
    const yidaService = {
      searchForm: jest.fn().mockResolvedValue([
        {
          formData: {
            [OLD_EMPLOYEE_INFO_FIELDS.USER_ID]: 'user001',
            [OLD_EMPLOYEE_INFO_FIELDS.DEPARTMENT]: '研发中心',
            [OLD_EMPLOYEE_INFO_FIELDS.NUMBER]: 'E001',
            [OLD_EMPLOYEE_INFO_FIELDS.NAME]: '张三',
            [OLD_EMPLOYEE_INFO_FIELDS.COUNTRY]: '中国',
            [OLD_EMPLOYEE_INFO_FIELDS.WORK_PLACE]: '上海',
            [OLD_EMPLOYEE_INFO_FIELDS.CONTRACT_COMPANY]: 'FFOA',
            [OLD_EMPLOYEE_INFO_FIELDS.BANK]: '招商银行',
            [OLD_EMPLOYEE_INFO_FIELDS.BANK_NO]: '1234',
            [OLD_EMPLOYEE_INFO_FIELDS.TITLE]: '工程师',
            [OLD_EMPLOYEE_INFO_FIELDS.RANK]: 'P5',
            [OLD_EMPLOYEE_INFO_FIELDS.START_DATE]: '2024-01-01',
            [OLD_EMPLOYEE_INFO_FIELDS.PHONE]: '13800000000',
            [OLD_EMPLOYEE_INFO_FIELDS.STATUS]: '正常',
          },
        },
      ]),
      createOrUpdateForm: jest.fn().mockResolvedValue({ success: true }),
    };
    const hrmService = {
      getDepartmentParents: jest.fn().mockResolvedValue({
        1001: { name: '研发一部', firstLevel: '研发中心' },
        1002: { name: '产品一部', firstLevel: '产品中心' },
      }),
      getOnJobEmployeeIds: jest.fn().mockResolvedValue(['user001']),
      getEmployeeInfoByIds: jest.fn().mockResolvedValue({
        user001: buildEmployee('1001|1002', { 手机号: '13900000000' }),
      }),
    };

    const service = new EmployeeInfoSyncService(yidaService as any, hrmService as any);
    const result = await service.syncOldTable();

    expect(result.success).toBe(true);
    expect(result.processedCount).toBe(2);
    expect(yidaService.createOrUpdateForm).toHaveBeenCalledTimes(2);
    expect(yidaService.createOrUpdateForm).toHaveBeenCalledWith(
      FORM_UUIDS.OLD_EMPLOYEE_INFO,
      expect.stringContaining('研发中心'),
      expect.stringContaining('13900000000'),
    );
    expect(yidaService.createOrUpdateForm).toHaveBeenCalledWith(
      FORM_UUIDS.OLD_EMPLOYEE_INFO,
      expect.stringContaining('产品中心'),
      expect.stringContaining('13900000000'),
    );
  });
});
