import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';

import {
  ConfigProvider,
  message,
  Modal,
  notification,
} from 'antd';
import { ConnectedRouter } from 'connected-react-router/immutable';
import Cookies from 'js-cookie';
import canUseDom from 'rc-util/lib/Dom/canUseDom';
import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
import { Provider } from 'react-redux';

import { LocaleContainer } from '@wisdom-utils/components';
import { history } from '@wisdom-utils/runtime';
import {
  params,
  Storeage,
} from '@wisdom-utils/utils/lib/helpers';

import { appService } from './api';
import Container from './components/Container';
import App from './containers/App';
import { actionCreators } from './containers/App/store';
import {
  defaultApp,
  initMicroApps,
} from './micro';
import Login from './pages/user/login/login';
import store from './stores';
import { getToken } from './utils/utils';

const { getThemeVariables } = require('antd/dist/theme');
const defaultSetting = require('../config/defaultSetting');
const MOUNT_NODE = document.getElementById('root');
const customPrefixCls = 'panda-console-base';
const namespace = `__PANDA_STORE__${location.hostname}`;
window.createStoreage = new Storeage(namespace);


const dynamicStyleMark = `-panda-${Date.now()}-${Math.random()}`;
function getStyle(prefixCls, theme) {
  const variables = {};

  Object.keys(theme).forEach(item => {
    variables[item] = theme[item]
  })
  const cssList = Object.keys(variables).map(
    key => `--${prefixCls}-${key}: ${variables[key]};`,
  );

  return `
  :root {
    ${cssList.join('\n')}
  }
  `.trim();


}

const registerTheme = function(prefixCls, theme) {
  const style = getStyle(prefixCls, theme);
  if(canUseDom()) {
    updateCSS(style, `${dynamicStyleMark}-dynamic-theme`)
  }
}


