import { createElement, useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import ConfigEditor from '../ConfigEditor';
// import Device from '../Device';
import { $on, $off, $emit } from '../../common/event';

import './index.scss';

function prehandle(variables, theme, component) {
  let varList = [];
  let refVars = [];

  // 过滤掉 非当前组件主题变量&不可以配置变量
  const tempVars = theme.filter(
    item =>
      !item.unconfigurable &&
      variables.includes(item.name) &&
      (!component || item.component === component)
  );

  // 引用变量:
  // 如下变量 --button-padding 本身不可配置，需拆分成对 --button-padding-ver 和 --button-padding-hoz 的配置
  // --button-padding: var(--button-padding-ver) var(--button-padding-hoz)
  // ref: [--button-padding-ver, --button-padding-hoz]
  tempVars.forEach(item => {
    if (item.ref) {
      refVars = [].concat(refVars, item.ref); 
      // 复杂变量可以通过配置 configurable 强制可配
      if(item.configurable) {
        varList.push(item)
      }
    } else {
      varList.push(item);
    }
  });

  return [].concat(
    varList,
    theme.filter(
      ({ name, unconfigurable }) => !unconfigurable && refVars.includes(name)
    )
  );
}

export default function ConfigPage(props) {
  let wrapper = null;
  const [theme, setTheme] = useState(props.theme || []);
  const [variables, setVariables] = useState([]);

  function getView() {
    return (
      wrapper.querySelector('.shadow-node') &&
      wrapper
        .querySelector('.shadow-node')
        .shadowRoot.querySelector('.config-view')
    );
  }

  function handleChange(name, value) {
    const configView = getView();

    variables.find(item => item.name === name).value = value;
    const current = theme.find(item => item.name === name);
    current.value = value;

    setTheme([...theme]);
    setVariables([...variables]);

    $emit(configView, 'themechange', theme);
    props.onChange && props.onChange(name, value, current.component, theme);
  }

  !props.isPreview &&
    useEffect(() => {
      const callback = (__, variables) => {
        setVariables(prehandle(variables, theme, props.component));
      };

      $on(wrapper, 'config', callback);

      return () => {
        $off(wrapper, 'config', callback);
      };
    }, []);

  useEffect(() => {
    const configView = getView();
    configView && $emit(configView, 'themechange', [...theme]);
  });

  // function wrapDevice(el) {
  //   return props.isDevice === false ? (
  //     el
  //   ) : (
  //     <Device platform='Android'>{el}</Device>
  //   );
  // }

  return (
    <div
      // className={'config-page' + (props.isDevice ? ' config-view-mobile' : '')}
      className='config-page'
      style={props.style}
    >
      <div className='config-content'>
        <div id='config-view-wrapper' ref={el => (wrapper = el)}></div>
      </div>
      {!props.isPreview ? (
        <ConfigEditor
          onChange={handleChange}
          theme={theme}
          type={props.editorType}
          variables={variables}
        />
      ) : null}
    </div>
  );
}

ConfigPage.propTypes = {
  theme: PropTypes.arrayOf(PropTypes.object),
  onChange: PropTypes.func,
  component: PropTypes.string,
  editorType: PropTypes.oneOf(['shadow']),
  isPreview: PropTypes.bool,
  style: PropTypes.object,
};
