import type { ResolvedTheme } from "./theme.ts";

export type ThemeTransitionContext = {
  element?: HTMLElement | null;
  pointerClientX?: number;
  pointerClientY?: number;
};

export type ThemeTransitionOptions = {
  nextTheme: ResolvedTheme;
  applyTheme: () => void;
  // Retained so callers from stacked slices can keep passing pointer metadata
  // while theme switching remains an immediate, non-animated update here.
  context?: ThemeTransitionContext;
  currentTheme?: ResolvedTheme | null;
};

const cleanupThemeTransition = (root: HTMLElement) => {
  root.classList.remove("theme-transition");
  root.style.removeProperty("--theme-switch-x");
  root.style.removeProperty("--theme-switch-y");
};

export const startThemeTransition = ({
  nextTheme,
  applyTheme,
  currentTheme,
}: ThemeTransitionOptions) => {
  if (currentTheme === nextTheme) {
    // Even when the resolved palette is unchanged (e.g. system->dark on a dark OS),
    // we still need to persist the user's explicit selection immediately.
    applyTheme();
    return;
  }

  const documentReference = globalThis.document ?? null;
  if (!documentReference) {
    applyTheme();
    return;
  }

  const root = documentReference.documentElement;
  // Theme updates should be visible immediately on click with no transition lag.
  applyTheme();
  cleanupThemeTransition(root);
};
