1import type { TimestampFormat } from "@t3tools/contracts/settings";
2import {
3 resolveSnoozePresets as resolveSharedSnoozePresets,
4 snoozeWakeLabel,
5 type SnoozePreset,
6} from "@t3tools/client-runtime/state/thread-settled";
7
8import { formatShortTimestamp, parseTimestampDate } from "../timestampFormat";
9
10export { snoozeWakeLabel, type SnoozePreset };
11
12const DAY_MS = 24 * 60 * 60 * 1_000;
13
14function timeOfDayLabel(date: Date, timestampFormat: TimestampFormat): string {
15 return formatShortTimestamp(date.toISOString(), timestampFormat);
16}
17
18export function resolveSnoozePresets(
19 now: Date,
20 timestampFormat: TimestampFormat,
21): ReadonlyArray<SnoozePreset> {
22 return resolveSharedSnoozePresets(now).map((preset) => {
23 const wake = parseTimestampDate(preset.snoozedUntil);
24 if (wake === null) return preset;
25 const time = timeOfDayLabel(wake, timestampFormat);
26 return {
27 ...preset,
28 whenLabel:
29 preset.id === "next-week"
30 ? `${wake.toLocaleDateString(undefined, { weekday: "short" })} ${time}`
31 : time,
32 };
33 });
34}
35
36/**
37 * Human wake time for menus and toasts: "tomorrow 9:00", "Mon 9:00",
38 * "17:30" (today).
39 */
40export function snoozeWakeDescription(
41 snoozedUntil: string,
42 now: Date,
43 timestampFormat: TimestampFormat,
44): string {
45 const wake = parseTimestampDate(snoozedUntil);
46 if (wake === null) return "";
47 const time = timeOfDayLabel(wake, timestampFormat);
48 const startOfToday = new Date(now);
49 startOfToday.setHours(0, 0, 0, 0);
50 const dayDelta = Math.floor((wake.getTime() - startOfToday.getTime()) / DAY_MS);
51 if (dayDelta === 0) return time;
52 if (dayDelta === 1) return `tomorrow ${time}`;
53 const weekday = wake.toLocaleDateString(undefined, { weekday: "short" });
54 if (dayDelta < 7) return `${weekday} ${time}`;
55 const date = wake.toLocaleDateString(undefined, { month: "short", day: "numeric" });
56 return `${date}, ${time}`;
57}