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

import { getDesignTokens } from "./themePrimitives";
import { getSemanticColors } from "./themeConfig";

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 = "light",
}: 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 semantic = React.useMemo(
    () => getSemanticColors(mode),
    [mode]
  );

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

        components: {
          ...inputsCustomizations,
          ...dataDisplayCustomizations,
          ...feedbackCustomizations,
          ...navigationCustomizations,
          ...surfacesCustomizations,
        },
      });
      (base as any).applyStyles = (m: "light" | "dark", styles: any) =>
        base.palette.mode === m ? styles : {};
      return base;
    },
    [mode, semantic]
  );

  return (
    <ColorModeContext.Provider value={contextValue}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <Box
          sx={{
            "--bg-page": semantic.surface.page,
            "--bg-card": semantic.surface.card,
            "--bg-elevated": semantic.surface.elevated,
            "--border-default": semantic.border.default,
            "--border-subtle": semantic.border.subtle,
            "--text-primary": semantic.text.primary,
            "--text-secondary": semantic.text.secondary,
            "--text-muted": semantic.text.muted,
          }}
        >
          {children}
        </Box>
      </ThemeProvider>
    </ColorModeContext.Provider>
  );
}
