import React, { createElement, forwardRef, useEffect, useState } from 'react';
import { Form, Tooltip } from 'antd';
import isArray from 'lodash/isArray';
import isNumber from 'lodash/isNumber';
import isString from 'lodash/isString';
import isObject from 'lodash/isObject';
import isBoolean from 'lodash/isBoolean';
import isEmpty from 'lodash/isEmpty';
import isEqual from 'lodash/isEqual';
import get from 'lodash/get';
import keys from 'lodash/keys';
import { FormComponentProps } from 'antd/lib/form';
import { PROPS_TYPES, PropsConfigType } from '@brickd/react';
import EnumComponent from './EnumComponent';
import styles from '../index.less';
import { TYPES_TO_COMPONENT } from '../index';

const FormItem = Form.Item;

interface SwitchMultiTypesPropsType extends FormComponentProps {
  types: PROPS_TYPES[];
  field: string;
  childPropsConfig?: PropsConfigType | PropsConfigType[];
  extraObj?: any;
  itemOption?: any;
  formItemProps?: any;
  tip?: string;
  label?: string;
  componentProps: any;
}

function SwitchMultiTypes(props: SwitchMultiTypesPropsType, ref: any) {
  const {
    types,
    form: { getFieldValue, setFieldsValue, getFieldDecorator },
    field,
    childPropsConfig,
    extraObj = {},
    itemOption = {},
    formItemProps = {},
    tip,
    label,
    componentProps,
  } = props;
  const [type, setType] = useState(types[0]);
  const value = getFieldValue(field);
  useEffect(() => {
    let type = null;
    if (isArray(value)) {
      const firstValue = value[0];
      if (isNumber(firstValue)) {
        type = PROPS_TYPES.numberArray;
      } else if (isString(firstValue)) {
        type = PROPS_TYPES.stringArray;
      } else if (isObject(firstValue)) {
        type = PROPS_TYPES.objectArray;
      }
    } else if (isObject(value)) {
      if (
        isEmpty(childPropsConfig) ||
        !isEqual(keys(value), keys(childPropsConfig))
      ) {
        type = PROPS_TYPES.json;
      } else {
        type = PROPS_TYPES.object;
      }
    } else if (isNumber(value)) {
      type = PROPS_TYPES.number;
    } else if (isString(value)) {
      type = PROPS_TYPES.string;
    } else if (isBoolean(value)) {
      type = PROPS_TYPES.boolean;
    }
    type && setType(type);
  }, []);

  useEffect(() => {
    setFieldsValue({ [field]: value });
  }, [type]);

  if (type === PROPS_TYPES.boolean) {
    extraObj.valuePropName = 'checked';
  }
  return (
    <FormItem
      style={{ marginLeft: 10, marginRight: 10, marginBottom: 5 }}
      {...formItemProps}
      label={
        <div className={styles['multi-type']}>
          <Tooltip title={`${field}:${tip || label}`}>{label}</Tooltip>
          <EnumComponent
            value={type}
            enumData={types}
            allowClear={false}
            style={{ width: 90, marginLeft: 10 }}
            onChange={(newType) => setType(newType)}
          />
        </div>
      }
    >
      {getFieldDecorator(field, { ...extraObj, ...itemOption })(
        createElement(get(TYPES_TO_COMPONENT, type), {
          ...componentProps,
          type,
          size: type === PROPS_TYPES.boolean ? 'default' : 'small',
        }),
      )}
    </FormItem>
  );
}

export default forwardRef(SwitchMultiTypes);