import "core-js/modules/es.regexp.exec.js";
import "core-js/modules/es.promise.js";
import "core-js/modules/es.array.sort.js";
import "core-js/modules/es.array.iterator.js";
import "core-js/modules/web.dom-collections.iterator.js";
import React, { useContext, useRef, useCallback, useState, useMemo } from 'react';
import classNames from 'classnames';
import omit from 'omit.js';
import ConfigProvider from '../config-provider';
import QueryFilter from '../wau-query-filter';
import LightFilter from '../wau-light-filter';
import ProForm, { ProFormField } from '../wau-form';
import { runFunction, useDeepCompareEffect, getFieldPropsOrFormItemProps } from '../utils';
import { useIntl } from '../wau-provider';
import { jsx as _jsx } from "react/jsx-runtime";
/**
 * 获取当前选择的 Form Layout 配置
 *
 * @param isForm
 * @param searchConfig
 * @returns LightFilter | QueryFilter | ProForm
 */
const getFormCompetent = (isForm, searchConfig) => {
  if (!isForm && searchConfig !== false) {
    if ((searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.filterType) === 'light') {
      return {
        Competent: LightFilter,
        competentName: 'light-filter'
      };
    }
    return {
      Competent: QueryFilter,
      competentName: 'query-filter'
    };
  }
  return {
    Competent: ProForm,
    competentName: 'form'
  };
};

/**
 * 获取需要传给相应表单的props
 *
 * @param searchConfig
 * @param name
 */
const getFromProps = (isForm, searchConfig, name) => {
  if (!isForm && name === 'light-filter') {
    // 传给 lightFilter 的问题
    return omit({
      ...searchConfig
    }, ['labelWidth', 'defaultCollapsed', 'filterType', 'show']);
  }
  if (!isForm) {
    // 传给 QueryFilter 的配置
    return omit({
      labelWidth: searchConfig ? searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.labelWidth : undefined,
      defaultCollapsed: true,
      ...searchConfig
    }, ['filterType', 'show']);
  }
  return {};
};

/**
 * 从formConfig中获取传给相应表单的配置
 *
 * @param isForm
 * @param formConfig
 */
const getFormConfigs = (isForm, formConfig) => {
  if (isForm) {
    // 传给Form的配置
    return omit(formConfig, ['ignoreRules']);
  }
  // 传给Filter的配置
  return {
    ignoreRules: true,
    ...formConfig
  };
};
/**
 * 把配置转化为输入控件
 *
 * @param props
 * @param ref
 */
