import React from 'react';
import './index.scss';
import { RelativeDateSelect } from '@/common/setter/default-value-setter/components/relative-date-select';
import { JsonEditor } from '@/common/setter/default-value-setter/components/json-editor';
import { handleI18nLabel } from '@/common/util/util';
import { allowSelectFirstComponentList } from '@/common/util/const';
import { DisplayPosition } from '@/type/display-position';

const {
  CnAsyncSelect,
  Button,
  CnInput,
  CnNumberPicker,
  CnTimePicker2,
  CnRangeTimePicker2,
  CnIcon,
  CnRangeDatePicker2,
  CnDatePickerPro,
} = window.CNUI || {};
const ParamSelectSetter =
  window.AliLowCodeEngine?.setters?.getSetter?.('ParamSelectSetter')
    ?.component || CnInput;

const typeList = [
  {
    label: '时间选择器',
    value: 'CnTimePicker2',
    component: CnTimePicker2,
    position: ['TimePicker'],
    props: {},
  },
  {
    label: '时间区间选择器',
    value: 'CnRangeTimePicker2',
    component: CnRangeTimePicker2,
    position: ['RangeTimePicker'],
    props: {
      popupAlign: 'br br',
    },
  },
  {
    label: '日期区间选择器',
    value: 'CnRangeDatePicker2',
    component: CnRangeDatePicker2,
    position: ['RangePicker'],
    props: {
      popupAlign: 'br br',
    },
  },
  {
    label: '日期选择器',
    value: 'CnDatePicker2',
    component: CnDatePickerPro,
    position: ['DatePicker'],
    props: {
      popupAlign: 'br br',
    },
  },
  {
    label: '选择相对时间',
    value: 'buildIn',
    component: RelativeDateSelect,
    position: ['DatePicker', 'RangePicker'],
  },
  {
    label: '文本输入框',
    value: 'CnInput',
    component: CnInput,
    props: {},
  },
  {
    label: '数字输入框',
    value: 'CnNumberPicker',
    component: CnNumberPicker,
    props: {
      precision: 9,
    },
  },
  {
    label: '是 / 否',
    value: 'CnAsyncSelect',
    component: CnAsyncSelect,
    props: {
      dataSource: [
        {
          label: '是',
          value: true,
        },
        {
          label: '否',
          value: false,
        },
      ],
    },
  },
  {
    label: 'JSON编辑器',
    value: 'JSON',
    component: JsonEditor,
    props: {},
  },
  {
    label: '从数据源选择',
    value: 'SelectFromDataSource',
    component: ParamSelectSetter,
    props: {
      dataKey: 'aa',
      labelKey: 'aa',
      valueKey: 'aa',
      groupName: '参数列表',
    },
  },
  {
    label: '默认选中第几项',
    value: 'DefaultSelect',
    position: allowSelectFirstComponentList,
    componentPosition: [
      DisplayPosition.filter,
      DisplayPosition.form,
      DisplayPosition.formDialog,
    ],
    component: CnAsyncSelect,
    props: {
      dataSource: [
        {
          label: '第1项',
          value: 0,
        },
      ],
    },
  },
];
const typeMap = {};
typeList.forEach((item) => {
  typeMap[item.value] = item;
});
function getTypeList(config) {
  const { position, componentPosition } = config;
  const result = [];
  typeList.forEach((item) => {
    if (Array.isArray(item.position) && position) {
      if (item.position.includes(position)) {
        if (item.componentPosition) {
          if (item.componentPosition.includes(componentPosition)) {
            result.push(item);
          }
        } else {
          result.push(item);
        }
      }
    } else {
      result.push(item);
    }
  });
  return result;
}

