import { useCallback, useState, useEffect } from 'react';
// import { useSelector } from 'react-redux';
import { App } from 'utils/types';
import fetchData from 'utils/fetchData';
import transformer from 'utils/transformer';
import { CheckboxOptionType } from 'components/ui';
import { FormTypes } from '../../types';

const DEFAULT_LIST_KEY = 'list';

const useOptions = (props: FormTypes.FormItem.FormAtomicSelectProps) => {
  const { config, dict } = props;
  // const aliasState = useSelector((state: any) => state.alias);
  const [options, updateOptions] = useState<CheckboxOptionType[]>([]);
  const {
    type,
    dataKey,
    dataLabel,
    ajax,
    resFormat = FormTypes.FormItem.OptionsResultFormatType.NONE,
    separator,
    listKey = DEFAULT_LIST_KEY,
    alias,
    aliasKey,
    aliasLabel,
    resFunc,
    onlyChildSelected,
  } = config;
  const label = aliasLabel || 'label';
  const value = aliasKey || 'value';
  const formatData = (data: (App.Dict[] | string[] | string)) => {
    if (alias) return data;
    let resData = [];
    if (resFormat === FormTypes.FormItem.OptionsResultFormatType.STR_ARR) {
      resData = (data as string[]).map((item: string) => ({
        [value]: item,
        [label]: item,
      }));
    } else if (resFormat === FormTypes.FormItem.OptionsResultFormatType.STR) {
      resData = (data as string).split(separator as string).map((item: string) => ({
        [value]: item,
        [label]: item,
      }));
    } else if (dataKey && dataLabel) {
      if ([
        FormTypes.FormItem.FormAtomicType.treeselect,
        FormTypes.FormItem.FormAtomicType.multtreeselect,
        FormTypes.FormItem.FormAtomicType.cascader,
        FormTypes.FormItem.FormAtomicType.multcascader,
      ].includes(type)) {
        resData = data as any[];
        transformer.tree(resData, {
          dataKey,
          dataLabel,
          onlyChildSelected,
        });
      } else if (resFunc) {
        resData = transformer[resFunc](data);
      } else {
        resData = (data as any[]).map((item: string) => ({
          [value]: item[dataKey],
          [label]: item[dataLabel],
        }));
      }
    } else {
      resData = data as App.Dict[];
    }
    return resData;
  };

  const fetchDataHandler = useCallback(
    (params?: App.Dict) => {
      if (ajax) {
        return fetchData(ajax, params || {}).then((rs: App.Dict) => {
          const data = rs[listKey] || rs;
          const resData = formatData(data);
          updateOptions(resData);
          return Promise.resolve(resData);
        });
      }
      return Promise.reject();
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [ajax?.url]
  );

  const handleSetOptions = useCallback(
    (params?: App.Dict) => {
      if (alias) {
        const newFormData = formatData(dict[alias]);
        updateOptions(newFormData);
        return Promise.resolve(newFormData);
      }
      return fetchDataHandler(params).then((newFormData) => {
        return Promise.resolve(newFormData);
      });
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [alias, ajax?.url]
  );

  useEffect(() => {
    if (alias) updateOptions(formatData(dict[alias]));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dict[alias as string]]);

  return {
    ajaxOptions: options,
    setOptions: handleSetOptions,
  };
};

export default useOptions;