export const AppInitState = () => {


  const getClient = () => {
    const value = params.getParams('client') || Cookies.get('client');
    const client = value && value !== 'undefined' ? value : 'city';
    return client;
  }

  const client = getClient();

  let config = window.globalConfig || {};
  createStoreage.remove(`__PANDA_STORE__${location.hostname}`);

  window.globalConfig = {};
  window.__INITIAL_STATE__ = {};

  if (!getToken() || config.token == null) {
    // eslint-disable-next-line no-undef
    createStoreage.remove(namespace);
    config = {};
  }
  if (!params.getParams('client', window.location.search) && config) {
    // eslint-disable-next-line no-undef
    createStoreage.remove(namespace);
  }

  // eslint-disable-next-line no-undef
  if (!createStoreage.get('globalConfig')) {
    window.createStoreage = new Storeage(namespace);
  }

  if (!getToken()) {
    localStorage.removeItem('loginSite');
  }

  const initGeteWay = () => {
    appService.getWateWayConfig({ignoreSite: true}).then(res => {
      const hasGateWay = !res || !res.data ? false : _.isString(res.data) ? JSON.parse(res.data) : typeof res.data === 'boolean' ? res.data : false;
      return {
        hasGateWay,
        apiGatewayDomain: `${window.location.origin}${hasGateWay ? '/PandaCore/GateWay' : ''}`,
      };
    }).then(gateWayConfig => {
      initGlobalConfig(gateWayConfig);
    }).catch(err => {
      initGlobalConfig();
    });
  }


  const initGlobalConfig = (gateWayConfig = {}) => {
    appService.queryConfig({
      client: client || 'city',
      ignoreSite: true,
    }).then(res => {
      if (res) {
        const { data } = res;
        if (!data.client) {
          data.client = client;
        }
        store.dispatch(actionCreators.getConfig(Object.assign({},data,{
          token: '',
          access_token: '',
          userInfo: null,
        },gateWayConfig)));
        const products = (data.products || []).map(item => {
          if (item.PackageName === 'civweb4') {
            return 'web4_console'
          }
          return `${item.PackageName}-main`;
        });

        if(products && products.length > 0) {
          Object.keys(products).forEach(item => {
            window[products[item]] && window[products[item]] && window[products[item]].unmount && window[products[item]].unmount({ store: store });
          });
          initMicroApps();
        }
        // eslint-disable-next-line no-new
        if (getToken()) {
          // eslint-disable-next-line no-new
          const action = new Login({
              global: Object.assign({}, data,
                {
                  token: getToken(),
                },
                gateWayConfig,
              ),
              // eslint-disable-next-line no-shadow
              updateConfig: data => store.dispatch(actionCreators.getConfig(data)),
              isInit: false,
              logout: () => store.dispatch(actionCreators.logout()),
            },
            () => {
              (async () => {
                (await (getToken() &&
                  window.globalConfig &&
                  window.globalConfig.token)) &&
                  initMicroApps(loader, store);
              })();
            },
            true,
          );
          action.events.on('loginSuccess', event =>{
            window.history.pushState('', '', `/?client=${client}`);
            defaultApp();
          })
        }
        return window.globalConfig.variableTheme
      }
    })
    .then(themeConfig => {
      ConfigProvider.config({
        prefixCls: customPrefixCls,
        theme: {
          primaryColor: themeConfig.primaryColor
        }
      });

      registerTheme(customPrefixCls, {
        'header-bg-color': themeConfig.headerPrimaryColor,
        // 'linear-gradient(0deg, #0066d6, #39a9ff 100%)'
      });
    })
    .catch(error => {
      store.dispatch(actionCreators.getConfigError(error));
    });
  }


  const initLocale = () => {
    localStorage.setItem('umi_locale', 'zh-CN');
  };

  // 语音播报全局拦截
  const initMessageVoice = () => {
    const rawSpeak = window.speechSynthesis.speak;
    window.speechSynthesis.speak = function(...args) {
      if (
        window.globalConfig &&
        // eslint-disable-next-line no-prototype-builtins
        window.globalConfig.hasOwnProperty('messageVoice') &&
        window.globalConfig.messageVoice === false
      )
        return;
      rawSpeak.apply(window.speechSynthesis, args);
    };
  };

  // 添加主题变更事件监听
  const initAppTheme = () => {
    const hasThemeChanged = (preTheme, theme) => {
      if (!preTheme && !theme) return false
      if (
        preTheme && theme &&
       (!theme.primaryColor || theme.primaryColor === preTheme.primaryColor) &&
       (!theme.navTheme || theme.navTheme === preTheme.navTheme) &&
       (!theme.headerPrimaryColor || theme.headerPrimaryColor === preTheme.headerPrimaryColor)
      ) return false
      return true
    }
    store.subscribe((function() {
      let preVariableTheme = store.getState().toJS().global?.globalConfig?.variableTheme;
      return function() {
        // if (!preVariableTheme)
        const variableTheme = store.getState().toJS().global?.globalConfig?.variableTheme;
        if(!hasThemeChanged(preVariableTheme, variableTheme)) return false
        const {
          primaryColor: prePrimaryColor,
          navTheme: preNavTheme,
          headerPrimaryColor: preHeaderPrimaryColor,
        } = (preVariableTheme || {});
        const { primaryColor, headerPrimaryColor } = variableTheme;
        if (primaryColor && primaryColor !== prePrimaryColor) {
          ConfigProvider.config({
            prefixCls: customPrefixCls,
            theme: {
              primaryColor,
            }
          });
        }
        if (headerPrimaryColor && headerPrimaryColor !== preHeaderPrimaryColor) {
          registerTheme(customPrefixCls, {
            'header-bg-color': headerPrimaryColor,
          });
        }
      }
    })())
  };

  initLocale();
  initMessageVoice();
  initGeteWay();
  initAppTheme();
}

const RootContainer = (props) => {
  const { loading } = props;

  useEffect(() => {
    AppInitState();
  }, []);

  const finalConfig = {
    ...{
      prefixCls: customPrefixCls,
      theme: {
        'root-entry-name': 'default',
        ...getThemeVariables({}),
        primaryColor: defaultSetting.primaryColor,
      },
    },
  };

  if (finalConfig.prefixCls) {
    Modal.config({
      rootPrefixCls: customPrefixCls,
    });
    message.config({
      rootPrefixCls: `${finalConfig.prefixCls}-message`,
    });
    notification.config({
      rootPrefixCls: `${finalConfig.prefixCls}-notification`,
    });
  }

  return React.createElement(Provider, {
    store: store,
  }, React.createElement(ConnectedRouter, {
    history: history,
  }, React.createElement(LocaleContainer, {
    prefixCls: customPrefixCls,
  }, React.createElement(ConfigProvider, {
    prefixCls: customPrefixCls,
  }, React.createElement(Container, null, React.createElement(App , {
    loading,
  }))))));
};


export const render = ({ loading }) => {

  // eslint-disable-next-line react-hooks/rules-of-hooks
  ReactDOM.render(<RootContainer loading={loading}  />, MOUNT_NODE);
};

// updateTheme('#ff9600');
const loader = (loading) => render({ loading });

export default loader;