import { batchVerifyApi, type Station } from '@/apis';
import { LINE_STATIONS_MUTATION_KEY, LINE_STATIONS_QUERY_KEY } from '@/constants';
import { useSettingStore, useStationStore } from '@/stores';
import { getAppEnvConfig, parseErrorFeedback } from '@/utils';
import { CancelledError, useMutation, useQuery } from '@tanstack/vue-query';
import axios, { isCancel } from 'axios';
import dayjs from 'dayjs';
import { storeToRefs } from 'pinia';
import { computed } from 'vue';

export const useLineStationsMutation = () => {
  const stationStore = useStationStore();

  return useMutation({
    mutationKey: [LINE_STATIONS_MUTATION_KEY],
    mutationFn: async (params: { signal?: AbortSignal }) => {
      const { signal } = params;
      const { data: ndmStationList } = await axios.get<Omit<Station, 'online' | 'ip'>[]>(`/minio/ndm/ndm-stations.json?_t=${dayjs().unix()}`, { signal });
      const stations = ndmStationList.map<Station>((station) => ({
        code: station.code ?? '',
        name: station.name ?? '',
        online: false,
        ip: '',
        occ: station.occ,
      }));
      const verifyList = await batchVerifyApi({ signal });
      return stations.map((station) => ({
        ...station,
        online: !!verifyList.find((verify) => verify.stationCode === station.code)?.onlineState,
        ip: verifyList.find((verify) => verify.stationCode === station.code)?.ipAddress ?? '',
      }));
    },
    onSuccess: (stations) => {
      stationStore.setStations(stations);
    },
    onError: (error) => {
      if (isCancel(error) || error instanceof CancelledError) return;
      console.error(error);
      const errorFeedback = parseErrorFeedback(error);
      window.$message.error(errorFeedback);
    },
  });
};

export const useLineStationsQuery = () => {
  const settingStore = useSettingStore();
  const { pollingStations } = storeToRefs(settingStore);
  const { requestInterval } = getAppEnvConfig();
  const { mutateAsync: getLineStations } = useLineStationsMutation();

  return useQuery({
    queryKey: computed(() => [LINE_STATIONS_QUERY_KEY]),
    enabled: computed(() => pollingStations.value),
    refetchInterval: requestInterval * 1000,
    staleTime: (requestInterval * 1000) / 2,
    queryFn: async ({ signal }) => {
      const startTime = performance.now();
      await getLineStations({ signal }).catch(() => {});
      const endTime = performance.now();
      console.log(`${LINE_STATIONS_QUERY_KEY}: ${endTime - startTime} ms`);

      return null;
    },
  });
};
