
// socketio client
import React, { useEffect, useState } from 'react';
import deepmerge from 'deepmerge';
import { Theme as ThemeEmitter, ThemeMain } from '@moonup/node';
import { createTheme, ThemeProvider } from '@mui/material';

// theme emitter
import useAuth from '../hooks/useAuth';
import useSocket from '../hooks/useSocket';
import ThemeContext from '../contexts/Theme';

// socket context
const MoonThemeProvider = (props = {}) => {
  // updated
  const [theme, setTheme] = useState(null);
  const [updated, setUpdated] = useState(new Date());

  // socket/auth
  const auth = useAuth();
  const socket = useSocket();

  // create emitter
  const [emitter] = useState(() => {
    // return emitter
    return (typeof window !== 'undefined' ? window.themeEmitter : null) || new ThemeEmitter({
      auth,
      socket,
    });
  });

  // use effect
  useEffect(() => {
    // real theme
    const realTheme = deepmerge((ThemeMain || {}), (emitter.state?.theme?.theme || {}));

    // remove broken
    Object.keys(realTheme.palette || {}).forEach((key) => {
      // check value
      if (!Object.keys(realTheme.palette[key]).length) delete realTheme.palette[key];
    });

    // check theme
    setTheme(createTheme(realTheme));
  }, [JSON.stringify(emitter.state?.theme?.theme)]);

  // use effect
  useEffect(() => {
    // check emitter
    if (!emitter) return;
    
    // on updated
    const onUpdated = () => setUpdated(new Date());

    // add listener
    emitter.on('theme', onUpdated);
    emitter.on('loading', onUpdated);
    emitter.on('updated', onUpdated);

    // return done
    return () => {
      // remove listener
      emitter.removeListener('theme', onUpdated);
      emitter.removeListener('loading', onUpdated);
      emitter.removeListener('updated', onUpdated);
    };
  }, [emitter]);

  // use effect
  useEffect(() => {
    // do props
    emitter.props({
      auth,
      socket,
    });
  }, [auth?.account]);

  // main theme
  const actualTheme = theme || createTheme(ThemeMain);

  // state
  const emitterState = emitter?.state;
  
  // moon theme
  if (typeof window !== 'undefined') window.MoonTheme  = actualTheme;
  if (typeof window !== 'undefined') window.MoonThemes = emitterState;

  // return jsx
  return (
    <ThemeProvider theme={ actualTheme }>
      <ThemeContext.Provider value={ emitterState }>
        { props.children }
      </ThemeContext.Provider>
    </ThemeProvider>
  );
};

// export default
export default MoonThemeProvider;