import { useCallback, useEffect, useState } from 'react';

function formatLocalTime(timezone: string, hour12: boolean): string | undefined {
  try {
    return new Intl.DateTimeFormat('en', {
      timeZone: timezone,
      hour: 'numeric',
      minute: '2-digit',
      hour12,
    }).format(new Date());
  } catch {
    return undefined;
  }
}

function getTimezoneAbbr(timezone: string): string | undefined {
  try {
    return new Intl.DateTimeFormat('en', {
      timeZone: timezone,
      timeZoneName: 'short',
    })
      .formatToParts(new Date())
      .find((p) => p.type === 'timeZoneName')?.value;
  } catch {
    return undefined;
  }
}

export type LocalTimeInfo = {
  time: string;
  abbr: string | undefined;
};

/**
 * Returns the current time (and timezone abbreviation) in the given IANA
 * timezone, updated every minute. Returns undefined when timezone is
 * undefined or invalid.
 */
export function useLocalTime(
  timezone: string | undefined,
  hour12: boolean = true,
): LocalTimeInfo | undefined {
  const compute = useCallback((): LocalTimeInfo | undefined => {
    if (!timezone) return undefined;
    const time = formatLocalTime(timezone, hour12);
    if (!time) return undefined;
    return { time, abbr: getTimezoneAbbr(timezone) };
  }, [timezone, hour12]);

  const [info, setInfo] = useState<LocalTimeInfo | undefined>(compute);

  useEffect(() => {
    setInfo(compute());
    const id = window.setInterval(() => setInfo(compute()), 60_000);
    return () => window.clearInterval(id);
  }, [compute]);

  return info;
}
