import React, { Component } from 'react';
// import cls from 'classnames';
import PropTypes from 'prop-types';
// import hoistNonReactStatics from 'hoist-non-react-statics';
import { CommonThemeProps } from '../types';
import { ConfigProvider as NextConfigProvider } from '@alifd/next';
import { ConfigProviderProps as NextConfigProviderProps } from '@alifd/next/types/config-provider';


interface ConfigProviderProps extends NextConfigProviderProps, CommonThemeProps {
}

type ConfigProviderType = React.Component<ConfigProviderProps>;

// @ts-ignore
const originalContextTypes = NextConfigProvider.contextTypes;
// @ts-ignore
NextConfigProvider.contextTypes = Object.assign({}, originalContextTypes, { theme: PropTypes.string });
// @ts-ignore
const originalChildContextTypes = NextConfigProvider.childContextTypes;
// @ts-ignore
NextConfigProvider.childContextTypes = Object.assign({}, originalChildContextTypes, { theme: PropTypes.string });
// @ts-ignore
const originalGetChildContext = NextConfigProvider.prototype.getChildContext;
// @ts-ignore
NextConfigProvider.prototype.getChildContext = function() {
  const { theme } = this.props;
  const originProps = originalGetChildContext.call(this);
  return Object.assign({ theme }, originProps);
};

// function typeOf(obj) {
//   return Object.prototype.toString.call(obj).replace(/\[object\s|]/g, '');
// }

// function isClassComponent(component) {
//   return (
//     typeOf(component) === 'Function' && component.prototype && component.prototype.isReactComponent !== undefined
//   );
// }

// const originalConfig = NextConfigProvider.config;
// NextConfigProvider.config = (Component, options) => {

//   const ConfigedComponent = originalConfig(Component, options);

//   class WrapperComponent extends Component {
//     static contextTypes = {
//       theme: PropTypes.string,
//     };

//     _getInstance = ref => {
//       this._instance = ref;
//       if (options) {
//         if (this._instance && options.exportNames) {
//           options.exportNames.forEach(name => {
//             const field = this._instance[name];
//             if (typeof field === 'function') {
//               this[name] = field.bind(this._instance);
//             } else {
//               this[name] = field;
//             }
//           });
//         }
//       }
//     };

//     render() {
//       const { theme: propTheme } = this.props;


//       const { theme: contextTheme } = this.context;


//       const theme = propTheme ? propTheme : (contextTheme ? contextTheme : 'white');

//       // console.log(theme);

//       // console.log(this);

//       return (
//         <ConfigedComponent
//           {...this.props}
//           {...this.context}
//           theme = {theme}
//           ref={isClassComponent(ConfigedComponent) ? this._getInstance : null}
//         />
//       );
//     }
//   }

//   return WrapperComponent;
// };

const originalConfig = NextConfigProvider.config;
// @ts-ignore
NextConfigProvider.configFC = (OriginComponent, options) => {

  const ConfigedComponent = originalConfig(OriginComponent, options);

  return class extends Component {
    static contextTypes = {
      theme: PropTypes.string,
    };

    render() {
      const { theme: contextTheme } = this.context;
      const theme = contextTheme ? contextTheme : 'white';

      return (
        <ConfigedComponent
          {...this.props}
          {...this.context}
          theme={theme}
        />
      );
    }
  };
};

interface IConfigProvider {
  new(): ConfigProviderType;
  config<T = any>(Component: T, options?: any): T;
  configFC<T = any>(Component: T, options?: any): T;
  getContextProps(props: {}, displayName: string): any;
  initLocales(locales: any): any;
  setLanguage(language: string): any;
  setLocale(locale: any): any;
  setDirection(dir: string): any;
  getLocale(): any;
  getLanguage(): string;
  getDirection(): string;
  clearCache(): any;
}
// @ts-ignore
const ConfigProvider: IConfigProvider = NextConfigProvider;

export default ConfigProvider;

