import "core-js/modules/es.promise.js";
import "core-js/modules/es.array.reduce.js";
import React from 'react';
import get from 'rc-util/es/utils/get';
import Typography from '../typography';
import Space from '../space';
import Form from '../form';
import Tooltip from '../tooltip';
import { proFieldParsingValueEnumToArray } from '../wau-field';
import { isNil, omitBoolean, omitUndefinedAndEmptyArr, runFunction } from '../utils';
import LabelIconTip from '../wau-label-icon-tip';
import defaultRenderText from './defaultRender';

/**
 * 检查值是否存在 为了 避开 0 和 false
 *
 * @param value
 */
import { jsx as _jsx } from "react/jsx-runtime";
export const checkUndefinedOrNull = value => value !== undefined && value !== null;

/**
 * 根据 key 和 dataIndex 生成唯一 id
 *
 * @param key 用户设置的 key
 * @param dataIndex 在对象中的数据
 * @param index 序列号，理论上唯一
 */
export const genColumnKey = (key, index) => {
  if (key) {
    return Array.isArray(key) ? key.join('-') : key.toString();
  }
  return `${index}`;
};

/**
 * 生成 Ellipsis 的 tooltip
 *
 * @param dom
 * @param item
 * @param text
 */
export const genEllipsis = (dom, item, text) => {
  if (!item.ellipsis) {
    return dom;
  }
  return /*#__PURE__*/_jsx(Tooltip, {
    title: text,
    children: /*#__PURE__*/_jsx("span", {
      children: dom
    })
  });
};
export const genCopyable = (dom, item, text) => {
  if (item.copyable || item.ellipsis) {
    return /*#__PURE__*/_jsx(Typography.Text, {
      style: {
        maxWidth: '100%',
        margin: 0,
        padding: 0
      },
      title: "",
      copyable: item.copyable && text ? {
        text,
        tooltips: ['', '']
      } : undefined,
      ellipsis: item.ellipsis,
      children: dom
    });
  }
  return dom;
};

/**
 * 合并用户 props 和 预设的 props
 *
 * @param pagination
 * @param action
 * @param intl
 */
export function mergePagination(pagination = {}, pageInfo, intl) {
  if (pagination === false) {
    return false;
  }
  const {
    total,
    current,
    pageSize,
    setPageInfo
  } = pageInfo;
  const defaultPagination = typeof pagination === 'object' ? pagination : {};
  return {
    showTotal: (all, range) => `${intl.getMessage('pagination.total.range', '第')} ${range[0]}-${range[1]} ${intl.getMessage('pagination.total.total', '条，共')} ${all} ${intl.getMessage('pagination.total.item', '条')}`,
    total,
    size: 'default',
    ...defaultPagination,
    showSizeChanger: true,
    showQuickJumper: false,
    current,
    pageSize,
    onChange: (page, newPageSize) => {
      const {
        onChange
      } = pagination;
      onChange === null || onChange === void 0 ? void 0 : onChange(page, newPageSize || 20);
      // pageSize 改变之后就没必要切换页码
      if (newPageSize !== pageSize || current !== page) {
        setPageInfo({
          pageSize: newPageSize,
          current: page
        });
      }
    }
  };
}

/**
 * 获取用户的 action 信息
 *
 * @param actionRef
 * @param counter
 * @param onCleanSelected
 */
export function useActionType(ref, action, props) {
  /** 这里生成action的映射，保证 action 总是使用的最新 只需要渲染一次即可 */
  const userAction = {
    ...props.editableUtils,
    pageInfo: action.pageInfo,
    reload: async resetPageIndex => {
      // 如果为 true，回到第一页
      if (resetPageIndex) {
        await action.setPageInfo({
          current: 1
        });
      }
      await (action === null || action === void 0 ? void 0 : action.reload());
    },
    reloadAndRest: async () => {
      // reload 之后大概率会切换数据，清空一下选择。
      props.onCleanSelected();
      await action.setPageInfo({
        current: 1
      });
      await (action === null || action === void 0 ? void 0 : action.reload());
    },
    reset: async () => {
      var _action$reset;
      await props.resetAll();
      await (action === null || action === void 0 || (_action$reset = action.reset) === null || _action$reset === void 0 ? void 0 : _action$reset.call(action));
      await (action === null || action === void 0 ? void 0 : action.reload());
    },
    fullScreen: () => props.fullScreen(),
    clearSelected: () => props.onCleanSelected(),
    setPageInfo: rest => action.setPageInfo(rest)
  };
  // eslint-disable-next-line no-param-reassign
  ref.current = userAction;
}
/**
 * 一个转化的 pipeline 列表
 *
 * @param data
 * @param pipeline
 */
