import "core-js/modules/es.array.iterator.js";
import "core-js/modules/web.dom-collections.iterator.js";
import "core-js/modules/es.promise.js";
import { useCallback, useMemo } from 'react';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import ReactDOM from 'react-dom';
import { useIntl } from '../../wau-provider';
import message from '../../message';
import { defaultActionRender, recordKeyToString } from '../useEditableArray';
import '../../message/style';

/**
 * 使用map 来删除数据，性能一般 但是准确率比较高
 *
 * @param params
 * @param action
 */
function editableRowByKey({
  data,
  row
}) {
  return {
    ...data,
    ...row
  };
}
/**
 * 一个方便的hooks 用于维护编辑的状态
 *
 * @param props
 */
function useEditableMap(props) {
  const editableType = props.type || 'single';
  const [editableKeys, setEditableRowKeys] = useMergedState([], {
    value: props.editableKeys,
    onChange: props.onChange ? keys => {
      var _props$onChange;
      props === null || props === void 0 || (_props$onChange = props.onChange) === null || _props$onChange === void 0 ? void 0 : _props$onChange.call(props,
      // 计算编辑的key
      keys, props.dataSource);
    } : undefined
  });
  /** 一个用来标志的set 提供了方便的 api 来去重什么的 */
  const editableKeysSet = useMemo(() => {
    const keys = editableType === 'single' ? editableKeys.slice(0, 1) : editableKeys;
    return new Set(keys);
  }, [editableKeys.join(','), editableType]);

  /** 这行是不是编辑状态 */
  const isEditable = useCallback(recordKey => {
    if (editableKeys.includes(recordKeyToString(recordKey))) return true;
    return false;
  }, [editableKeys.join(',')]);

  /**
   * 进入编辑状态
   *
   * @param recordKey
   */
  const startEditable = recordKey => {
    // 如果是单行的话，不允许多行编辑
    if (editableKeysSet.size > 0 && editableType === 'single') {
      message.warn(props.onlyOneLineEditorAlertMessage || '只能同时编辑一行');
      return false;
    }
    editableKeysSet.add(recordKeyToString(recordKey));
    setEditableRowKeys(Array.from(editableKeysSet));
    return true;
  };

  /**
   * 退出编辑状态
   *
   * @param recordKey
   */
  const cancelEditable = recordKey => {
    // 防止多次渲染
    ReactDOM.unstable_batchedUpdates(() => {
      editableKeysSet.delete(recordKeyToString(recordKey));
      setEditableRowKeys(Array.from(editableKeysSet));
    });
    return true;
  };
  const onCancel = async (recordKey, editRow, isNewLine) => {
    var _props$onCancel;
    const success = await (props === null || props === void 0 || (_props$onCancel = props.onCancel) === null || _props$onCancel === void 0 ? void 0 : _props$onCancel.call(props, recordKey, editRow, isNewLine));
    if (success === false) {
      return false;
    }
    return true;
  };
  const onSave = async (recordKey, editRow) => {
    var _props$onSave;
    const success = await (props === null || props === void 0 || (_props$onSave = props.onSave) === null || _props$onSave === void 0 ? void 0 : _props$onSave.call(props, recordKey, editRow));
    if (success === false) {
      return false;
    }
    cancelEditable(recordKey);
    const actionProps = {
      data: props.dataSource,
      row: editRow,
      key: recordKey,
      childrenColumnName: props.childrenColumnName || 'children'
    };
    props.setDataSource(editableRowByKey(actionProps));
    return true;
  };

  // Internationalization
  const intl = useIntl();
  const saveText = intl.getMessage('editableTable.action.save', '保存');
  const deleteText = intl.getMessage('editableTable.action.delete', '删除');
  const cancelText = intl.getMessage('editableTable.action.cancel', '取消');
  const actionRender = useCallback((key, form, config) => {
    const renderConfig = {
      recordKey: recordKeyToString(key),
      cancelEditable,
      onCancel,
      onSave,
      editableKeys,
      setEditableRowKeys,
      form,
      saveText,
      cancelText,
      deleteText,
      deletePopconfirmMessage: '删除此行？',
      editorType: 'Map',
      ...config
    };
    const defaultDoms = defaultActionRender(props.dataSource, renderConfig);
    if (props.actionRender) return props.actionRender(props.dataSource, renderConfig, {
      save: defaultDoms[0],
      delete: defaultDoms[1],
      cancel: defaultDoms[2]
    });
    return defaultDoms;
  }, [editableKeys.join(',')]);
  return {
    editableKeys,
    setEditableRowKeys,
    isEditable,
    actionRender,
    startEditable,
    cancelEditable
  };
}
export default useEditableMap;