import "core-js/modules/es.array.iterator.js";
import "core-js/modules/web.dom-collections.iterator.js";
import "core-js/modules/es.regexp.exec.js";
import "core-js/modules/es.promise.js";
import "core-js/modules/es.array.reduce.js";
import React, { useState, useImperativeHandle, useRef, useContext, useCallback, useEffect } from 'react';
import useSWR from 'swr';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import SizeContext from 'antd/es/config-provider/SizeContext';
import omit from 'omit.js';
import Spin from '../spin';
import Space from '../space';
import Select from '../select';
import { useIntl } from '../wau-provider';
import { useDeepCompareEffect } from '../utils';
import LightSelect from './light-select';
import TableStatus, { ProFieldBadgeColor } from '../wau-status-field';
import './style';
import { jsx as _jsx } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
let testId = 0;
export const ObjToMap = value => {
  if (getType(value) === 'map') {
    return value;
  }
  return new Map(Object.entries(value || {}));
};

/**
 * 转化 text 和 valueEnum 通过 type 来添加 Status
 *
 * @param text
 * @param valueEnum
 * @param pure 纯净模式，不增加 status
 */
export const proFieldParsingText = (text, valueEnumParams) => {
  if (Array.isArray(text)) {
    return /*#__PURE__*/_jsx(Space, {
      children: text.map(value =>
      /*#__PURE__*/
      // @ts-ignore
      _jsx(React.Fragment, {
        children: proFieldParsingText(value, valueEnumParams)
      }, (value === null || value === void 0 ? void 0 : value.value) || value))
    });
  }
  const valueEnum = ObjToMap(valueEnumParams);
  if (!valueEnum.has(text) && !valueEnum.has(`${text}`)) {
    // @ts-ignore
    return (text === null || text === void 0 ? void 0 : text.label) || text;
  }
  const domText = valueEnum.get(text) || valueEnum.get(`${text}`);
  if (!domText) {
    // @ts-ignore
    return (text === null || text === void 0 ? void 0 : text.label) || text;
  }
  const {
    status,
    color
  } = domText;
  const Status = TableStatus[status || 'Init'];
  // 如果类型存在优先使用类型
  if (Status) {
    return /*#__PURE__*/_jsx(Status, {
      children: domText.text
    });
  }

  // 如果不存在使用颜色
  if (color) {
    return /*#__PURE__*/_jsx(ProFieldBadgeColor, {
      color: color,
      children: domText.text
    });
  }
  // 什么都没有使用 text
  return domText.text || domText;
};

/**
 * 获取类型的 type
 *
 * @param obj
 */
function getType(obj) {
  // @ts-ignore
  const type = Object.prototype.toString.call(obj).match(/^\[object (.*)\]$/)[1].toLowerCase();
  if (type === 'string' && typeof obj === 'object') return 'object'; // Let "new String('')" return 'object'
  if (obj === null) return 'null'; // PhantomJS has type "DOMWindow" for null
  if (obj === undefined) return 'undefined'; // PhantomJS has type "DOMWindow" for undefined
  return type;
}

/**
 * 把 value 的枚举转化为数组
 *
 * @param valueEnum
 */
