/**
 * TimezonePicker — grouped IANA timezone selector (timezone-handling, wave-11 leaf-E).
 *
 * Uses Intl.supportedValuesOf('timeZone') to list all zones supported by the
 * browser runtime. Falls back to a curated short-list when the API is absent
 * (Safari ≤ 14, Firefox < 78).
 *
 * Groups zones by continent prefix for easier navigation.
 *
 * Props:
 *   value        — currently selected IANA timezone string
 *   onChange     — called with the new timezone string
 *   id           — id for the underlying <select> (for <label> association)
 *   disabled     — disables the select
 *   className    — extra className for the wrapper
 */
import * as React from 'react'
import { listSupportedTimezones, groupTimezonesByContinent } from '@zync/types'

// ── Continent labels ──────────────────────────────────────────────────────────

const CONTINENT_LABELS: Record<string, string> = {
  Africa:   'Africa',
  America:  'Americas',
  Antarctica: 'Antarctica',
  Arctic:   'Arctic',
  Asia:     'Asia',
  Atlantic: 'Atlantic',
  Australia: 'Australia & Pacific',
  Europe:   'Europe',
  Indian:   'Indian Ocean',
  Pacific:  'Pacific',
  Other:    'Other / UTC',
  Etc:      'UTC offsets',
  UTC:      'UTC offsets',
}

// ── Lazy-computed data ────────────────────────────────────────────────────────

let _grouped: Record<string, string[]> | null = null

function getGrouped(): Record<string, string[]> {
  if (!_grouped) {
    _grouped = groupTimezonesByContinent(listSupportedTimezones())
  }
  return _grouped
}

// ── Component ─────────────────────────────────────────────────────────────────

export interface TimezonePickerProps {
  value: string
  onChange: (tz: string) => void
  id?: string
  disabled?: boolean
  className?: string
}

export function TimezonePicker({
  value,
  onChange,
  id,
  disabled = false,
  className,
}: TimezonePickerProps): React.ReactElement {
  const grouped = getGrouped()
  const continents = Object.keys(grouped).sort((a, b) => {
    // Put Asia/Jerusalem region first
    if (a === 'Asia') return -1
    if (b === 'Asia') return 1
    return a.localeCompare(b)
  })

  return (
    <select
      id={id}
      value={value}
      onChange={(e) => onChange(e.target.value)}
      disabled={disabled}
      className={['select', className].filter(Boolean).join(' ')}
    >
      {continents.map((continent) => (
        <optgroup key={continent} label={CONTINENT_LABELS[continent] ?? continent}>
          {(grouped[continent] ?? []).map((tz) => (
            <option key={tz} value={tz}>
              {/* Show offset + city name */}
              {formatTimezoneOption(tz)}
            </option>
          ))}
        </optgroup>
      ))}
    </select>
  )
}

// ── Helpers ───────────────────────────────────────────────────────────────────

function formatTimezoneOption(tz: string): string {
  try {
    const now = new Date()
    const offset = new Intl.DateTimeFormat('en', {
      timeZone: tz,
      timeZoneName: 'shortOffset',
    })
      .formatToParts(now)
      .find((p) => p.type === 'timeZoneName')?.value ?? ''

    // Strip continent prefix for display: "Asia/Jerusalem" → "Jerusalem"
    const city = tz.includes('/') ? tz.slice(tz.lastIndexOf('/') + 1).replace(/_/g, ' ') : tz
    return `(${offset}) ${city}`
  } catch {
    return tz
  }
}
