import { usePermission } from '../permission';
import { type Station } from '@/apis';
import { PERMISSION_TYPE_LITERALS, type PermissionType } from '@/enums';
import { objectEntries } from '@vueuse/core';
import type { CheckboxProps } from 'naive-ui';
import { computed, ref, watch, type Ref } from 'vue';

type BatchActionKey = 'export-icmp' | 'export-record' | 'sync-camera' | 'sync-nvr';

type BatchAction = {
  label: string;
  key: BatchActionKey;
  permission: PermissionType;
  active: boolean;
};

export const useBatchActions = (stations: Ref<Station[]>, abortController?: Ref<AbortController | undefined>) => {
  const { hasPermission } = usePermission();

  const batchActions = ref<BatchAction[]>([
    {
      label: '导出设备状态',
      key: 'export-icmp',
      permission: PERMISSION_TYPE_LITERALS.VIEW,
      active: false,
    },
    {
      label: '导出录像诊断',
      key: 'export-record',
      permission: PERMISSION_TYPE_LITERALS.VIEW,
      active: false,
    },
    {
      label: '同步摄像机',
      key: 'sync-camera',
      permission: PERMISSION_TYPE_LITERALS.OPERATION,
      active: false,
    },
    {
      label: '同步录像机通道',
      key: 'sync-nvr',
      permission: PERMISSION_TYPE_LITERALS.OPERATION,
      active: false,
    },
  ]);

  const selectedAction = computed(() => {
    return batchActions.value.find((action) => action.active);
  });

  const selectableStations = computed(() => {
    if (!selectedAction.value) return [];
    const result: Station[] = [];
    if (selectedAction.value.permission === PERMISSION_TYPE_LITERALS.VIEW) {
      result.push(...stations.value.filter((station) => hasPermission(station.code, PERMISSION_TYPE_LITERALS.VIEW)));
    }
    if (selectedAction.value.permission === PERMISSION_TYPE_LITERALS.OPERATION) {
      result.push(...stations.value.filter((station) => hasPermission(station.code, PERMISSION_TYPE_LITERALS.OPERATION)));
    }
    return result;
  });

  const stationSelection = ref<Record<Station['code'], boolean>>({});

  const selectionProps = computed<CheckboxProps>(() => {
    const selectableStationsLength = selectableStations.value.length;
    const selectedStationsLength = objectEntries(stationSelection.value).filter(([, selected]) => selected).length;

    const disabled = selectableStationsLength === 0;
    const checked = selectableStationsLength > 0 && selectedStationsLength === selectableStationsLength;
    const indeterminate = selectableStationsLength > 0 && selectedStationsLength > 0 && selectedStationsLength < selectableStationsLength;

    return {
      disabled,
      checked,
      indeterminate,
    };
  });

  const toggleSelectAction = (action: BatchAction) => {
    batchActions.value.forEach((batchAction) => {
      if (batchAction.key === action.key) {
        if (batchAction.active) stationSelection.value = {};
        batchAction.active = !batchAction.active;
      } else {
        batchAction.active = false;
      }
    });
  };

  const toggleSelectAllStations = (checked: boolean) => {
    if (!checked) {
      stationSelection.value = {};
      return;
    }
    selectableStations.value.forEach((station) => {
      stationSelection.value[station.code] = checked;
    });
  };

  watch(selectedAction, () => {
    toggleSelectAllStations(false);
  });

  const confirmAction = (callbacks: Record<BatchActionKey, () => void>) => {
    const { key } = selectedAction.value ?? {};
    if (!key) return;
    const noStationSeleted = !Object.values(stationSelection.value).some((selected) => selected);
    if (noStationSeleted) {
      window.$message.warning('请选择车站');
      return;
    }
    callbacks[key]();
  };

  const cancelAction = () => {
    abortController?.value?.abort();
    stationSelection.value = {};
    batchActions.value.forEach((batchAction) => {
      batchAction.active = false;
    });
  };

  return {
    batchActions,
    selectedAction,

    selectableStations,
    stationSelection,

    selectionProps,

    toggleSelectAction,
    toggleSelectAllStations,

    confirmAction,
    cancelAction,
  };
};
