/**
 * 上次到诊的时间分档 —— 圈人筛选的「上次时间」维度取值。
 *
 * 业务口径(2026-07-29):0-3 / 3-6 / 6-12 / 12-18 / 18 个月以上。
 * 边界天数在 visit-recency.feature.ts 的 BUCKET_EDGES,两处要一起改。
 *
 * ⚠️ 与「生命周期」(潜客/新客/…/流失客)信息高度重叠 —— 后者本质也是 recency 分档,
 *   只是掺了首诊时间与就诊次数。业务这次要下线生命周期、改用这个更直白的口径。
 *   两者并存时别让客服以为是两件事。
 */
export const VISIT_RECENCY_BUCKETS = [
  { value: '0_3m', zh: '0-3 个月', hint: '近三个月来过' },
  { value: '3_6m', zh: '3-6 个月', hint: '上次到诊在 3 到 6 个月前' },
  { value: '6_12m', zh: '6-12 个月', hint: '上次到诊在半年到一年前' },
  { value: '12_18m', zh: '12-18 个月', hint: '上次到诊在一年到一年半前' },
  { value: '18m_plus', zh: '18 个月以上', hint: '一年半以上没来过' },
] as const;

/**
 * 分档 code → `last_visit_at` 的日期区间(半开区间 [gte, lt))。
 *
 * ⭐ 现算而不是存死分档:存 bucket 会随时间过期(今天 2 个月、下个月就 3 个月),
 *   得配一整套「到期重算」机械;存日期 + 查询时现算区间,永远准,零维护。
 * 未知 code → null(调用方丢弃该条,不产生"筛了个寂寞"的全集查询)。
 */
export function visitRecencyRange(
  bucket: string,
  now: Date,
): { gte?: Date; lt?: Date } | null {
  const daysAgo = (d: number) => new Date(now.getTime() - d * 86400_000);
  switch (bucket) {
    case '0_3m':
      return { gte: daysAgo(90) };
    case '3_6m':
      return { gte: daysAgo(180), lt: daysAgo(90) };
    case '6_12m':
      return { gte: daysAgo(365), lt: daysAgo(180) };
    case '12_18m':
      return { gte: daysAgo(547), lt: daysAgo(365) }; // 18 个月 ≈ 547 天
    case '18m_plus':
      return { lt: daysAgo(547) };
    default:
      return null;
  }
}
