/**
 * 浏览器 + Node 双端可用的格式化工具(零 node 依赖)。
 *
 * 设计纪律:
 *   - 这里只放 pure-JS 的格式化 / 掩码 / 时间相对值
 *   - 任何用到 node:crypto / node:fs 的工具放在 ../index.ts(Node-only)
 */

/**
 * 手机号脱敏:前 3 + 4 个 * + 后 4。长度不足时原样返回。
 *   13855612937 → 138****2937
 */
export function maskPhone(phone: string | null | undefined): string {
  if (!phone || phone.length < 7) return phone ?? '';
  return phone.slice(0, 3) + '****' + phone.slice(-4);
}

/**
 * 姓名脱敏:首字 + 余下用 * 替代。
 *   张志远 → 张**     单字保留原值
 */
export function maskName(name: string | null | undefined): string {
  if (!name) return '';
  if (name.length <= 1) return name;
  return name[0] + '*'.repeat(name.length - 1);
}

/**
 * 相对时间("3 分钟前 / 2 小时前 / 5 天前 / 刚刚")— 中文展示。
 * @param d 目标时间
 * @param now 参考时间(默认 Date.now)— 便于测试注入
 */
export function fmtRel(d: Date | string, now: Date = new Date()): string {
  const target = typeof d === 'string' ? new Date(d) : d;
  const ms = now.getTime() - target.getTime();
  const mins = Math.round(ms / 60_000);
  if (mins < 1) return '刚刚';
  if (mins < 60) return `${mins} 分钟前`;
  const hrs = Math.round(mins / 60);
  if (hrs < 24) return `${hrs} 小时前`;
  const days = Math.round(hrs / 24);
  return `${days} 天前`;
}

/**
 * `YYYY-MM-DD`(UTC slice)
 */
export function fmtDate(d: Date | string): string {
  const target = typeof d === 'string' ? new Date(d) : d;
  return target.toISOString().slice(0, 10);
}

/**
 * `YYYY.MM`(year + month,主要用于治疗链节点标签)
 */
export function fmtYearMonth(d: Date | string): string {
  const target = typeof d === 'string' ? new Date(d) : d;
  return `${target.getFullYear()}.${String(target.getMonth() + 1).padStart(2, '0')}`;
}

/**
 * `YYYY.MM.DD`(year + month + day,治疗链节点 / fact 时间轴精确日期)
 */
export function fmtYearMonthDay(d: Date | string): string {
  const target = typeof d === 'string' ? new Date(d) : d;
  return `${target.getFullYear()}.${String(target.getMonth() + 1).padStart(2, '0')}.${String(target.getDate()).padStart(2, '0')}`;
}

/**
 * 周岁年龄(birthDate → 整岁),按月/日精确扣减未满周岁。
 * @param now 参考时间(默认当下)— 便于测试注入
 */
export function calcAge(birthDate: Date | string, now: Date = new Date()): number {
  const b = typeof birthDate === 'string' ? new Date(birthDate) : birthDate;
  let age = now.getFullYear() - b.getFullYear();
  const m = now.getMonth() - b.getMonth();
  if (m < 0 || (m === 0 && now.getDate() < b.getDate())) age--;
  return age;
}
