'use client';

import {createContext, useCallback, useContext, useMemo, useState} from 'react';
import {DEFAULT_LOCALE, type LocaleOption} from './account-menu';

/**
 * The account menu's shell-level state.
 *
 * Two things in this menu cannot live inside the menu:
 *
 *   the help dialogs   they are opened BY a menu row and must outlive it. A
 *                      dialog mounted inside the popover would be torn down
 *                      the moment the row that opened it closed the popover,
 *                      and a `<dialog>` nested inside MobileNav's own dialog
 *                      cannot show at all.
 *   the mobile sheet   its trigger is the chip inside the nav drawer, and the
 *                      drawer has to close before the sheet opens. Same
 *                      nesting problem, same fix: mount both at the shell and
 *                      let the chip ask.
 *
 * The locale is here for a plainer reason — the popover and the sheet are two
 * renderings of one menu, and a check mark that disagreed between them would
 * be a bug you could only see by resizing the window.
 */

export type AccountDialogId = 'shortcuts' | 'about';

interface AccountMenuValue {
  isSheetOpen: boolean;
  openSheet: () => void;
  closeSheet: () => void;
  dialog: AccountDialogId | null;
  openDialog: (id: AccountDialogId) => void;
  closeDialog: () => void;
  /** Display-only until there is a locale provider. See account-menu.ts. */
  locale: LocaleOption['code'];
  setLocale: (code: LocaleOption['code']) => void;
}

const AccountMenuContext = createContext<AccountMenuValue | null>(null);

export function AccountMenuProvider({children}: {children: React.ReactNode}) {
  const [isSheetOpen, setSheetOpen] = useState(false);
  const [dialog, setDialog] = useState<AccountDialogId | null>(null);
  const [locale, setLocale] = useState<LocaleOption['code']>(DEFAULT_LOCALE);

  const openSheet = useCallback(() => setSheetOpen(true), []);
  const closeSheet = useCallback(() => setSheetOpen(false), []);
  const closeDialog = useCallback(() => setDialog(null), []);
  const openDialog = useCallback((id: AccountDialogId) => {
    // The menu that opened it is already closing; opening the dialog in the
    // same tick would otherwise race the sheet's own close transition and
    // leave two top-layer surfaces stacked for ~200ms.
    setSheetOpen(false);
    setDialog(id);
  }, []);

  const value = useMemo(
    () => ({
      isSheetOpen,
      openSheet,
      closeSheet,
      dialog,
      openDialog,
      closeDialog,
      locale,
      setLocale,
    }),
    [isSheetOpen, openSheet, closeSheet, dialog, openDialog, closeDialog, locale],
  );

  return <AccountMenuContext value={value}>{children}</AccountMenuContext>;
}

export function useAccountMenu(): AccountMenuValue {
  const ctx = useContext(AccountMenuContext);
  if (!ctx) {
    throw new Error('useAccountMenu must be used inside <AccountMenuProvider>');
  }
  return ctx;
}