export function postDataPipeline(data, pipeline) {
  if (pipeline.filter(item => item).length < 1) {
    return data;
  }
  return pipeline.reduce((pre, postData) => {
    return postData(pre);
  }, data);
}
export const tableColumnSort = columnsMap => (a, b) => {
  var _columnsMap$aKey, _columnsMap$bKey;
  const {
    fixed: aFixed,
    index: aIndex
  } = a;
  const {
    fixed: bFixed,
    index: bIndex
  } = b;
  if (aFixed === 'left' && bFixed !== 'left' || bFixed === 'right' && aFixed !== 'right') {
    return -2;
  }
  if (bFixed === 'left' && aFixed !== 'left' || aFixed === 'right' && bFixed !== 'right') {
    return 2;
  }
  // 如果没有index，在 dataIndex 或者 key 不存在的时候他会报错
  const aKey = a.key || `${aIndex}`;
  const bKey = b.key || `${bIndex}`;
  if ((_columnsMap$aKey = columnsMap[aKey]) !== null && _columnsMap$aKey !== void 0 && _columnsMap$aKey.order || (_columnsMap$bKey = columnsMap[bKey]) !== null && _columnsMap$bKey !== void 0 && _columnsMap$bKey.order) {
    var _columnsMap$aKey2, _columnsMap$bKey2;
    return (((_columnsMap$aKey2 = columnsMap[aKey]) === null || _columnsMap$aKey2 === void 0 ? void 0 : _columnsMap$aKey2.order) || 0) - (((_columnsMap$bKey2 = columnsMap[bKey]) === null || _columnsMap$bKey2 === void 0 ? void 0 : _columnsMap$bKey2.order) || 0);
  }
  return (a.index || 0) - (b.index || 0);
};

/**
 * 增加了 icon 的功能 render title
 *
 * @param item
 */
export const renderColumnsTitle = item => {
  const {
    title
  } = item;
  if (title && typeof title === 'function') {
    return title(item, 'table', /*#__PURE__*/_jsx(LabelIconTip, {
      label: title,
      tooltip: item.tooltip || item.tip
    }));
  }
  return /*#__PURE__*/_jsx(LabelIconTip, {
    label: title,
    tooltip: item.tooltip || item.tip
  });
};
export const defaultOnFilter = (value, record, dataIndex) => {
  const recordElement = Array.isArray(dataIndex) ? get(record, dataIndex) : record[dataIndex];
  const itemValue = String(recordElement);
  return String(itemValue) === String(value);
};

/** 转化列的定义 */

const isMergeCell = (dom // 如果是合并单元格的，直接返回对象
) => {
  var _dom$props;
  return dom && typeof dom === 'object' && (dom === null || dom === void 0 || (_dom$props = dom.props) === null || _dom$props === void 0 ? void 0 : _dom$props.colSpan);
};

/** 判断可不可编辑 */
function isEditableCell(text, rowData, index, editable) {
  if (typeof editable === 'boolean') {
    return editable === false;
  }
  return (editable === null || editable === void 0 ? void 0 : editable(text, rowData, index)) === false;
}

/**
 * 这个组件负责单元格的具体渲染
 *
 * @param param0
 */
