import type {
  DingTalkAttendanceResult,
  DingTalkServiceContext,
} from './dingtalk.types';

export class DingTalkAttendanceClient {
  constructor(private readonly context: DingTalkServiceContext) {}

  async fetchAttendanceResults(params: {
    startDate: string;
    endDate: string;
    userIds?: string[];
  }): Promise<DingTalkAttendanceResult[]> {
    if (!(await this.context.isConfigured())) throw new Error('DingTalk not configured');
    if (!params.userIds?.length) throw new Error('钉钉考勤 userIds 不能为空');
    if (params.userIds.length > 50) throw new Error('钉钉考勤单次最多查询50人');
    const token = await this.context.getAccessToken();

    const dateFrom = params.startDate.includes(' ') ? params.startDate : `${params.startDate} 00:00:00`;
    const dateTo = params.endDate.includes(' ') ? params.endDate : `${params.endDate} 23:59:59`;

    const body: Record<string, unknown> = {
      checkDateFrom: dateFrom,
      checkDateTo: dateTo,
    };
    body.userIds = params.userIds;

    const res = await fetch(
      `https://oapi.dingtalk.com/attendance/listRecord?access_token=${token}`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      },
    );
    const data = await res.json() as {
      errcode: number; errmsg: string;
      recordresult?: Array<{
        id: number; userId: string; workDate: number;
        userCheckTime: number; sourceType: string;
        checkType?: string; timeResult?: string;
        locationResult?: string; locationMethod?: string;
        userAddress?: string; userLongitude?: number; userLatitude?: number;
        deviceName?: string; deviceId?: string | number; deviceSN?: string | number;
        attendanceMachineName?: string; attendanceMachineId?: string | number;
      }>;
    };
    if (data.errcode !== 0) throw new Error(`钉钉考勤获取失败: ${data.errmsg}`);

    const records = data.recordresult ?? [];

    return records.map((r) => ({
      userId: r.userId,
      userName: '',
      workDate: new Date(r.workDate + 8 * 60 * 60 * 1000).toISOString().slice(0, 10),
      timeResult: r.timeResult ?? r.sourceType ?? '',
      locationResult: r.locationResult ?? r.locationMethod ?? r.userAddress ?? '',
      planCheckTime: '',
      actualCheckTime: new Date(r.userCheckTime).toISOString(),
      checkId: String(r.id),
      checkType: r.checkType ?? '',
      sourceType: r.sourceType ?? '',
      deviceName: r.deviceName ?? r.attendanceMachineName,
      deviceId: String(r.deviceId ?? r.attendanceMachineId ?? r.deviceSN ?? '') || undefined,
    }));
  }
}
