/**
 * Mobile Water Log — formatting helpers.
 *
 * Pure functions, no React. Used by the PIN, headgate list, and log
 * screens for consistent display of timestamps, units, and "geocode"
 * secondary text.
 *
 * Functions that emit user-facing strings accept a `Lang` so they
 * localize correctly (en / es). Defaults to `"en"` for back-compat
 * with any code path that hasn't been threaded through `useLang()`.
 */

import { displayUnit, getT, type Lang } from "@/lib/water-log/i18n";

/**
 * Format an ISO timestamp as a short relative phrase.
 *   "just now"     < 45s
 *   "5m ago"       < 60m
 *   "3h ago"       < 24h
 *   "Mar 14"       same calendar year
 *   "Mar 14 '25"   previous calendar year
 */
export function formatRelativeTime(
  iso: string | null,
  lang: Lang = "en",
): string {
  const t = getT(lang).format;
  if (!iso) return t.neverLogged;
  const then = new Date(iso).getTime();
  if (Number.isNaN(then)) return t.neverLogged;
  const diffSec = Math.round((Date.now() - then) / 1000);
  if (diffSec < 45) return t.justNow;
  if (diffSec < 60 * 60) return t.minutesAgo(Math.round(diffSec / 60));
  if (diffSec < 60 * 60 * 24) return t.hoursAgo(Math.round(diffSec / 3600));
  const d = new Date(iso);
  const sameYear = d.getFullYear() === new Date().getFullYear();
  // Use Intl.DateTimeFormat with the appropriate locale. "es" covers
  // es-ES, es-MX, etc. for date format strings.
  const locale = lang === "es" ? "es" : "en-US";
  const date = d.toLocaleDateString(locale, {
    month: "short",
    day: "numeric",
  });
  return sameYear ? date : `${date} '${String(d.getFullYear()).slice(-2)}`;
}

/**
 * Format a Date as a 12-hour time suitable for the sticky log header
 * (e.g. "2:37 PM").
 */
export function formatClockTime(d: Date, lang: Lang = "en"): string {
  const locale = lang === "es" ? "es" : "en-US";
  return d.toLocaleTimeString(locale, {
    hour: "numeric",
    minute: "2-digit",
    hour12: true,
  });
}

/**
 * Format a Date as a long human label for the submit timestamp preview
 * (e.g. "Wed, Mar 14 · 2:37 PM" / "mié, mar 14 · 2:37 PM").
 */
export function formatLongTimestamp(d: Date, lang: Lang = "en"): string {
  const locale = lang === "es" ? "es" : "en-US";
  const date = d.toLocaleDateString(locale, {
    weekday: "short",
    month: "short",
    day: "numeric",
  });
  return `${date} · ${formatClockTime(d, lang)}`;
}

/**
 * Format a measurement for the success-screen recap. Strips trailing
 * zeros and clamps to 4 significant fraction digits so "12.5000"
 * becomes "12.5". For integer-count units ("holes") we render the
 * whole-number form ("12" not "12.0").
 */
export function formatMeasurement(value: number, integer = false): string {
  if (!Number.isFinite(value)) return "0";
  if (integer) return String(Math.round(value));
  const fixed = value.toFixed(4);
  return fixed.replace(/\.?0+$/, "") || "0";
}

/**
 * Decide what to show under a headgate name. The schema doesn't have
 * a dedicated `geocode` column, so we fall back through the available
 * context fields in priority order:
 *   1. headgate.notes         — admin's free-text label
 *   2. status label           — localized "Open · Ready to log" / etc.
 *   3. raw status string
 */
export function headgateSubtitle(
  h: FieldHeadgateLike,
  lang: Lang = "en",
): string {
  if (h.notes && h.notes.trim()) return h.notes.trim();
  const t = getT(lang).status;
  const status = (h.status ?? "open").toLowerCase();
  if (status === "open") return t.openReady;
  if (status === "closed") return t.closed;
  if (status === "maintenance") return t.maintenance;
  return status;
}

/**
 * Display label for a headgate's stored unit (e.g. "CFS" / "hoyos"),
 * localized. Falls back to the raw string for unknown units.
 */
export function formatUnit(unit: string, lang: Lang): string {
  return displayUnit(unit, lang);
}

/** Type alias used by `headgateSubtitle` — accepts any object with the
 *  relevant subset, so callers don't need the full FieldHeadgate type. */
type FieldHeadgateLike = {
  notes?: string | null;
  status?: string | null;
};