import { createElement } from 'react';
import PropTypes from 'prop-types';
import { Select, Balloon, NumberPicker, Input } from '@alifd/next';
import { ColorItem } from '../Color';

function createDataSource(options) {
  return options.map(
    ({ desc, description, name, value, type, computedVal }) => {
      return {
        value: `var(${name})`,
        label: `${desc || description}`,
        computedVal: computedVal || value,
        type,
      };
    }
  );
}

// 渲染下拉选择器
function renderSelect(props) {
  const { data, theme, onChange } = props;

  const itemRender = params => {
    const { label, computedVal, type } = params;

    const useDefault = label && label.match(/^calc/);

    return type === 'color' ? (
      <ColorItem color={computedVal} label={label} />
    ) : (
      useDefault? 'default': label
    );
  };

  const options = theme.filter(({ group }) => group && group === data.enum);
  const dataSource = createDataSource(options);

  return (
    <Select
      className='editor-input'
      id={data.name}
      itemRender={itemRender}
      valueRender={itemRender}
      onChange={v => onChange(data.name, `${v}`, data.value)}
      defaultValue={data.value}
      dataSource={dataSource}
    />
  );
}

// 渲染数字选择器
function renderNumber(props) {
  const { data } = props;

  let val = data.value;
  if (typeof val === 'string') {
    val = parseFloat(val);
  }

  function handleChange(v) {
    if (data.unit) {
      v = v + data.unit;
    }
    props.onChange(data.name, v, val);
  }

  return (
    <div>
      <NumberPicker
        defaultValue={val}
        step={data.step || 1}
        onChange={handleChange}
        innerAfter={data.unit || ''}
      />
    </div>
  );
}

// 渲染 string 类型输入
function renderString(props) {
  const { data } = props;

  function handleChange(v) {
    props.onChange(data.name, v, data.value);
  }
  return (
    <Input
      className='editor-input'
      defaultValue={data.value}
      onChange={handleChange}
    />
  );
}

function renderItem(props) {
  const { type } = props.data;

  switch (type) {
    case 'enum':
      return renderSelect(props);

    case 'number':
      return renderNumber(props);

    case 'string':
    default:
      return renderString(props);
  }
}

export default function EditorItem(props) {
  const { data } = props;
  const { name, desc, description, semantic } = data;

  const labelEl = <label>{semantic || desc || description}</label>;

  return (
    <div key={name} className='editor-item'>
      <Balloon
        closable={false}
        trigger={labelEl}
        triggerType='hover'
        align='lb'
      >
        {desc || description || semantic}
      </Balloon>
      {renderItem(props)}
    </div>
  );
}

EditorItem.propTypes = {
  data: PropTypes.object,
  theme: PropTypes.arrayOf(PropTypes.object),
  onChange: PropTypes.func, // @return (name, newvalue, oldvalue)
};
