import { Logger } from '@nestjs/common';

export interface DingTalkCredentials {
  appKey: string;
  appSecret: string;
}

export interface DingTalkUserListResponse {
  errcode: number;
  errmsg: string;
  result: {
    has_more: boolean;
    next_cursor?: number;
    list: Array<{
      userid: string;
      name: string;
      mobile: string;
      dept_id_list: number[];
    }>;
  };
}

export function isDingTalkUserListResponse(value: unknown): value is DingTalkUserListResponse {
  if (!value || typeof value !== 'object' || !('errcode' in value)) return false;
  if (typeof value.errcode !== 'number') return false;
  if ('errmsg' in value && typeof value.errmsg !== 'string') return false;
  if (!('result' in value) || !value.result || typeof value.result !== 'object') {
    return value.errcode !== 0;
  }
  if (!('has_more' in value.result) || typeof value.result.has_more !== 'boolean') return false;
  if (!('list' in value.result) || !Array.isArray(value.result.list)) return false;
  return value.result.list.every(
    (item: Record<string, unknown>) =>
      item &&
      typeof item === 'object' &&
      'userid' in item &&
      typeof item.userid === 'string' &&
      'name' in item &&
      typeof item.name === 'string' &&
      'mobile' in item &&
      typeof item.mobile === 'string' &&
      'dept_id_list' in item &&
      Array.isArray(item.dept_id_list) &&
      item.dept_id_list.every((id) => typeof id === 'number'),
  );
}

/** 钉钉打卡结果 — 对齐 dws attendance check result */
export interface DingTalkAttendanceResult {
  userId: string;
  userName: string;
  workDate: string;
  timeResult: string;
  locationResult: string;
  planCheckTime: string;
  actualCheckTime: string;
  checkId: string;
  checkType: string;
  /** 钉钉返回的打卡来源，例如 ATM / USER / BEACON。 */
  sourceType: string;
  /** 部分钉钉租户会额外返回考勤机名称或编号。 */
  deviceName?: string;
  deviceId?: string;
}

/** 钉钉已审批通过的请假记录 — 对齐 dws 考勤数据中的审批单列表。 */
export interface DingTalkLeaveResult {
  userId: string;
  workDate: string;
  /** 钉钉审批单 ID */
  procInstId: string;
  /** 审批单类型名称，例如 请假 */
  tagName: string;
  /** 请假类型，例如 年假 / 事假 / 病假 */
  leaveType: string;
  beginTime: Date;
  endTime: Date;
  /** 审批完成时间；为 null 表示仍在审批中，不纳入结算 */
  approvedAt: Date | null;
  duration: string;
  durationUnit: string;
}

// ── 组织架构 API 类型 ──

export interface DingTalkDeptListResponse {
  errcode: number;
  result?: Array<{ dept_id: number; name: string; parent_id: number }>;
}

export interface DingTalkDeptGetResponse {
  errcode: number;
  result?: { name: string; parent_id: number };
}

export interface OrgDeptNode {
  id: number;
  name: string;
  parentId: number;
  children: OrgDeptNode[];
}

export interface OrgDeptNodeWithUsers extends OrgDeptNode {
  users: Array<{ userid: string; name: string; mobile: string; deptIds: number[] }>;
}

// ── 考勤排班 API 类型 ──

/** 班次卡段打卡时间 */
export interface DingTalkShiftTime {
  check_type: 'OnDuty' | 'OffDuty';
  across: number;
  check_time: string;
  begin_min?: number;
  end_min?: number;
  free_check?: boolean;
}

/** 班次卡段 */
export interface DingTalkShiftSection {
  times: DingTalkShiftTime[];
}

/** 班次配置 */
export interface DingTalkShiftSetting {
  is_flexible?: boolean;
  serious_late_minutes?: number;
  absenteeism_late_minutes?: number;
}

/** 创建/修改班次参数 */
export interface DingTalkShiftParams {
  id?: number;
  name: string;
  owner?: string;
  sections: DingTalkShiftSection[];
  setting?: DingTalkShiftSetting;
}

/** 班次摘要（查询返回） */
export interface DingTalkShiftSummary {
  id: number;
  name: string;
}

/** 考勤组成员 */
export interface DingTalkGroupMember {
  role: string;
  type: 'StaffMember' | 'DeptMember';
  user_id: string;
}

/** 创建考勤组参数 */
export interface DingTalkGroupParams {
  name: string;
  type: 'TURN';
  owner: string;
  members: DingTalkGroupMember[];
  shift_ids?: number[];
  enable_emp_select_class?: boolean;
  disable_check_without_schedule?: boolean;
  disable_check_when_rest?: boolean;
  /** 关闭外勤、定位、Wi-Fi 和手机蓝牙打卡，仅保留考勤机打卡入口 */
  attendance_machine_only?: boolean;
}

/** 修改考勤组参数 */
export interface DingTalkGroupUpdateParams extends DingTalkGroupParams {
  id: number;
}

/** 考勤组摘要（查询返回） */
export interface DingTalkGroupSummary {
  group_id: number;
  group_name: string;
  type: string;
  member_count: number;
}

/** 排班参数（单条） */
export interface DingTalkScheduleItem {
  userid: string;
  work_date: number;
  shift_id: number;
  is_rest?: boolean;
}

/** 排班查询结果 */
export interface DingTalkScheduleResult {
  userid: string;
  work_date: string;
  shift_id: number;
  is_rest: string;
  check_type: string;
  plan_check_time: string;
  group_id: number;
  id: number;
}

/** 子服务访问主服务状态/能力的共享上下文。 */
export interface DingTalkServiceContext {
  accessToken: string | null;
  accessTokenCredentialKey: string | null;
  tokenExpiresAt: number;
  apiRequestCount: number;
  readonly logger: Logger;
  isConfigured(): Promise<boolean>;
  getAccessToken(): Promise<string>;
  rateLimit(): Promise<void>;
}
