import { Injectable } from '@nestjs/common';
import { DingtalkYidaService } from '../sdk/dingtalk-yida.service';
import { DingtalkAttendanceService } from '../sdk/dingtalk-attendance.service';
import {
  FORM_UUIDS,
  LEAVE_EXTENSION_PROCESS_FIELDS,
  LEAVE_EXTENSION_DATA_FIELDS,
} from '../constants';
import { getLeaveCode, getLeaveType } from '../constants/leave-codes';
import { SyncExecutionResult } from './business-trip-sync.service';
import { SyncLogger } from './sync-logger';

@Injectable()
export class LeaveExtensionSyncService {

  constructor(
    private yidaService: DingtalkYidaService,
    private attendanceService: DingtalkAttendanceService,
  ) {}

  /**
   * 处理假期延期申请
   * 对应Python: get_vacation_extension()
   */
  async sync(fromTime?: string, toTime?: string, userId?: string): Promise<SyncExecutionResult> {
    const logger = new SyncLogger('LeaveExtensionSyncService');
    const startTime = Date.now();
    let count = 0;
    const errors: string[] = [];

    logger.log('----开始假期延期申请数据同步----');
    if (fromTime || toTime) logger.log(`时间范围: ${fromTime || '不限'} ~ ${toTime || '不限'}`);
    if (userId) logger.log(`指定员工: ${userId}`);

    try {
      const formData = await this.yidaService.searchApprovedInstances(
        FORM_UUIDS.LEAVE_EXTENSION_PROCESS,
        fromTime,
        toTime,
      );
      logger.log(`从宜搭获取到 ${formData.length} 条审批通过的假期延期申请`);

      const items = userId ? formData.filter(d => d.creatorUserId === userId) : formData;
      if (userId) logger.log(`按员工过滤后剩余 ${items.length} 条`);
      const extensions: any[] = [];

      for (const data of items) {
        const processData = data.formData;
        const creatorUserId = data.creatorUserId;
        const leaveType = processData[LEAVE_EXTENSION_PROCESS_FIELDS.LEAVE_TYPE];
        const leaveCode = getLeaveCode(leaveType);
        const expirationDate = processData[LEAVE_EXTENSION_PROCESS_FIELDS.EXPIRATION_DATE];
        const applicationDate = processData[LEAVE_EXTENSION_PROCESS_FIELDS.APPLICATION_DATE];

        if (!leaveCode || !expirationDate) continue;

        const expirationStart = parseInt(expirationDate[0]);
        const expirationEnd = parseInt(expirationDate[1]) + 86400000;

        const leaveQuotas = await this.attendanceService.searchLeaveQuota(leaveCode, creatorUserId);

        for (const quota of leaveQuotas) {
          if (expirationStart <= parseInt(quota.end_time) && parseInt(quota.end_time) <= expirationEnd) {
            const days = (parseInt(quota.quota_num_per_day) - parseInt(quota.used_num_per_day)) / 100;
            if (days > 0) {
              extensions.push({
                userId: creatorUserId,
                employeeName: processData[LEAVE_EXTENSION_PROCESS_FIELDS.NAME] || '',
                employeeId: processData[LEAVE_EXTENSION_PROCESS_FIELDS.EMPLOYEE_ID] || '',
                leaveType: getLeaveType(quota.leave_code),
                leaveId: quota.quota_id,
                expirationDate: quota.end_time,
                days,
                applicationDate,
              });
            }
          }
        }
      }

      logger.log(`匹配到 ${extensions.length} 条需要延期的假期记录`);

      // 保存到宜搭表单
      for (const ext of extensions) {
        try {
          const searchCond = JSON.stringify([
            { key: LEAVE_EXTENSION_DATA_FIELDS.LEAVE_ID, value: ext.leaveId, type: 'TEXT', operator: 'eq', componentName: 'TextField' },
          ]);

          const appDateStr = ext.applicationDate
            ? `${this.formatTimestamp(ext.applicationDate[0])}-${this.formatTimestamp(ext.applicationDate[1])}`
            : '';

          const formDataJson = JSON.stringify({
            [LEAVE_EXTENSION_DATA_FIELDS.USER_ID]: ext.userId,
            [LEAVE_EXTENSION_DATA_FIELDS.EMPLOYEE_ID]: ext.employeeId,
            [LEAVE_EXTENSION_DATA_FIELDS.EMPLOYEE_NAME]: ext.employeeName,
            [LEAVE_EXTENSION_DATA_FIELDS.LEAVE_TYPE]: ext.leaveType,
            [LEAVE_EXTENSION_DATA_FIELDS.LEAVE_ID]: ext.leaveId,
            [LEAVE_EXTENSION_DATA_FIELDS.EXPIRATION_DATE_STR]: this.formatTimestamp(ext.expirationDate),
            [LEAVE_EXTENSION_DATA_FIELDS.EXPIRATION_DATE]: ext.expirationDate,
            [LEAVE_EXTENSION_DATA_FIELDS.DAYS]: String(ext.days),
            [LEAVE_EXTENSION_DATA_FIELDS.APPLICATION_DATE_STR]: appDateStr,
            [LEAVE_EXTENSION_DATA_FIELDS.APPLICATION_DATE]: ext.applicationDate ? `${ext.applicationDate[0]}-${ext.applicationDate[1]}` : '',
            [LEAVE_EXTENSION_DATA_FIELDS.IS_NOTIFY]: 'No',
          });

          await this.yidaService.createOrUpdateForm(
            FORM_UUIDS.LEAVE_EXTENSION_DATA,
            searchCond,
            formDataJson,
          );
          count++;
          logger.log(`已保存延期申请: ${ext.userId} ${ext.employeeName} ${ext.leaveType} ${ext.days}天`);
        } catch (error: any) {
          errors.push(`保存延期申请失败: ${error.message}`);
        }
      }
    } catch (error: any) {
      errors.push(`假期延期同步整体失败: ${error.message}`);
    }

    logger.log(`----假期延期申请数据同步完成，共${count}条----`);

    return {
      success: errors.length === 0,
      processedCount: count,
      errors,
      duration: Date.now() - startTime,
      logs: logger.getText(),
    };
  }

  private formatTimestamp(timestamp: string | number): string {
    const date = new Date(Number(timestamp));
    const parts = new Intl.DateTimeFormat('sv-SE', {
      timeZone: 'Asia/Shanghai',
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false,
    }).formatToParts(date);
    const get = (type: string) => parts.find(p => p.type === type)?.value || '';
    return `${get('year')}-${get('month')}-${get('day')} ${get('hour')}:${get('minute')}:${get('second')}`;
  }
}
