import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import {enquireScreen} from 'enquire-js';
import themeSwitcher from 'theme-switcher';
import {addLocaleData, IntlProvider} from 'react-intl';
import {presetPalettes, presetDarkPalettes} from '@ant-design/colors';
import {setTwoToneColor} from '@ant-design/icons';
import 'moment/locale/zh-cn';
import {ConfigProvider, Empty} from 'antd';
import zhCN from 'antd/lib/locale-provider/zh_CN';
import Header from './Header';
import SiteContext from './SiteContext';
import enLocale from '../../en-US';
import cnLocale from '../../zh-CN';
import * as utils from '../utils';

if (typeof window !== 'undefined' && navigator.serviceWorker) {
  navigator.serviceWorker.getRegistrations().then((registrations) => {
    registrations.forEach(registration => registration.unregister());
  });
}

if (typeof window !== 'undefined') {
  /* eslint-disable global-require */
  require('../../static/style');

  // Expose to iframe
  window.react = React;
  window['react-dom'] = ReactDOM;
  window.antd = require('antd');
  window['@enos/dpl'] = require('@enos/dpl');
  window['@ant-design/icons'] = require('@ant-design/icons');
  /* eslint-enable global-require */
}

let isMobile = false;
enquireScreen((b) => {
  isMobile = b;
});

// for dark.css timestamp to remove cache
const timestamp = new Date().getTime();
const themeMap = {
  dark: `/dark.css?${timestamp}`,
  green: `/green.css?${timestamp}`,
  compact: `/compact.css?${timestamp}`
};
const themeConfig = {
  themeMap
};
const {switcher} = themeSwitcher(themeConfig);

export default class Layout extends React.Component {
  static childContextTypes = {
    isMobile: PropTypes.bool,
    theme: PropTypes.string,
    setTheme: PropTypes.func,
    setIframeTheme: PropTypes.func
  };

  constructor(props) {
    super(props);
    const {pathname} = props.location;
    const appLocale = utils.isZhCN(pathname) ? cnLocale : enLocale;
    addLocaleData(appLocale.data);

    this.state = {
      appLocale,
      isMobile,
      setTheme: this.setTheme,
      setIframeTheme: this.setIframeTheme
    };
  }

  getChildContext() {
    const {isMobile: mobile, theme, setTheme, setIframeTheme} = this.state;
    return {isMobile: mobile, theme, setTheme, setIframeTheme};
  }

  componentDidMount() {
    const {location, router} = this.props;
    router.listen(() => {
      // const {theme} = this.props.location.query;
      //
      // // const componentPage = /^\/?components/.test(pathname);
      // const componentPage = true;
      //
      // // only component page can use `dark` theme
      // if (!componentPage) {
      //   this.setTheme('default', false);
      // } else if (theme) {
      //   this.setTheme(theme, false);
      // }
    });

    if (location.query.theme) {
      this.setTheme(location.query.theme, false);
    } else {
      this.setTheme('default', false);
    }

    const nprogressHiddenStyle = document.getElementById('nprogress-style');
    if (nprogressHiddenStyle) {
      this.timer = setTimeout(() => {
        nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
      }, 0);
    }

    enquireScreen((b) => {
      this.setState({
        isMobile: !!b
      });
    });
  }

  componentWillUnmount() {
    clearTimeout(this.timer);
  }

  setTheme = (theme, persist = true) => {
    if (typeof window === 'undefined') {
      return;
    }

    switcher({
      theme,
      useStorage: persist
    });

    Empty.useImg();

    const iframeNodes = document.querySelectorAll('.iframe-demo');
    // loop element node
    [].forEach.call(iframeNodes, (iframeNode) => {
      this.setIframeTheme(iframeNode, theme);
    });

    this.setState({
      theme
    });
    const iconTwoToneThemeMap = {
      dark: [presetDarkPalettes.blue.primary, '#111d2c'],
      default: presetPalettes.blue.primary
    };
    setTwoToneColor(iconTwoToneThemeMap[theme] || iconTwoToneThemeMap.default);
  };

  setIframeTheme = (iframeNode, theme) => {
    iframeNode.contentWindow.postMessage(
      JSON.stringify({
        action: 'change.theme',
        data: {
          themeConfig,
          theme
        }
      })
    );
  };

  render() {
    const {children, ...restProps} = this.props;
    const {appLocale, theme, setTheme, setIframeTheme} = this.state;

    return (
      <SiteContext.Provider value={{isMobile, theme, setTheme, setIframeTheme}}>
        <IntlProvider locale={appLocale.locale} messages={appLocale.messages}>
          <ConfigProvider locale={appLocale.locale === 'zh-CN' ? zhCN : null}>
            <div className='page-wrapper'>
              <Header {...restProps} theme={theme} />
              {children}
            </div>
          </ConfigProvider>
        </IntlProvider>
      </SiteContext.Provider>
    );
  }
}
