/**
 * TimezoneProvider.
 *
 * Fetches the IANA timezone configured during the BanGUI setup wizard and
 * makes it available throughout the component tree via React Context.
 *
 * The timezone is fetched once at mount.  On error or before the initial
 * fetch resolves, the value defaults to ``"UTC"`` so date-formatting callers
 * always receive a safe fallback.
 */

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import { fetchTimezone } from "../api/setup";

// ---------------------------------------------------------------------------
// Context definition
// ---------------------------------------------------------------------------

interface TimezoneContextValue {
  /** IANA timezone string, e.g. ``"Europe/Berlin"`` or ``"UTC"``. */
  timezone: string;
}

const TimezoneContext = createContext<TimezoneContextValue>({ timezone: "UTC" });

// ---------------------------------------------------------------------------
// Provider
// ---------------------------------------------------------------------------

export interface TimezoneProviderProps {
  children: React.ReactNode;
}

/**
 * Wrap the application (or authenticated shell) with this provider to make the
 * configured timezone available via {@link useTimezone}.
 *
 * @example
 * ```tsx
 * <TimezoneProvider>
 *   <App />
 * </TimezoneProvider>
 * ```
 */
export function TimezoneProvider({
  children,
}: TimezoneProviderProps): React.JSX.Element {
  const [timezone, setTimezone] = useState<string>("UTC");

  const load = useCallback((): void => {
    fetchTimezone()
      .then((resp) => { setTimezone(resp.timezone); })
      .catch(() => {
        // Silently fall back to UTC; the backend may not be reachable yet.
      });
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  const value = useMemo<TimezoneContextValue>(() => ({ timezone }), [timezone]);

  return (
    <TimezoneContext.Provider value={value}>{children}</TimezoneContext.Provider>
  );
}

// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------

/**
 * Return the IANA timezone string configured during setup.
 *
 * Must be used inside a {@link TimezoneProvider}.
 *
 * @returns The configured timezone, e.g. ``"Europe/Berlin"``.
 *
 * @example
 * ```tsx
 * const { timezone } = useTimezone();
 * const label = formatDate(item.created_at, timezone);
 * ```
 */
export function useTimezone(): string {
  return useContext(TimezoneContext).timezone;
}
