import {
  EXECUTION_OUTCOME_META,
  ExecutionOutcome,
  BREAKER_SUPPRESS_DAYS,
} from '@pac/types';

const DAY_MS = 86_400_000;

/**
 * 计算 execution 回写后的 snoozedUntil(召回冷静期 / 终态抑制窗)—— 纯函数,便于单测。
 *
 * 优先级(高 → 低):
 *   1. 熔断(breakerTripped):连续未接通累计达上限强制 abandoned → 固定短冷静期(30d),
 *      不是"拒绝",换天再试 / 后续可接换渠道。优先于 outcome 自身策略。
 *   2. outcome 固定抑制窗(EXECUTION_OUTCOME_META.suppressDays):
 *      明确拒绝/近期不考虑=90d、成功转化/客服放弃=60d、外院/无效=永久。
 *   3. keep 类无固定抑制窗但带了 scheduledNextAt(约定回访/考虑中等)→ 到该时间前 snooze。
 *   4. 其余(no_answer / sms_sent 等)→ null,不 snooze,维持现状很快再试。
 *
 * @returns snoozedUntil Date,或 null(不抑制)
 */
export function resolveSnoozedUntil(params: {
  outcome: string;
  breakerTripped: boolean;
  scheduledNextAt?: string | null;
  now: Date;
}): Date | null {
  const { outcome, breakerTripped, scheduledNextAt, now } = params;

  if (breakerTripped) {
    return new Date(now.getTime() + BREAKER_SUPPRESS_DAYS * DAY_MS);
  }

  const meta = EXECUTION_OUTCOME_META[outcome as ExecutionOutcome];
  if (meta?.suppressDays != null) {
    return new Date(now.getTime() + meta.suppressDays * DAY_MS);
  }

  if (scheduledNextAt) {
    return new Date(scheduledNextAt);
  }

  return null;
}