export const formInputRender = (props, ref) => {
  var _item$search;
  const {
    item,
    // eslint-disable-next-line
    intl,
    form,
    type,
    formItemProps: propsFormItemProps,
    ...rest
  } = props;
  const formItemProps = getFieldPropsOrFormItemProps(propsFormItemProps, form, item);
  const {
    valueType: itemValueType = 'text'
  } = item;
  // if function， run it
  const valueType = (typeof itemValueType === 'function' ? itemValueType({}, type) : itemValueType) || 'text';
  const {
    onChange,
    ...restFieldProps
  } = getFieldPropsOrFormItemProps(item.fieldProps || {}, form, item);

  /** 公共的 props */
  const initialProps = {
    name: item.key || item.dataIndex,
    initialValue: item.initialValue,
    params: item.params,
    key: `${item.dataIndex || ''}-${item.key || ''}-${item.index}`,
    formItemProps,
    transform: item.search ? (_item$search = item.search) === null || _item$search === void 0 ? void 0 : _item$search.transform : undefined
  };

  /** 自定义 render */
  if (item.renderFormItem && form) {
    /** 删除 renderFormItem 防止重复的 dom 渲染 */
    const {
      renderFormItem,
      ...restItem
    } = item;
    const defaultRender = newItem => formInputRender({
      ...{
        ...props,
        item: newItem
      }
    });

    /** 拼接 renderFormItem 的配置 */
    const renderFormItemProps = omit({
      ...rest,
      type,
      defaultRender
    }, ['colSize']);

    // 自动注入 onChange 和 value，用户自己很有可能忘记
    const dom = renderFormItem({
      ...restItem,
      type: 'form'
    }, renderFormItemProps, form);

    // 有可能不是一个组件
    if (! /*#__PURE__*/React.isValidElement(dom)) {
      return dom;
    }
    const defaultProps = dom.props;
    if (defaultProps.isDefaultDom) {
      return dom;
    }
    return /*#__PURE__*/_jsx(ProFormField, {
      ...rest,
      ...initialProps,
      ref: ref,
      fieldProps: {
        style: {
          width: undefined
        },
        ...item.fieldProps
      },
      children: /*#__PURE__*/React.cloneElement(dom, omit({
        ...rest,
        ...defaultProps
      }, ['colSize']))
    });
  }
  const finalValueType = !valueType || ['textarea', 'jsonCode', 'code'].includes(valueType) && type === 'table' ? 'text' : valueType;
  return /*#__PURE__*/_jsx(ProFormField, {
    ref: ref,
    tooltip: item.tooltip || item.tip,
    isDefaultDom: true,
    valueEnum: runFunction(item.valueEnum, undefined),
    onChange: onChange,
    fieldProps: {
      style: {
        width: undefined
      },
      ...restFieldProps
    },
    ...rest,
    ...initialProps,
    // valueType = textarea，但是在 查询表单这里，应该是个 input 框
    valueType: finalValueType
  });
};
export const proFormItemRender = ({
  item,
  intl,
  formInstance,
  type
}) => {
  const {
    // eslint-disable-next-line
    valueType,
    // eslint-disable-next-line
    dataIndex,
    // eslint-disable-next-line
    valueEnum,
    // eslint-disable-next-line
    renderFormItem,
    // eslint-disable-next-line
    render,
    // eslint-disable-next-line
    hideInForm,
    // eslint-disable-next-line
    hideInSearch,
    // eslint-disable-next-line
    search,
    // eslint-disable-next-line
    hideInTable,
    // eslint-disable-next-line
    renderText,
    // eslint-disable-next-line
    order,
    // eslint-disable-next-line
    width,
    // eslint-disable-next-line
    sorter,
    formItemProps,
    // eslint-disable-next-line
    initialValue,
    // eslint-disable-next-line
    ellipsis,
    // eslint-disable-next-line
    index,
    // eslint-disable-next-line
    filters,
    request,
    params,
    colSize,
    ...rest
  } = item;

  // 支持 function 的 title
  const getTitle = () => {
    if (rest.title && typeof rest.title === 'function') {
      return rest.title(item, 'form', '');
    }
    return rest.title;
  };
  const dom = formInputRender({
    item,
    type,
    intl,
    form: formInstance,
    label: getTitle(),
    request,
    params,
    formItemProps,
    colSize
  });
  if (!dom) {
    return null;
  }
  return dom;
};
const FormSearch = ({
  onSubmit,
  formRef,
  dateFormatter = 'string',
  type,
  columns,
  manualRequest,
  onReset,
  submitButtonLoading,
  search: searchConfig,
  form: formConfig = {},
  bordered
}) => {
  /** 为了支持 dom 的消失，支持了这个 api */
  const intl = useIntl();
  const isForm = type === 'form';
  /** 提交表单，根据两种模式不同，方法不相同 */
  const submit = async (values, firstLoad) => {
    if (onSubmit) {
      onSubmit(values, firstLoad);
    }
  };
  const {
    getPrefixCls
  } = useContext(ConfigProvider.ConfigContext);
  const columnsList = useMemo(() => {
    return columns.filter(item => {
      const {
        valueType
      } = item;
      if ((item.hideInSearch || item.search === false) && type !== 'form') {
        return false;
      }
      if (type === 'form' && item.hideInForm) {
        return false;
      }
      if (valueType !== 'index' && valueType !== 'indexBorder' && valueType !== 'option' && (item.key || item.dataIndex)) {
        return true;
      }
      return false;
    }).sort((a, b) => {
      if (b.order || a.order) {
        return (b.order || 0) - (a.order || 0);
      }
      return (b.index || 0) - (a.index || 0);
    });
  }, [columns, type]);
  const columnsListRef = useRef([]);
  const updateDomList = useCallback(list => {
    const newFormItemList = list.map((item, index) => proFormItemRender({
      isForm,
      formInstance: formRef.current || undefined,
      item: {
        index,
        ...item
      },
      type,
      intl
    })).filter(item => !!item);
    columnsListRef.current = newFormItemList;
    return newFormItemList;
  }, [formRef, intl, isForm, type]);
  const [domList, setDomList] = useState(() => updateDomList(columnsList));
  useDeepCompareEffect(() => {
    if (columnsList.length < 1) return;
    setDomList(updateDomList(columnsList));
  }, [columnsList]);
  const className = getPrefixCls('pro-table-search');
  const formClassName = getPrefixCls('pro-table-form');
  const {
    Competent,
    competentName
  } = useMemo(() => getFormCompetent(isForm, searchConfig), [searchConfig, isForm]);

  // 传给每个表单的配置，理论上大家都需要
  const loadingProps = useMemo(() => ({
    submitter: {
      submitButtonProps: {
        loading: submitButtonLoading
      }
    }
  }), [submitButtonLoading]);
  return /*#__PURE__*/_jsx("div", {
    className: classNames(className, {
      [formClassName]: isForm,
      [getPrefixCls(`pro-table-search-${competentName}`)]: true,
      [`${getPrefixCls('card')}-bordered`]: !!bordered
    }),
    children: /*#__PURE__*/_jsx(Competent, {
      ...loadingProps,
      ...getFromProps(isForm, searchConfig, competentName),
      ...getFormConfigs(isForm, formConfig),
      formRef: formRef,
      onValuesChange: (change, all) => {
        setDomList(updateDomList(columnsList));
        if (formConfig.onValuesChange) {
          formConfig.onValuesChange(change, all);
        }
      },
      dateFormatter: dateFormatter,
      onInit: values => {
        // 触发一个 submit，之所以这里触发是为了保证 value 都被 format了
        if (type !== 'form') {
          // 重新计算一下dom
          setDomList(updateDomList(columnsList));
          /** 如果是手动模式不需要提交 */
          if (manualRequest) return;
          submit(values, true);
        }
      },
      onReset: values => {
        onReset === null || onReset === void 0 ? void 0 : onReset(values);
      },
      onFinish: values => {
        submit(values, false);
      },
      initialValues: formConfig.initialValues,
      children: domList
    })
  });
};
export default /*#__PURE__*/React.memo(FormSearch);