/**
 * 将分钟数转换为 “xx天yy小时zz分钟” 格式字符串
 * @param minutes 要转换的分钟数
 * @returns 格式例如："1天2小时30分钟"
 */
export function minutesToDayHourMinute(minutes: number): string {
  if (!Number.isFinite(minutes) || Number.isNaN(minutes) || minutes <= 0) {
    return '0分钟';
  }

  const total = Math.floor(minutes);
  const days = Math.floor(total / 1440); // 24*60
  const hours = Math.floor((total % 1440) / 60);
  const mins = total % 60;

  const parts: string[] = [];
  if (days > 0) {
    parts.push(`${days}天`);
  }
  if (hours > 0) {
    parts.push(`${hours}小时`);
  }
  // 当所有其他部分都为0时，仍需显示分钟（0分钟）
  if (mins > 0 || parts.length === 0) {
    parts.push(`${mins}分钟`);
  }

  return parts.join('');
}

/**
 * 将毫秒数转换为 “xx天yy小时zz分钟aa秒” 格式字符串
 * @param milliseconds 要转换的毫秒数
 * @returns 格式例如："1天2小时30分钟10秒"
 */
export function millisecondsToDayHourMinuteSecond(milliseconds: number): string {
  if (!Number.isFinite(milliseconds) || Number.isNaN(milliseconds) || milliseconds <= 0) {
    return '0秒';
  }

  const totalSeconds = Math.floor(milliseconds / 1000);
  const days = Math.floor(totalSeconds / 86400); // 24*60*60
  const hours = Math.floor((totalSeconds % 86400) / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;

  const parts: string[] = [];
  if (days > 0) {
    parts.push(`${days}天`);
  }
  if (hours > 0) {
    parts.push(`${hours}小时`);
  }
  if (minutes > 0) {
    parts.push(`${minutes}分钟`);
  }
  if (seconds > 0 || parts.length === 0) {
    parts.push(`${seconds}秒`);
  }

  return parts.join('');
}

/**
 * 计算两个时间字符串之间相差的天数
 * 输入格式：'YYYY-MM-DD HH:mm'
 * 如果结果为整数则返回整数，例如 2
 * 如果有小数则保留两位小数，例如 1.25 -> 1.25
 * 返回类型：number（若输入无效则返回 0）
 */
export function daysBetween(start: string | undefined, end: string | undefined): number {
  if (!start || !end || typeof start !== 'string' || typeof end !== 'string') {
    return 0;
  }

  // 转换为 ISO-like 字符串，添加秒以确保兼容解析
  const toIso = (s: string) => `${s.replace(' ', 'T')}:00`;

  const d1 = new Date(toIso(start));
  const d2 = new Date(toIso(end));

  if (Number.isNaN(d1.getTime()) || Number.isNaN(d2.getTime())) {
    return 0;
  }

  const diffMs = Math.abs(d2.getTime() - d1.getTime());
  const days = diffMs / (24 * 60 * 60 * 1000);

  const rounded = Math.round(days * 100) / 100;
  if (Number.isInteger(rounded)) {
    return rounded;
  }
  return Number(rounded.toFixed(2));
}

export function isEmpty(val: any): boolean {
  if (val === null || val === undefined || typeof val === 'undefined') {
    return true;
  }
  if (isArray(val) || isString(val)) {
    return val.length === 0;
  }

  if (val instanceof Map || val instanceof Set) {
    return val.size === 0;
  }

  if (isObject(val)) {
    return Object.keys(val).length === 0;
  }

  return false;
}

export function isArray(val: any) {
  return val && Array.isArray(val);
}

export function is(val: unknown, type: string) {
  return toString.call(val) === `[object ${type}]`;
}

export function isString(val: unknown): boolean {
  return is(val, 'String');
}

export function isObject(val: any) {
  return val !== null && is(val, 'Object');
}
