import * as React from "react";
import {
  ThemeProvider,
  createTheme,
  CssBaseline,
} from "@mui/material";

import { getDesignTokens } from "./themePrimitives";

import { inputsCustomizations } from "./customizations/inputs";
import { dataDisplayCustomizations } from "./customizations/dataDisplay";
import { feedbackCustomizations } from "./customizations/feedback";
import { navigationCustomizations } from "./customizations/navigation";
import { surfacesCustomizations } from "./customizations/surfaces";

export type ColorMode = "light" | "dark";

type ColorModeContextValue = {
  mode: ColorMode;
  setMode: (mode: ColorMode) => void;
  toggleColorMode: () => void;
};

export const ColorModeContext =
  React.createContext<ColorModeContextValue>({
    mode: "light",
    setMode: () => {},
    toggleColorMode: () => {},
  });

type AppThemeProps = {
  children: React.ReactNode;
  defaultMode?: ColorMode;
};

export default function AppTheme({
  children,
  defaultMode = "dark",
}: AppThemeProps) {
  const [mode, setMode] =
    React.useState<ColorMode>(defaultMode);

  const toggleColorMode = React.useCallback(() => {
    setMode((prev) =>
      prev === "light" ? "dark" : "light"
    );
  }, []);

  const contextValue = React.useMemo(
    () => ({
      mode,
      setMode,
      toggleColorMode,
    }),
    [mode, toggleColorMode]
  );

  const theme = React.useMemo(
    () =>
      createTheme({
        ...getDesignTokens(mode),

        components: {
          ...inputsCustomizations,
          ...dataDisplayCustomizations,
          ...feedbackCustomizations,
          ...navigationCustomizations,
          ...surfacesCustomizations,
        },
      }),
    [mode]
  );

  return (
    <ColorModeContext.Provider value={contextValue}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        {children}
      </ThemeProvider>
    </ColorModeContext.Provider>
  );
}
