/**
 * JST の `YYYY-MM-DD` の範囲を、★Prisma の `where` に渡せる「DBの壁時計値」★ に変換する
 * （指示書AC 段階2 D-2 / ★C-6★）。
 *
 * ------------------------------------------------------------------------
 * ★★なぜ純粋関数に切り出したのか — ローカルDBではこの間違いを検出できないから★★
 * ------------------------------------------------------------------------
 * `clean_timetables.start_at` は DATETIME で、中身は ★日本時間の壁時計値★ です
 * （TeamWorks 第8回 A2 / D-115 / `fromDbJst()` の docstring）。
 * 一方 `parseDate("2026-09-08")`（`lib/clean-logs/query.ts`）が返すのは ★真の瞬間★ です。
 *
 * ```
 * parseDate("2026-09-08")          = 2026-09-07T15:00:00.000Z （真の瞬間）
 * toDbJst(parseDate("2026-09-08")) = 2026-09-08T00:00:00.000Z （DBの壁時計値として渡せる形）
 * ```
 *
 * ★★この2つをそのまま比較すると9時間ずれ、境界の行が静かに消えます★★。
 *
 * ★★ところがローカルDB（`dwatch_local`）ではこの間違いが1件も表に出ません★★ —
 *   `clean_timetables` 1,044行の `start_at`（壁時計）は ★0時:210 / 1時:516 / 2時:288 / 3時:30★ で、
 *   ★15時以降が0件★。9時間ずらしても日付が変わらない時間帯にしかデータがないため、
 *   ★補正を忘れても件数が1件も変わりません★（指示書AC C-6 の実測）。
 *   ★★だからこの関数には「壁時計 20:00 の清掃」を含む合成データの単体テストがあります★★
 *   （`lib/db/__tests__/date-range.test.ts`）。★そのテストを消さないこと★。
 */
import { parseDate } from "@/lib/clean-logs/query";
import { toDbJst } from "@/lib/format/date";

/** Prisma の `where.start_at` にそのまま展開できる形（`gte` / `lt` は無ければキーごと無い） */
export interface DbDateRange {
  gte?: Date;
  lt?: Date;
}

/** 1日（ミリ秒）。`to` を「その日を含む」＝「翌日 00:00 未満」にするために足す */
const ONE_DAY_MS = 86_400_000;

/**
 * @param from JST の `YYYY-MM-DD`。★下限なしは `null`★
 * @param to   JST の `YYYY-MM-DD`。★上限なしは `null`★。★その日を**含む**★
 * @returns `{ gte?, lt? }`。★どちらも無ければ空オブジェクト★（呼び出し側は
 *   `start_at` のキーごと付けないこと。`start_at: {}` は Prisma では条件なしだが、
 *   ★キーを付けないほうが生成SQLを読んだときに意図が分かる★）
 *
 * ★形式が不正な文字列（`parseDate()` が `null` を返すもの）は「指定なし」として扱う★ —
 *   ★★ここに検証を持たせないこと★★。入口の検証は `parseCleanLogQuery()` の仕事で
 *   （422 を返す。指示書AC §E-2）、そこを通った値しかここには来ない。
 *   ★2箇所で検証すると、片方だけ緩めたときに気づけない★。
 */
export function dbDateRange(from: string | null, to: string | null): DbDateRange {
  const range: DbDateRange = {};

  const fromDate = parseDate(from);
  if (fromDate) {
    // ★★必ず `toDbJst()` を通す★★（通さないと9時間ずれる。C-6）
    range.gte = toDbJst(fromDate);
  }

  const toDate = parseDate(to);
  if (toDate) {
    // ★`to` はその日を**含む**ので「翌日 00:00 未満」にする★。
    //   ★★`lte: その日 23:59:59` にしないこと★★ — `start_at` は DATETIME(0) なので
    //   いまは秒までだが、桁が増えたときに 23:59:59.5 の行が静かに落ちる。
    range.lt = toDbJst(new Date(toDate.getTime() + ONE_DAY_MS));
  }

  return range;
}
