import React, { ReactNode, useContext } from 'react';
import { Global } from '@emotion/react';
import type { ThemeOptions } from '@mui/material/styles';
// material
import { createTheme, ThemeProvider } from '@mui/material/styles';

import { APPEARANCE_MODE_DARK, APPEARANCE_MODE_LIGHT, SPACING } from './constants';
import breakpoints from './constants/breakpoints';
import { COMMON } from './constants/palette';
import shadows from './constants/shadows';
import shape from './constants/shape';
import typography from './constants/typography';
import zIndex from './constants/zIndex';
import darkTheme from '@/mui/constants/palette/dark';
import lightTheme from '@/mui/constants/palette/light';

import { getCssVarsFromTheme } from './helpers';

import { SettingsContext } from '@/modules/@common/app/SettingsProvider';
import components from './components/MuiOverrides';

const paletteCollection = {
  [APPEARANCE_MODE_LIGHT]: lightTheme,
  [APPEARANCE_MODE_DARK]: darkTheme,
};

export type ThemeModeType = typeof APPEARANCE_MODE_LIGHT | typeof APPEARANCE_MODE_DARK;

type ThemeConfigProps = {
  className?: string;
  children: ReactNode;
  appearance?: typeof APPEARANCE_MODE_DARK | typeof APPEARANCE_MODE_LIGHT;
  global?: boolean;
};

function ThemeConfig({ className, children, appearance, global = false }: ThemeConfigProps) {
  const { themeMode } = useContext(SettingsContext);

  const palette$ =
    paletteCollection[appearance ?? (themeMode as ThemeModeType)] ?? paletteCollection[APPEARANCE_MODE_LIGHT];

  const options: ThemeOptions = {
    palette: {
      ...palette$,
      common: COMMON,
      neutral: {
        dark: palette$.shades[900],
        main: palette$.shades[900],
        light: palette$.shades[700],
        contrastText: palette$.shades[900],
      },
      grey: { ...palette$.shades },
    },
    spacing: SPACING,
    shape,
    typography,
    breakpoints,
    shadows,
    zIndex,
  };

  const defaultTheme = createTheme({ ...options });

  const theme = createTheme({
    ...options,
    components: components(defaultTheme),
  });

  const cssVars = getCssVarsFromTheme(defaultTheme);

  return (
    <ThemeProvider theme={theme}>
      {global ? (
        <>
          <Global styles={{ ':root': cssVars }} />
          {children}
        </>
      ) : (
        <div style={cssVars} className={className}>
          {children}
        </div>
      )}
    </ThemeProvider>
  );
}

export default ThemeConfig;