export const proFieldParsingValueEnumToArray = (valueEnumParams = new Map()) => {
  const enumArray = [];
  const valueEnum = ObjToMap(valueEnumParams);
  valueEnum.forEach((_, key) => {
    const value = valueEnum.get(key) || valueEnum.get(`${key}`);
    if (!value) {
      return;
    }
    if (typeof value === 'object' && value !== null && value !== void 0 && value.text) {
      enumArray.push({
        text: value === null || value === void 0 ? void 0 : value.text,
        value: key,
        disabled: value.disabled
      });
      return;
    }
    enumArray.push({
      text: value,
      value: key
    });
  });
  return enumArray;
};
export const useFieldFetchData = props => {
  var _props$fieldProps;
  /** Key 是用来缓存请求的，如果不在是有问题 */
  const [cacheKey] = useState(() => {
    if (props.proFieldKey) {
      return props.proFieldKey;
    }
    if (props.request) {
      testId += 1;
      return testId;
    }
    return 'no-fetch';
  });
  const proFieldKeyRef = useRef(cacheKey);
  const getOptionsFormValueEnum = useCallback(valueEnum => {
    return proFieldParsingValueEnumToArray(ObjToMap(valueEnum)).map(({
      value,
      text,
      ...rest
    }) => ({
      label: text,
      value,
      key: value,
      ...rest
    }));
  }, []);
  const [options, setOptions] = useMergedState(() => {
    if (props.valueEnum) {
      return getOptionsFormValueEnum(props.valueEnum);
    }
    return [];
  }, {
    value: (_props$fieldProps = props.fieldProps) === null || _props$fieldProps === void 0 ? void 0 : _props$fieldProps.options
  });
  useDeepCompareEffect(() => {
    var _props$fieldProps2;
    // 优先使用 fieldProps?.options
    if (!props.valueEnum || (_props$fieldProps2 = props.fieldProps) !== null && _props$fieldProps2 !== void 0 && _props$fieldProps2.options) return;
    setOptions(getOptionsFormValueEnum(props.valueEnum));
  }, [props.valueEnum]);
  const [loading, setLoading] = useState(false);
  const {
    data,
    mutate
  } = useSWR([proFieldKeyRef.current, JSON.stringify(props.params)], async () => {
    if (props.request) {
      setLoading(true);
      const fetchData = await props.request(props.params, props);
      setLoading(false);
      return fetchData;
    }
    return [];
  }, {
    revalidateOnFocus: false
  });
  return [loading, props.request ? data : options, async () => {
    if (!props.request) return;
    setLoading(true);
    const fetchData = await props.request(props.params, props);
    setLoading(false);
    mutate(fetchData, false);
  }];
};

/**
 * 可以根据 valueEnum 来进行类型的设置
 *
 * @param
 */
const FieldSelect = (props, ref) => {
  const {
    mode,
    valueEnum,
    render,
    renderFormItem,
    fieldProps,
    light,
    // eslint-disable-next-line
    proFieldKey,
    ...rest
  } = props;
  const inputRef = useRef();
  const intl = useIntl();
  useEffect(() => {
    testId += 1;
  }, []);
  const [loading, options, fetchData] = useFieldFetchData(props);
  const size = useContext(SizeContext);
  useImperativeHandle(ref, () => ({
    ...(inputRef.current || {}),
    fetchData: () => fetchData()
  }));
  if (loading) {
    return /*#__PURE__*/_jsx(Spin, {});
  }
  if (mode === 'read') {
    var _rest$text;
    const optionsValueEnum = options !== null && options !== void 0 && options.length ? options === null || options === void 0 ? void 0 : options.reduce((pre, cur) => {
      return {
        ...pre,
        [cur.value]: cur.label
      };
    }, {}) : undefined;
    // 如果有 label 直接就用 label
    // @ts-ignore
    if ((_rest$text = rest.text) !== null && _rest$text !== void 0 && _rest$text.label) {
      var _rest$text2;
      // @ts-ignore
      return (_rest$text2 = rest.text) === null || _rest$text2 === void 0 ? void 0 : _rest$text2.label;
    }
    const dom = /*#__PURE__*/_jsx(_Fragment, {
      children: proFieldParsingText(rest.text, ObjToMap(valueEnum || optionsValueEnum))
    });
    if (render) {
      return render(rest.text, {
        mode,
        ...fieldProps
      }, dom) || null;
    }
    return dom;
  }
  if (mode === 'edit' || mode === 'update') {
    const renderDom = () => {
      if (light) {
        return /*#__PURE__*/_jsx(LightSelect, {
          loading: loading,
          ref: inputRef,
          allowClear: true,
          size: size,
          ...omit(rest, ['request']),
          options: options,
          ...fieldProps
        });
      }
      return /*#__PURE__*/_jsx(Select, {
        style: {
          minWidth: 100
        },
        loading: loading,
        ref: inputRef,
        allowClear: true,
        ...omit(rest, ['request']),
        placeholder: intl.getMessage('tableForm.selectPlaceholder', '请选择'),
        options: options,
        ...fieldProps
      });
    };
    const dom = renderDom();
    if (renderFormItem) {
      return renderFormItem(rest.text, {
        mode,
        ...fieldProps,
        options
      }, dom) || null;
    }
    return dom;
  }
  return null;
};
export default /*#__PURE__*/React.forwardRef(FieldSelect);