/**
 * Asia/Taipei（UTC+8，無日光節約）時間顯示 helper（fix/console-truth-audit，2026-07-07）
 *
 * 為什麼存在：console 各頁原本用瀏覽器本地時區（`Date#getFullYear/getMonth/...`）渲染
 * created_at / last_used_at / 刷新時間戳——顯示結果隨看的裝置漂移（換個時區的裝置就換一個
 * 日期），且與駕駛艙 #36 的「台北日曆日」判定（`taipeiDayKey`）不是同一套。本檔把
 * 「epoch ms → 台北牆鐘」收斂成唯一實作：
 *   - server 側（TS）：dashboard-data 的台北日判定 import 這裡。
 *   - client 側（頁面 inline JS）：console.ts / console-dashboard.ts 的 HTML 內嵌
 *     `TAIPEI_CLIENT_JS`（同邏輯的 ES5 版）。等價性由 tests/taipei-time.test.ts 用
 *     `new Function` 求值 client 版與 server 版逐案對照，防兩份漂移。
 *
 * 台北無 DST、固定 +8——用「UTC getter ＋固定位移」即可，不需要 Intl 時區資料庫。
 */

export const TAIPEI_OFFSET_MS = 8 * 3600 * 1000;

function pad2(n: number): string {
  return String(n).padStart(2, '0');
}

/** 台北日曆日 key（'YYYY-MM-DD'）。#36 駕駛艙「這筆是不是今天寫的」判定用。 */
export function taipeiDayKey(ms: number): string {
  return new Date(ms + TAIPEI_OFFSET_MS).toISOString().slice(0, 10);
}

/** 台北日期字串 'YYYY-MM-DD'（顯示用，同 taipeiDayKey，語意別名）。 */
export function taipeiDateStr(ms: number): string {
  return taipeiDayKey(ms);
}

/** 台北日期＋時分 'YYYY-MM-DD HH:MM'。 */
export function taipeiDateTimeStr(ms: number): string {
  const d = new Date(ms + TAIPEI_OFFSET_MS);
  return `${taipeiDayKey(ms)} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())}`;
}

/** 台北時分秒 'HH:MM:SS'（駕駛艙「上次刷新」戳記用）。 */
export function taipeiTimeStr(ms: number): string {
  const d = new Date(ms + TAIPEI_OFFSET_MS);
  return `${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())}:${pad2(d.getUTCSeconds())}`;
}

/**
 * client 版（ES5，內嵌進 console 頁 inline <script>）。與上面 server 版同邏輯——
 * 測試以 `new Function(TAIPEI_CLIENT_JS + 'return {...}')()` 求值後逐案對照 server 版，
 * 任一份改了另一份沒跟上會直接紅。頁面內以 `${TAIPEI_CLIENT_JS}` 插入，故這裡不用
 * template literal 語法（頁面本身是 template string，反引號會提前終結）。
 */
export const TAIPEI_CLIENT_JS = [
  "var TAIPEI_OFFSET_MS = 28800000; // UTC+8，台北無 DST",
  "function tpePad(n) { n = String(n); return n.length < 2 ? '0' + n : n; }",
  "function taipeiDayKey(ms) { return new Date(ms + TAIPEI_OFFSET_MS).toISOString().slice(0, 10); }",
  "function taipeiDateStr(ms) { return taipeiDayKey(ms); }",
  "function taipeiDateTimeStr(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return taipeiDayKey(ms) + ' ' + tpePad(d.getUTCHours()) + ':' + tpePad(d.getUTCMinutes()); }",
  "function taipeiTimeStr(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return tpePad(d.getUTCHours()) + ':' + tpePad(d.getUTCMinutes()) + ':' + tpePad(d.getUTCSeconds()); }",
  "function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return { month: d.getUTCMonth() + 1, day: d.getUTCDate() }; }",
].join('\n');
