import {addUser, editUser, getAllDepartment, getAllRoleList, getUserInfo} from '@apis';
import {yupResolver} from '@hookform/resolvers/yup';
import {AddUserParams} from '@models';
import {useMutation, useQuery} from '@tanstack/react-query';
import {message} from 'antd';
import {useEffect} from 'react';
import {useForm, useFormContext} from 'react-hook-form';
import {object, string} from 'yup';

export type FormState = {
  userName: string;
  userPassword: string;
  userRealName: string;
  userEmail: string;
  userLandline: string;
  userPhone: string;
  userDepartment: string;
  userRole: string;
};

const validate = object({
  userName: string().required('请输入用户名'),
  userPassword: string().required('请输入用户密码'),
  userRealName: string().required('请输入真实姓名'),
  userDepartment: string().required('请选择部门'),
  userRole: string().required('请选择角色'),
});

function useAdd(onClose: () => void, onFetch: () => void) {
  const {isLoading, mutate} = useMutation(
    addUser,
    {
      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(
    editUser,
    {
      onSuccess(data) {
        if (data.msg === '200') {
          onClose();
          onFetch();
          message.success('修改成功');
        }
      },
    },
  );

  return [isLoading, mutate] as const;
}

export function useFormState(
  {onClose, onFetch, id, visible}:
  {onClose: () => void, onFetch: () => void, id: string, visible: boolean},
) {
  const formInstance = useForm<FormState>({
    defaultValues: {
      userName: '',
      userPassword: '',
      userRealName: '',
      userEmail: '',
      userLandline: '',
      userPhone: '',
      userDepartment: '',
      userRole: '',
    },
    resolver: yupResolver(validate),
  });
  const {handleSubmit, clearErrors} = formInstance;

  useEffect(function() {
    visible && clearErrors();
  }, [clearErrors, visible]);

  const [isAddLoading, addMutate] = useAdd(onClose, onFetch);
  const [isEditLoading, editMutate] = useEdit(onClose, onFetch);
  const isLoading = isAddLoading || isEditLoading;

  const onSubmit = handleSubmit(function({
    userName,
    userPassword,
    userRealName,
    userEmail,
    userLandline,
    userPhone,
    userDepartment,
    userRole,
  }) {
    const params: Omit<AddUserParams, 'password'> = {
      userName,
      realName: userRealName,
      email: userEmail,
      landline: userLandline,
      phone: userPhone,
      department: userDepartment,
      role: userRole,
    };

    id
      ? editMutate({...params, id: Number(id)})
      : addMutate({...params, password: userPassword});
  });

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

export function useOptions() {
  const {data: roleOptions} = useQuery(
    [getAllRoleList.name],
    async function() {
      const data = await getAllRoleList();

      if (data.msg === '200')
        return data.data.map(({id, roleName}) => ({value: String(id), label: roleName}));

      return [];
    }
    ,
    {initialData: [], retry: 3},
  );

  const {data: departmentOptions} = useQuery(
    [getAllDepartment.name],
    async function() {
      const data = await getAllDepartment();

      if (data.msg === '200')
        return data.data.map(
          ({id, departmentName}) => ({
            value: String(id), label: departmentName,
          }),
        );

      return [];
    }
    ,
    {initialData: [], retry: 3},
  );

  return {roleOptions, departmentOptions};
}

export function useField() {
  return useFormContext<FormState>();
}

export function useFetchUserInfo(id: string) {
  const {data} = useQuery(
    [id, getUserInfo.name],
    async function() {
      const data = await getUserInfo(id);

      if (data.msg === '200') {
        if (data.data.list[0])
          return data.data.list[0];

        throw new Error('未获取到用户信息');
      }

      throw new Error(data.errMsg);
    },
    {
      suspense: true,
      enabled: Boolean(id),
      cacheTime: 0,
    },
  );

  const {setValue} = useFormContext<FormState>();

  useEffect(function() {
    setValue('userName', data?.userName ?? '');
    setValue('userPassword', data?.password ?? '');
    setValue('userRealName', data?.realName ?? '');
    setValue('userEmail', data?.email ?? '');
    setValue('userLandline', data?.landline ?? '');
    setValue('userPhone', data?.phone ?? '');
    setValue('userRole', data?.roleId ?? '');
    setValue('userDepartment', data?.departmentId ?? '');
  }, [data, setValue]);
}
