'use client';

import {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';

import type { AppLocale } from '@/config/i18n';

/**
 * Per-locale link override for the language switcher.
 *
 * Most routes are addressed by a locale-stable identifier, so the switcher can
 * reuse the current params and just swap the locale. Routes keyed by a
 * locale-specific slug (e.g. /program/[slug]) can't: the current slug is bound
 * to the current language. Such a page registers the target href for each
 * locale here, and the switcher navigates to the right one instead of reusing
 * the stale slug.
 */
export interface LocaleSwitchHref {
  pathname: string;
  params?: Record<string, string | number>;
}

export type LocaleSwitchOverrides = Partial<Record<AppLocale, LocaleSwitchHref>>;

interface LocaleSwitchContextValue {
  overrides: LocaleSwitchOverrides | null;
  setOverrides: (overrides: LocaleSwitchOverrides | null) => void;
}

const LocaleSwitchContext = createContext<LocaleSwitchContextValue | null>(null);

export function LocaleSwitchProvider({ children }: { children: ReactNode }) {
  const [overrides, setOverrides] = useState<LocaleSwitchOverrides | null>(null);
  const value = useMemo(() => ({ overrides, setOverrides }), [overrides]);

  return <LocaleSwitchContext.Provider value={value}>{children}</LocaleSwitchContext.Provider>;
}

export function useLocaleSwitchOverrides(): LocaleSwitchOverrides | null {
  return useContext(LocaleSwitchContext)?.overrides ?? null;
}

/**
 * Registers per-locale hrefs for the language switcher while mounted, and
 * clears them on unmount. Render it on pages with locale-bound slugs.
 */
export function LocaleSwitchOverride({ hrefs }: { hrefs: LocaleSwitchOverrides }) {
  const setOverrides = useContext(LocaleSwitchContext)?.setOverrides;
  const serialized = JSON.stringify(hrefs);

  useEffect(() => {
    if (!setOverrides) return;
    setOverrides(hrefs);
    return () => setOverrides(null);
    // hrefs is captured via its serialized form to keep the dependency stable.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [serialized, setOverrides]);

  return null;
}
