import '!file-loader?name=[name].[ext]!./images/favicon.ico';
import './global.less';
import '@babel/polyfill';
import 'animate.css/animate.css';
import 'antd/dist/antd.less';
import 'file-loader?name=.htaccess!./.htaccess'; // eslint-disable-line import/extensions
import 'kit_utils/lib/format';
import 'sanitize.css/sanitize.css';
import React from 'react';
import ReactDOM from 'react-dom';
import { ErrorBoundary } from '@ant-design/pro-utils';
import { ConnectedRouter } from 'connected-react-router/immutable';
import Immutable from 'immutable';
import { params, Storeage } from 'kit_utils';
import { Provider } from 'react-redux';
import { message, Button, ConfigProvider, notification } from 'antd';
import defaultSettings from '../config/defaultSetting';
import Container from './components/Container';
import configureStore from './configureStore';
import App from './containers/App';
import { actionCreators } from './containers/App/store';
import { initMicroApps } from './micro';
import history from './utils/history';
import { isString } from './utils/utils';
import services from './api/service/base';
const isHttps = document.location.protocol === 'https:';
const { pwa } = defaultSettings;
// eslint-disable-next-line no-restricted-globals
const namespace = `__PANDA_STORE__${location.hostname}`;
window.createStoreage = new Storeage(namespace);
// eslint-disable-next-line no-underscore-dangle
const initialState = Immutable.Map();
const store = configureStore(initialState, history);
const MOUNT_NODE = document.getElementById('app');
const render = () => {
  // eslint-disable-next-line react-hooks/rules-of-hooks

  ReactDOM.render(
    <Provider store={store}>
      <ConnectedRouter history={history}>
        <ConfigProvider>
          <ErrorBoundary>
            <Container>
              <App />
            </Container>
          </ErrorBoundary>
        </ConfigProvider>
      </ConnectedRouter>
    </Provider>,
    MOUNT_NODE,
  );
};

const loader = (appContent, loading) => render({ appContent, loading });

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

const initGlobalConfig = () => {
  // eslint-disable-next-line no-undef
  const config = createStoreage.get('globalConfig') || {};
  if (config.title == null) {
    // eslint-disable-next-line no-undef
    createStoreage.remove(namespace);
  }
  if (!params.getParams('client') && 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 (config.title !== null && Object.keys(config).length > 0) {
    store.dispatch(actionCreators.getConfig(config));
    render({ appContent: '', loading: true });
  } else {
    services
      .queryConfig({ client: params.getParams('client') || 'city' })
      .then(res => {
        if (res) {
          const data = res;
          store.dispatch(actionCreators.getConfig(Object.assign({}, data)));
          // eslint-disable-next-line no-shadow
          try {
            services
              .getWateWayConfig()
              // eslint-disable-next-line no-shadow
              .then(res => {
                const hasGateWay =
                  res && res.data && isString(res.data)
                    ? JSON.parse(res.data)
                    : res.data;
                // eslint-disable-next-line no-debugger
                if (res.code === 0) {
                  store.dispatch(
                    actionCreators.getConfig(
                      Object.assign({}, data, {
                        hasGateWay,
                        apiGatewayDomain: `${
                          window.location.origin
                        }/Publish/GateWay`,
                      }),
                    ),
                  );
                }
              })
              .catch(error => {
                store.dispatch(actionCreators.getConfigError(error));
                store.dispatch(
                  actionCreators.getConfig(Object.assign({}, data)),
                );
              });
          } catch (e) {
            console.log(e);
            // eslint-disable-next-line no-empty
          } finally {
          }
        }
      })
      // eslint-disable-next-line no-shadow
      .then(res => {
        render({ appContent: '', loading: true });
      })
      .catch(error => {
        store.dispatch(actionCreators.getConfigError(error));
      });
  }

  if (config.token) {
    initMicroApps(loader);
  }
};

window.share &&
  window.share.event &&
  window.share.event.on('triggerMicro', () => {
    initMicroApps(loader);
  });
initGlobalConfig();
initLocale();

if (pwa) {
  window.addEventListener('sw.offline', () => {
    message.warning('当前处于离线状态');
  });

  window.addEventListener('sw.updated', event => {
    const e = event;
    const reloadSW = async () => {
      const worker = e.detail && e.detail.waiting;
      if (!worker) {
        return true;
      }
      await new Promise((resolve, reject) => {
        const channel = new MessageChannel();
        channel.port1.onmessage = msgEvent => {
          if (msgEvent.data.error) {
            reject(msgEvent.data.error);
          } else {
            resolve(msgEvent.data);
          }
        };
        worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
      });
      window.location.reload(true);
      return true;
    };
    const key = `open${Date.now()}`;
    const btn = (
      <Button
        type="primary"
        onClick={() => {
          notification.close(key);
          reloadSW();
        }}
      >
        刷新
      </Button>
    );
    notification.open({
      message: '有新内容',
      description: '请点击“刷新”按钮或者手动刷新页面',
      btn,
      key,
      onClose: async () => null,
    });
  });
} else if ('serviceWorker' in navigator && isHttps) {
  const { serviceWorker } = navigator;
  if (serviceWorker.getRegistrations) {
    serviceWorker.getRegistrations().then(sws => {
      sws.forEach(sw => {
        sw.unregister();
      });
    });
  }
  serviceWorker.getRegistration().then(sw => {
    if (sw) sw.unregister();
  });

  if (window.caches && window.caches.keys) {
    caches.keys().then(keys => {
      keys.forEach(key => {
        caches.delete(key);
      });
    });
  }
}
