import { useState, useCallback, useEffect } from 'react';
import type {
  BasePaginatedOptions,
  PaginatedOptionsWithFormat,
} from '@umijs/use-request/lib/types';
import omit from 'omit.js'
import useUpdateEffect from '@umijs/hooks/lib/useUpdateEffect';


export interface Store {
  [name: string]: any;
}

export interface UseAntdTableFormUtils {
  getFieldInstance?: (name: string) => {}; // antd 3
  setFieldsValue: (value: Store) => void;
  getFieldsValue: (...args: any) => Store;
  resetFields: (...args: any) => void;
  [key: string]: any;
}

export interface BaseOptions<U> extends Omit<BasePaginatedOptions<U>, 'paginated'> {
  form: UseAntdTableFormUtils;
}

export interface OptionsWithFormat<R, Item, U> extends Omit<PaginatedOptionsWithFormat<R, Item, U>, 'paginated'> {
  form: UseAntdTableFormUtils;
}

function handleArray(key: string, formValue: Store) {
  const keys = key.split('-');
  const values = formValue[key];
  const formData = formValue;
  //  && (Array.isArray(values) && values.length === keys.length) || values    日期可能清除为 null
  if (keys.length > 1) {
    keys.forEach((element, index) => {
      if (values === null || values === undefined || values === "") {
        delete formData[element]
      } else {
        const val = values && values[index];
        // eslint-disable-next-line no-underscore-dangle
        formData[element] = val && (val._isAMomentObject ? val.valueOf() : val) || null;
      }
    });
    delete formData[key];
  }
  if (values === null || values === undefined) {
    delete formData[key];
  }
}

function handleValue(formData: Store) {
  const data = formData; // {...formData};
  const keys: string[] = Object.keys(data);
  keys.forEach((element: string) => {
    handleArray(element, data);
  });
  // for (const key in data) {
  //   handleArray(key, data);
  // }
  return data;
}


function useFormTable<R = any, Item = any, U extends Item = any>(
  service: (P: any) => void,
  options: BaseOptions<U> | OptionsWithFormat<R, Item, U>,
  submitHandle?: () => void,
): any {
  const { form, ...restOptions } = options;

  const [type, setType] = useState('simple');

  // 全量 form 数据,包括 simple 和 advance
  const [allFormData, setAllFormData] = useState<Store>({});

  // 获取当前展示的 form 字段值
  const getActivetFieldValues = useCallback((): Store => {
    return form.getFieldsValue(null, () => true);
  }, [form]);

  /* 初始化,或改变了 searchType, 恢复表单数据 */
  useUpdateEffect(() => {
    form.setFieldsValue(allFormData);
  }, [type]);


  const changeType = useCallback(() => {
    const currentFormData = getActivetFieldValues();
    setAllFormData({ ...allFormData, ...currentFormData });

    const targetType = type === 'simple' ? 'advance' : 'simple';
    setType(targetType);
  }, [type, allFormData, getActivetFieldValues]);

  const submit = useCallback((e?: any) => {
    let params = {};
    if (e?.preventDefault) {
      e.preventDefault();
    } else {
      params = e || params;
    }
    setTimeout(() => {
      const activeFormData = getActivetFieldValues();

      // 记录全量数据
      const innerAllFormData = { ...allFormData, pageNumber: 1, pageSize: 10, ...activeFormData, ...params };
      setAllFormData(innerAllFormData);
      service(handleValue(innerAllFormData));
      if (submitHandle) submitHandle();
    });
  }, [getActivetFieldValues, allFormData, type]);

  // 首次加载,手动提交。为了拿到 form 的 initial values
  useEffect(() => {
    // 如果有缓存,则使用缓存,重新请求
    if(!restOptions?.manual){
      form.setFieldsValue(restOptions);
      submit(restOptions);
    }
  }, []);

  const refresh = useCallback(() => {
    service(handleValue(allFormData));
  }, [type, allFormData, getActivetFieldValues]);

  const reset = useCallback(() => {
    form.resetFields();
    submit();
  }, [form, submit]);

  const resetSearch = useCallback((e: any) => {
    form.resetFields();
    setAllFormData({});
    submit(e);
  }, [form, submit]);

  return {
    tableProps: {
      onChange: (pagination: any, filters: any, sorter: any) => {
        const innerAllFormData = { ...allFormData, pageNumber: pagination?.current, pageSize: pagination?.pageSize };
        setAllFormData(innerAllFormData);
        service(handleValue(innerAllFormData))
        console.log(filters)
        console.log(sorter)
      }
    },
    search: {
      submit,
      refresh,
      data: allFormData,
      type,
      changeType,
      reset,
      resetSearch
    }
  }
}

export default useFormTable;