export default class DefaultValueSetter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  getList = () => {
    const { field, dataKey, labelKey, valueKey, groupName } = this.props;
    const originList = field?.getNode?.()?.getPropValue?.(dataKey);
    const result = [];
    const map = {};
    if (originList?.length > 0) {
      originList.forEach((item) => {
        const { componentName } = item;
        const label = handleI18nLabel(item[labelKey]);
        const value = item[valueKey];
        if (label && value && componentName) {
          result.push({
            label,
            value,
            componentName,
          });
          map[value] = {
            ...item,
            label,
          };
        }
      });
    }
    return { fieldList: result, fieldMap: map };
  };

  changeField = (index, key, v, m, record) => {
    const { value, onChange } = this.props;
    const newValue = [...value];
    if (newValue?.[index]) {
      const temp = {
        [key]: v,
      };
      const { name, valueType } = newValue[index];
      if (key === 'valueType') {
        temp.name = name;
      }
      if (key === 'value') {
        temp.valueType = valueType;
        temp.name = name;
      }
      newValue[index] = temp;
      onChange(newValue);
    }
  };

  addField = () => {
    const { value, onChange } = this.props;
    let newValue;
    if (Array.isArray(value)) {
      newValue = [...value, {}];
    } else {
      newValue = [{}];
    }
    onChange(newValue);
  };

  deleteField = (index) => {
    const { value, onChange } = this.props;
    const newValue = [...value];
    newValue.splice(index, 1);
    onChange(newValue);
  };

  componentDidMount() {
    const { value, onChange } = this.props;
    if (!Array.isArray(value)) {
      onChange('');
    }
  }

  render() {
    const { field, value, onChange, position } = this.props;
    const { fieldList, fieldMap } = this.getList();
    return (
      <div className='cn-default-value-setter'>
        {Array.isArray(value) &&
          value.map((item, index) => {
            const { name, valueType, value: fieldValue } = item;
            const current = fieldMap[name];
            const temp = typeMap[valueType];
            let Component = CnInput;
            let prop;
            if (temp?.component) {
              prop = { ...temp.props };
              Component = temp.component;
              if (current?.componentName === 'RangePicker') {
                prop = {
                  ...prop,
                  hideTime: true,
                  componentName: current?.componentName,
                };
              }
              if (valueType === 'SelectFromDataSource') {
                prop.field = field;
              }
            }
            const extraProps = {};
            const tempDataSource = current?.options?.dataSource;
            if (Array.isArray(tempDataSource) && tempDataSource.length > 0) {
              extraProps.dataSource = tempDataSource.map((item) => {
                item.label = handleI18nLabel(item.label);
                return item;
              });
            }
            const options = { ...current?.options };
            delete options.addonAfter;
            let comProps = {
              ...options,
              ...extraProps,
              ...prop,
            };
            if (valueType === 'DefaultSelect') {
              comProps = { ...prop };
            }
            if (Component === CnInput) {
              comProps = {};
            }
            return (
              <div style={{ marginBottom: '10px' }}>
                <div className={'cdvs-item'}>
                  <CnAsyncSelect
                    autoWidth={false}
                    size={'small'}
                    value={name}
                    style={{ flex: '1' }}
                    dataSource={fieldList}
                    onChange={this.changeField.bind(this, index, 'name')}
                  />
                  <CnAsyncSelect
                    autoWidth={false}
                    size={'small'}
                    value={valueType}
                    style={{ width: '100px', flex: '0 0 100px' }}
                    dataSource={getTypeList({
                      position: current?.componentName,
                      componentPosition: position,
                    })}
                    onChange={this.changeField.bind(this, index, 'valueType')}
                  />
                </div>
                <div className={'cdvs-item'}>
                  <Component
                    {...comProps}
                    size={'small'}
                    style={{ flex: '1 0 70px' }}
                    onChange={this.changeField.bind(this, index, 'value')}
                    value={fieldValue}
                  />
                  <CnIcon
                    onClick={this.deleteField.bind(this, index)}
                    style={{ marginLeft: '5px' }}
                    type='delete'
                    size='medium'
                  />
                </div>
              </div>
            );
          })}
        <Button
          size={'small'}
          onClick={this.addField}
          style={{ type: 'primary', width: '100%' }}
        >
          添加一项
        </Button>
      </div>
    );
  }
}
