import {addStorage, editStorage, getStorageInfo} from '@apis';
import {yupResolver} from '@hookform/resolvers/yup';
import {AddStorageParams} 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 {number, object, string} from 'yup';

type FormState = {
  /** 库位编号 */
  storageLocationCode: string
  /** 库位名称 */
  storageLocationName: string
  /** 库位类型 */
  storageLocationType: string
  /** 是否禁用 */
  storageIsNotDisable: string
  /** 所在仓库 */
  storageWarehouseWhere: string
  /** 库位容量 */
  storageCapacity: number
};

const validate = object({
  storageLocationCode: string().required('请输入库位编号'),
  storageLocationName: string().required('请输入库位名称'),
  storageLocationType: string().required('请输入库位类型'),
  storageWarehouseWhere: string().required('请输入所在仓库'),
  storageIsNotDisable: string().required('请选择状态'),
  storageCapacity: number().typeError('请输入数字类型').min(0, '库位容量必须大于0')
    .required('请输入库位容量'),
});

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

  return [isLoading, mutate] as const;
}

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

  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: {
      storageLocationCode: '',
      storageLocationName: '',
      storageLocationType: '',
      storageWarehouseWhere: '',
      storageIsNotDisable: '1',
      storageCapacity: 0,
    },
    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({
    storageLocationName,
    storageLocationCode,
    storageLocationType,
    storageIsNotDisable,
    storageWarehouseWhere,
    storageCapacity,
  }) {
    const params: AddStorageParams = {
      storageLocationName,
      storageLocationCode,
      storageLocationType,
      isNotDisable: storageIsNotDisable,
      warehouseWhere: storageWarehouseWhere,
      storageLocationCapacity: storageCapacity,
    };

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

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

export function useFormInstance() {
  const {control} = useFormContext<FormState>();

  return control;
}

export function useFormInfoValue(id: string) {
  const {setValue} = useFormContext<FormState>();

  const {data} = useQuery(
    [getStorageInfo.name, id],
    async function() {
      const data = await getStorageInfo(id);

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

        throw new Error('未获取到库位信息');
      }

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

  useEffect(function() {
    setValue('storageLocationCode', data?.storageLocationCode ?? '');
    setValue('storageLocationName', data?.storageLocationName ?? '');
    setValue('storageLocationType', data?.storageLocationType ?? '');
    setValue('storageIsNotDisable', data?.isNotDisable ?? '1');
    setValue('storageWarehouseWhere', data?.warehouseWhere ?? '');
    setValue('storageCapacity', Number(data?.storageLocationCapacity ?? 0));
  }, [data, setValue]);
}
