/**
 * datetime.ts — shared time formatting utilities for Energy/Modbus displays.
 *
 * Root cause addressed: the backend stores timestamps as naive ISO strings without
 * timezone info (e.g. "2026-06-24T10:27:00", no Z/offset). Browsers parse these as
 * *local* time by default, but the values are actually UTC. We fix this by treating
 * any string that lacks a timezone marker as UTC (appending "Z" before parsing).
 *
 * Scope: Energy domain + Modbus meter readings ONLY.
 * Do NOT use these for Location/Poo timestamps — those already use raw strings.
 */

/**
 * Timezone-marker detection regex.
 * Matches a trailing Z (any case) or a UTC offset like +05:30, -08:00, +0530, -0800.
 */
const TZ_MARKER_RE = /([zZ]|[+-]\d{2}:?\d{2})$/

/**
 * Parse a backend ISO timestamp, treating strings without a timezone marker as UTC.
 *
 * - If the string already has Z / +HH:MM / -HHMM → parse as-is.
 * - If no timezone marker → append "Z" so the browser reads it as UTC.
 * - Pure date strings like "2026-06-24" (no 'T') → parse as-is (Date handles them).
 * - Invalid / empty input → returns an Invalid Date (does NOT throw).
 */
export function parseBackendTimestamp(iso: string): Date {
  if (!iso || typeof iso !== 'string') return new Date(NaN)

  const hasTComponent = iso.includes('T')

  if (hasTComponent && !TZ_MARKER_RE.test(iso)) {
    // No timezone marker on a datetime string — treat as UTC.
    return new Date(iso + 'Z')
  }

  return new Date(iso)
}

// ---------------------------------------------------------------------------
// Locale formatting helpers
// All use the browser's local timezone (no explicit timeZone option) and
// 24-hour clock (hour12: false).
// ---------------------------------------------------------------------------

/**
 * Local date + time, 24-hour, e.g. "6/24/2026, 12:27:00".
 * Used for: LatestReadingsCard recorded_at, DSMR recorded_at, chart tooltips,
 *           meter readings table (RecordsPage), cost period detail table.
 */
export function formatLocalDateTime(iso: string): string {
  try {
    const d = parseBackendTimestamp(iso)
    if (isNaN(d.getTime())) return iso
    return d.toLocaleString(undefined, {
      hour12: false,
      year: 'numeric',
      month: 'numeric',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
    })
  } catch {
    return iso
  }
}

/**
 * Local time only, compact HH:mm (24-hour), e.g. "12:27".
 * Used for: chart X-axis ticks, cost chart X-axis, Tibber price chart X-axis.
 */
export function formatLocalTime(iso: string): string {
  try {
    const d = parseBackendTimestamp(iso)
    if (isNaN(d.getTime())) return iso
    return d.toLocaleTimeString(undefined, {
      hour12: false,
      hour: '2-digit',
      minute: '2-digit',
    })
  } catch {
    return iso
  }
}

/**
 * Local date only, e.g. "6/1/2026" or "2026-06-01" depending on locale.
 * Used for: contract effective_from / effective_to dates, contract created_at.
 */
export function formatLocalDate(iso: string): string {
  try {
    const d = parseBackendTimestamp(iso)
    if (isNaN(d.getTime())) return iso
    return d.toLocaleDateString(undefined, {
      year: 'numeric',
      month: 'numeric',
      day: 'numeric',
    })
  } catch {
    return iso
  }
}
