import { initStationAlarms, pageDeviceAlarmLogApi, type Station } from '@/apis';
import { LINE_ALARMS_QUERY_KEY, STATION_ALARMS_MUTATION_KEY } from '@/constants';
import { tryGetDeviceType } from '@/enums';
import { useAlarmStore, usePermissionStore } from '@/stores';
import { parseErrorFeedback } from '@/utils';
import { CancelledError, useMutation, useQuery } from '@tanstack/vue-query';
import { isCancel } from 'axios';
import dayjs from 'dayjs';
import { computed } from 'vue';

export const useStationAlarmsMutation = () => {
  const alarmStore = useAlarmStore();

  return useMutation({
    mutationKey: [STATION_ALARMS_MUTATION_KEY],
    mutationFn: async (params: { station: Station; signal?: AbortSignal }) => {
      const { station, signal } = params;
      const stationAlarms = initStationAlarms();
      if (!station.online) {
        return stationAlarms;
      }
      const now = dayjs();
      const todayStart = now.startOf('date').valueOf();
      const todayEnd = now.endOf('date').valueOf();
      const { records } = await pageDeviceAlarmLogApi(
        {
          model: {
            stationCode: station.code,
          },
          extra: {
            alarmDate_ge: todayStart,
            alarmDate_le: todayEnd,
          },
          size: 50000,
          current: 1,
          sort: 'alarmDate',
          order: 'descending',
        },
        {
          stationCode: station.code,
          signal,
        },
      );
      for (const alarm of records) {
        const { deviceType: deviceTypeCode } = alarm;
        const deviceType = tryGetDeviceType(deviceTypeCode);
        if (!!deviceType) {
          stationAlarms[deviceType].unshift(alarm);
        }
      }
      stationAlarms['unclassified'] = records;
      return stationAlarms;
    },
    onSuccess: (stationAlarms, { station }) => {
      alarmStore.setStationAlarms(station.code, stationAlarms);
    },
    onError: (error) => {
      if (isCancel(error) || error instanceof CancelledError) return;
      console.error(error);
      const errorFeedback = parseErrorFeedback(error);
      window.$message.error(errorFeedback);
    },
  });
};

/**
 * 由 `useLineStationsQuery` 显式触发
 * @see [use-line-stations-query.ts](./use-line-stations-query.ts)
 */
export const useLineAlarmsQuery = () => {
  const permissionStore = usePermissionStore();
  const stations = computed(() => permissionStore.stations.VIEW ?? []);

  const { mutateAsync: getStationAlarms } = useStationAlarmsMutation();

  return useQuery({
    queryKey: computed(() => [LINE_ALARMS_QUERY_KEY]),
    enabled: false,
    queryFn: async ({ signal }) => {
      const startTime = performance.now();
      for (const station of stations.value) {
        await getStationAlarms({ station, signal }).catch(() => {});
      }
      const endTime = performance.now();
      console.log(`${LINE_ALARMS_QUERY_KEY}: ${endTime - startTime} ms`);

      return null;
    },
  });
};
