import {addMenu, editMenu, getMenuList} from '@apis';
import {yupResolver} from '@hookform/resolvers/yup';
import {useContextSection, usePage} from '@hooks';
import {MenuListData} from '@models';
import {pIdContext} from '@pages/menu-id/context';
import {context, pageContext} from '@pages/menu/context';
import {useMutation, useQueryClient} from '@tanstack/react-query';
import {message} from 'antd';
import {useEffect, useMemo} from 'react';
import {useForm} from 'react-hook-form';
import {object, string} from 'yup';

type FormState = {
  menuName: string;
  menuUrl: string;
  menuOrderBy: string;
};

const validate = object({
  menuName: string().required('请输入菜单名称'),
  menuUrl: string().required('请输入菜单路径'),
  menuOrderBy: string().required('请输入菜单排序'),
});

function useAdd(onClose: () => void, onFetch: () => void) {
  const {isLoading, mutate} = useMutation(
    addMenu,
    {
      onSuccess(data) {
        if (data.msg === '200') {
          onClose();
          onFetch();
          message.success('新增成功');
        }
      },
    },
  );

  return [isLoading, mutate] as const;
}

function useEdit(onClose: () => void, onFetch: () => void) {
  const {isLoading, mutate} = useMutation(
    editMenu,
    {
      onSuccess(data) {
        if (data.msg === '200') {
          onClose();
          onFetch();
          message.success('修改成功');
        }
      },
    },
  );

  return [isLoading, mutate] as const;
}

function useEditData(id: string, isEdit: boolean) {
  const client = useQueryClient();
  const pId = useContextSection(pIdContext, ([pid]) => pid);
  const [{page, pageSize}] = usePage(pageContext);
  const name = useContextSection(context, state => state[0].name);
  return useMemo(function() {
    if (!isEdit) return null;

    const list = client.getQueryData<MenuListData[]>(
      [getMenuList.name, pId, page, pageSize, name],
    );

    const result = list?.find(val => val.id === id);

    return result;
  }, [isEdit, client, pId, page, pageSize, name, id]);
}

export function useFormState(
  {onClose, id, visible, onFetch}:
  {
    id: string, visible: boolean,
    onFetch: () => void, onClose: () => void,
  },
) {
  const isEdit = Boolean(id.length);
  const pid = useContextSection(pIdContext, ([pid]) => pid);
  const editData = useEditData(id, isEdit);
  const {handleSubmit, control, setValue, clearErrors} = useForm<FormState>({
    defaultValues: {
      menuName: '',
      menuUrl: '',
      menuOrderBy: '0',
    },
    resolver: yupResolver(validate),
  });
  const [addIsLoading, addMutate] = useAdd(onClose, onFetch);
  const [editIsLoaindg, editMutate] = useEdit(onClose, onFetch);
  const isLoading = addIsLoading || editIsLoaindg;

  useEffect(function() {
    if (visible) {
      setValue('menuName', editData?.name ?? '');
      setValue('menuUrl', editData?.url ?? '');
      setValue('menuOrderBy', editData?.orderBy ?? '0');
      clearErrors();
    }
  }, [clearErrors, editData, setValue, visible]);

  const onSubmit = handleSubmit(function({menuName, menuUrl, menuOrderBy}) {
    isEdit
      ? editMutate({name: menuName, url: menuUrl, id, pId: pid ?? '0', orderBy: menuOrderBy})
      : addMutate({name: menuName, url: menuUrl, pId: pid ?? '0', orderBy: menuOrderBy});
  });

  return [{control, isLoading}, onSubmit] as const;
}
