import {
  createContext,
  lazy,
  Suspense,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import { qk } from "../lib/queryKeys";
import { useQuery } from "@tanstack/react-query";
import { api } from "../lib/api";
import { shouldAutoOpenOnboarding } from "../lib/onboarding";

const OnboardingWizard = lazy(() => import("./OnboardingWizard"));

// Owns the onboarding wizard's open state (and the wizard render itself), lifted out of App so any
// module can trigger "connect YouTube" via a hook instead of an onOpenWizard prop threaded through
// the tree. Mirrors the other split-context providers; composed in main.tsx around <App/>.
//
// The wizard auto-opens on first login for accounts that still need to connect YouTube (derived from
// granted scopes + storage flags, so it's stable across the OAuth round-trip) and is reopenable from
// Settings / the notify "reconnect" action. It reads `me` as a passive qk.me() observer (App owns the
// fetching query), so it re-runs the auto-open check when the account resolves or its grants change.

interface WizardActions {
  openWizard: () => void;
  closeWizard: () => void;
}

// Only the actions are shared — the open flag stays local to the provider (it renders the wizard
// itself), so no consumer needs to subscribe to it.
const ActionsContext = createContext<WizardActions>({
  openWizard: () => {},
  closeWizard: () => {},
});

export function useWizard(): WizardActions {
  return useContext(ActionsContext);
}

export function WizardProvider({ children }: { children: ReactNode }) {
  const [open, setOpen] = useState(false);
  // Passive observer of the account App fetches (enabled:false → reads cache, re-renders on update).
  const { data: me } = useQuery({ queryKey: qk.me(), queryFn: api.me, enabled: false });

  const openWizard = useCallback(() => setOpen(true), []);
  const closeWizard = useCallback(() => setOpen(false), []);

  // First-login onboarding: prompt the user to connect YouTube (and resume the flow after each
  // consent redirect). Re-checked when the account or its grants change.
  useEffect(() => {
    if (me && shouldAutoOpenOnboarding(me)) setOpen(true);
  }, [me?.id, me?.can_read, me?.can_write]);

  const actions = useMemo<WizardActions>(
    () => ({ openWizard, closeWizard }),
    [openWizard, closeWizard],
  );

  return (
    <ActionsContext.Provider value={actions}>
      {children}
      {/* The wizard is a full-screen overlay; the demo account can't connect YouTube, so it never
          opens there. Lazy — its chunk loads only when first opened. */}
      <Suspense fallback={null}>
        {open && me && !me.is_demo && <OnboardingWizard me={me} onClose={closeWizard} />}
      </Suspense>
    </ActionsContext.Provider>
  );
}
