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

@Injectable()
export class LeaveReminderService {

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

  async sync(): Promise<SyncExecutionResult> {
    const logger = new SyncLogger('LeaveReminderService');
    const startTime = Date.now();
    let count = 0;
    const errors: string[] = [];

    logger.log('----开始通知假期延期程序----');

    try {
      // 获取未通知的假期延期数据
      const searchCond = JSON.stringify([
        { key: LEAVE_EXTENSION_DATA_FIELDS.IS_NOTIFY, value: 'No', type: 'TEXT', operator: 'eq', componentName: 'TextField' },
      ]);

      const extensions = await this.yidaService.searchForm(FORM_UUIDS.LEAVE_EXTENSION_DATA, searchCond);
      logger.log(`获取到 ${extensions.length} 条未通知的假期延期记录`);

      // 过滤本周到期的
      const now = new Date();
      const dayOfWeek = now.getDay();
      const lastFriday = new Date(now.getTime() - ((dayOfWeek + 2) % 7) * 86400000);
      lastFriday.setHours(0, 0, 0, 0);
      const thisFriday = new Date(lastFriday.getTime() + 7 * 86400000);

      const filtered = extensions.filter((ext: any) => {
        const expDate = parseInt(ext.formData[LEAVE_EXTENSION_DATA_FIELDS.EXPIRATION_DATE] || '0');
        return expDate >= lastFriday.getTime() && expDate < thisFriday.getTime() + 86400000;
      });
      logger.log(`本周到期需通知: ${filtered.length} 条`);

      // 更新每条记录的实际余额并标记为已通知
      for (const ext of filtered) {
        try {
          const formData = ext.formData;
          const leaveCode = getLeaveCode(formData[LEAVE_EXTENSION_DATA_FIELDS.LEAVE_TYPE]);
          const userId = formData[LEAVE_EXTENSION_DATA_FIELDS.USER_ID];

          // 查询最新假期消费记录
          const leaveRecords = await this.attendanceService.getLeaveRecords(leaveCode, userId);
          const leaveDays = this.calculateUsedLeaveDays(leaveRecords);
          const extensionDays = parseFloat(formData[LEAVE_EXTENSION_DATA_FIELDS.DAYS]) - leaveDays;

          if (extensionDays <= 0) {
            logger.log(
              `跳过延期提醒回写: ${formData[LEAVE_EXTENSION_DATA_FIELDS.EMPLOYEE_NAME]} ` +
              `${formData[LEAVE_EXTENSION_DATA_FIELDS.LEAVE_TYPE]} 实际剩余${extensionDays}天`,
            );
            continue;
          }

          // 标记为已通知
          const searchCond = JSON.stringify([
            { key: LEAVE_EXTENSION_DATA_FIELDS.LEAVE_ID, value: formData[LEAVE_EXTENSION_DATA_FIELDS.LEAVE_ID], type: 'TEXT', operator: 'eq', componentName: 'TextField' },
          ]);

          await this.yidaService.createOrUpdateForm(
            FORM_UUIDS.LEAVE_EXTENSION_DATA,
            searchCond,
            JSON.stringify({
              ...formData,
              [LEAVE_EXTENSION_DATA_FIELDS.DAYS]: String(extensionDays),
              [LEAVE_EXTENSION_DATA_FIELDS.IS_NOTIFY]: 'Yes',
            }),
          );

          count++;
          logger.log(
            `假期延期提醒: ${formData[LEAVE_EXTENSION_DATA_FIELDS.EMPLOYEE_NAME]} ` +
            `${formData[LEAVE_EXTENSION_DATA_FIELDS.LEAVE_TYPE]} 需延期${extensionDays}天`,
          );
        } 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 calculateUsedLeaveDays(records: any[]): number {
    const filtered = records.filter(
      (r: any) => !r.cal_type && r.leave_record_type === 'leave' && r.leave_status !== 'refuse' && r.leave_status !== 'abort',
    );

    let total = 0;
    for (const r of filtered) {
      if (r.leave_status === 'revoke') {
        total -= (r.record_num_per_day || 0) / 100;
      } else {
        total += (r.record_num_per_day || 0) / 100;
      }
    }
    return total;
  }
}
