import * as React from 'react';
import {
  useEffect,
  useMemo,
  useState,
} from 'react';
import * as moment from 'moment';
import { FastForm } from 'components/ui';
import { Component } from 'components/types';
import Action from 'components/basic/Action';
import { getSearchParam, setDefaultValue } from 'utils/tool';
import { isArray } from 'utils/isType';
import { App } from 'utils/types';
import { SearchProps } from './types';

const useSearch = (props: SearchProps) => {
  const {
    config,
    handle,
    // compRef,
    dict,
    onSetFilterParams,
  } = props;
  const {
    uuid,
    filter,
    action,
    notInit,
  } = config;

  // 生成表单初始值
  const initialValues = useMemo(() => {
    const defaultData = {};
    for (let i = 0, len = filter.length; i < len; i += 1) {
      const item = filter[i];
      const {
        key,
        defaultValue,
      } = item;
      defaultData[key] = getSearchParam(key) || setDefaultValue(defaultValue);
      if (key === 'range1') {
        defaultData[key] = [moment().startOf('day').format('YYYY-MM-DD HH:mm:ss'), moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')];
      }
      if (key === 'range2') {
        defaultData[key] = [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')];
      }
    }
    return defaultData;
  }, [filter]);

  const [formInstance] = FastForm.useForm();
  const [values, setValues] = useState(initialValues);
  const [formList, setFormList] = useState(filter);

  // 格式化数据
  const formatedData = (rawData: App.Dict) => {
    const newData = {};
    for (let i = 0, len = filter.length; i < len; i += 1) {
      const item = filter[i];
      const {
        notSubmit,
        key,
        type,
        startDateKey,
        endDateKey,
        ajaxKey,
        notSwitchArrToStr,
        switchArrToStrSeparator,
      } = item;
      if (!notSubmit) {
        if (type === 'daterangepicker') {
          const [startDate, endDate] = rawData[key];
          newData[startDateKey as string] = startDate;
          newData[endDateKey as string] = endDate;
        } else if (isArray(rawData[key]) && !notSwitchArrToStr) {
          newData[ajaxKey || key] = rawData[key].join(switchArrToStrSeparator || ',');
        } else {
          newData[ajaxKey || key] = rawData[key];
        }
      }
    }
    return newData;
  };

  const handleSearch = () => {
    const submitConfig = action.find(
      (actionItem: Component.Business.Action) =>
        actionItem.type === Component.Business.TriggerType.search
    );
    if (submitConfig) {
      const submitActionConfig = submitConfig.result.find(
        (resultItem: Component.Business.Result) =>
          resultItem.type === Component.Business.ResultType.fetch
      )
      if (submitActionConfig) {
        const { moduleIds, type } = submitActionConfig as Component.Business.Result;
        handle(type, moduleIds, formatedData(values), "search");
      }
    }
  };

  const handleReset = () => {
    setValues(initialValues);
  };

  // 更新form列表
  const updateFormList = () => {
    const newForms = [];
    for (let i = 0, len = filter.length; i < len; i += 1) {
      const item = filter[i];
      const { interact } = item;
      if (interact) {
        const { type, trigger, triggerKey } = interact;
        if (trigger === "contain") {
          const { triggerValue = [] } = interact;
          if (type === "show") {
            if (triggerValue.includes(values[triggerKey as string])) {
              newForms.push(item);
            }
          } else if (type === "disabled") {
            if (triggerValue.includes(values[triggerKey as string])) {
              newForms.push({ ...item, notModify: true });
            } else {
              newForms.push(item);
            }
          }
        } else if (trigger === "notContain") {
          const { triggerValue = [] } = interact;
          if (type === "show") {
            if (
              !triggerValue.includes(values[triggerKey as string]) &&
              !(
                values[triggerKey as string] === undefined &&
                triggerValue.includes("undefined")
              )
            ) {
              newForms.push(item);
            }
          } else if (type === "disabled") {
            if (!triggerValue.includes(values[triggerKey as string])) {
              newForms.push({ ...item, notModify: true });
            } else {
              newForms.push(item);
            }
          }
        } else {
          newForms.push(item);
        }
      } else {
        newForms.push(item);
      }
    }
    setFormList(newForms);
  };

  useEffect(updateFormList, [filter, values]);

  // 生成行为按钮
  const createActionBtns = (
    actionList: Component.Business.Action[],
    data?: App.Dict
  ) =>
    actionList.map((actionItem: Component.Business.Action) => {
      const { type, label } = actionItem;
      let handleActionClick = null;

      if (type === Component.Business.TriggerType.reset) {
        handleActionClick = handleReset;
      } else if (type === Component.Business.TriggerType.search) {
        handleActionClick = () => {
          handleSearch();
          return Promise.reject();
        };
      }

      return (
        <Action
          key={label}
          moduleUuid={uuid}
          action={actionItem}
          handle={handle}
          data={data}
          onActionClick={handleActionClick}
        />
      );
    });

  const immeEffectValues = () => {
    const newValues: any = [];
    Object.keys(values).forEach((key) => {
      const targetFilter = filter.find((filteItem) => filteItem.key === key);
      if (targetFilter && targetFilter.immeEffect) {
        newValues.push(values[key]);
      }
    });
    return newValues;
  };

  // 筛选立即生效
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(handleSearch, immeEffectValues());

  // 更新页面容器筛选参数
  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => onSetFilterParams(formatedData(values)), [values]);

  return {
    actionList: action,
    formList,
    formInstance,
    initialValues,
    values,
    notInit,
    dict,
    setValues,
    handleSearch,
    createActionBtns,
  };
};

export default useSearch;
