import React, { useMemo, useRef, useState, useEffect } from 'react';
import { Select, Spin } from 'antd';
import { debounce, objectMapper } from '@/utils/commons';

function DebounceSelect({ fetchOptions, debounceTimeout = 500, initLoad = false, defaultOptions=[], ...props }) {
  const [fetching, setFetching] = useState(false);
  const [options, setOptions] = useState([]);
  const fetchRef = useRef(0);

  // 首次加载获取选项
  useEffect(() => {
    setOptions(defaultOptions);
    if (initLoad && defaultOptions.length===0) {
      loadOptions(' ');
    }
  }, [initLoad]);

  const loadOptions = (value) => {
    fetchRef.current += 1;
    const fetchId = fetchRef.current;
    if (value) setOptions([]);
    setFetching(true);
    fetchOptions(value).then((newOptions) => {
      const mapperOptions = newOptions.map(ele => objectMapper(ele, props.map));
      if (fetchId !== fetchRef.current) {
        // for fetch callback order
        return;
      }
      setOptions(mapperOptions);
      setFetching(false);
      props.onFetch && props.onFetch(mapperOptions);
    });
  };

  const debounceFetcher = useMemo(() => {
    return debounce(loadOptions, debounceTimeout);
  }, [fetchOptions, debounceTimeout]);

  return (
    <Select
      labelInValue
      filterOption={false}
      showSearch
      allowClear
      maxTagCount={1}
      loading={fetching}
      // dropdownStyle={{width: '20rem'}}
      styles={{ root: { width: 'min(20rem, 100%)' }, popup: { root: { width: '20rem' } } }}
      {...props}
      onSearch={debounceFetcher}
      notFoundContent={fetching ? <Spin size='small' /> : null}
      optionFilterProp='label'
    >
      {options.map((d) => (
        <Select.Option key={d.value} title={d.label}>
          {d.label}
        </Select.Option>
      ))}
    </Select>
  );
}

export default DebounceSelect;