export function columnRender({
  columnProps,
  text,
  rowData,
  index,
  columnEmptyText,
  counter,
  type,
  editableUtils
}) {
  const {
    action
  } = counter;
  const {
    isEditable,
    recordKey
  } = editableUtils.isEditable({
    ...rowData,
    index
  });
  const {
    renderText = val => val
  } = columnProps;
  const renderTextStr = renderText(text, rowData, index, action.current);
  const mode = isEditable && !isEditableCell(text, rowData, index, columnProps === null || columnProps === void 0 ? void 0 : columnProps.editable) ? 'edit' : 'read';
  const textDom = defaultRenderText({
    text: renderTextStr,
    valueType: columnProps.valueType || 'text',
    index,
    rowData,
    columnProps,
    columnEmptyText,
    type,
    recordKey,
    mode
  });
  const dom = mode === 'edit' ? textDom : genEllipsis(genCopyable(textDom, columnProps, renderTextStr), columnProps, renderTextStr);

  /** 如果是编辑模式，并且 renderFormItem 存在直接走 renderFormItem */
  if (mode === 'edit') {
    if (columnProps.valueType === 'option') {
      return /*#__PURE__*/_jsx(Form.Item, {
        shouldUpdate: true,
        noStyle: true,
        children: form => /*#__PURE__*/_jsx(Space, {
          size: 16,
          children: editableUtils.actionRender({
            ...rowData,
            index: columnProps.index || index
          }, form)
        })
      });
    }
    return dom;
  }
  if (columnProps.render) {
    const renderDom = columnProps.render(dom, rowData, index, {
      ...action.current,
      ...editableUtils
    }, {
      ...columnProps,
      isEditable,
      type: 'table'
    });

    // 如果是合并单元格的，直接返回对象
    if (isMergeCell(renderDom)) {
      return renderDom;
    }
    if (renderDom && columnProps.valueType === 'option' && Array.isArray(renderDom)) {
      return /*#__PURE__*/_jsx(Space, {
        size: 16,
        children: renderDom
      });
    }
    return renderDom;
  }
  return !isNil(dom) ? dom : null;
}

/**
 * 转化 columns 到 pro 的格式 主要是 render 方法的自行实现
 *
 * @param columns
 * @param map
 * @param columnEmptyText
 */
export function genColumnList(props) {
  const {
    columns,
    map,
    counter,
    columnEmptyText,
    type,
    editableUtils
  } = props;
  return columns.map((columnProps, columnsIndex) => {
    const {
      key,
      dataIndex,
      valueEnum,
      valueType,
      children,
      onFilter,
      filters = []
    } = columnProps;
    const columnKey = genColumnKey(key, columnsIndex);
    // 这些都没有，说明是普通的表格不需要 pro 管理
    const noNeedPro = !dataIndex && !valueEnum && !valueType && !children;
    if (noNeedPro) {
      return {
        index: columnsIndex,
        ...columnProps
      };
    }
    const {
      propsRef
    } = counter;
    const config = map[columnKey] || {
      fixed: columnProps.fixed
    };
    const genOnFilter = () => {
      var _propsRef$current;
      if (!((_propsRef$current = propsRef.current) !== null && _propsRef$current !== void 0 && _propsRef$current.request) || onFilter === true) {
        return (value, row) => defaultOnFilter(value, row, dataIndex);
      }
      return omitBoolean(onFilter);
    };
    const tempColumns = {
      index: columnsIndex,
      ...columnProps,
      title: renderColumnsTitle(columnProps),
      valueEnum,
      filters: filters === true ? proFieldParsingValueEnumToArray(runFunction(valueEnum, undefined)).filter(valueItem => valueItem && valueItem.value !== 'all') : filters,
      onFilter: genOnFilter(),
      ellipsis: false,
      fixed: config.fixed,
      width: columnProps.width || (columnProps.fixed ? 200 : undefined),
      children: columnProps.children ? genColumnList({
        ...props,
        columns: columnProps === null || columnProps === void 0 ? void 0 : columnProps.children
      }) : undefined,
      render: (text, rowData, index) => {
        const renderProps = {
          columnProps,
          text,
          rowData,
          index,
          columnEmptyText,
          counter,
          type,
          editableUtils
        };
        return columnRender(renderProps);
      }
    };
    return omitUndefinedAndEmptyArr(tempColumns);
  }).filter(item => !item.hideInTable);
}