import { computed, inject, provide, ref, type Ref } from "vue";
import type { ChatMessage } from "../model/Message";
import { ArrayUtils, assertNotNull, requireNotNull } from "@imengyu/imengyu-utils";

export function useChatSelection() {
  const selectedMessageIds = ref<number[]>([]);
  const isSelectMode = ref(false);
  const selectedCount = computed(() => selectedMessageIds.value.length);

  provide('selectedMessageIds', selectedMessageIds);
  provide('isSelectMode', isSelectMode);

  function intoSelectMode(sourceIds: number[]) {
    isSelectMode.value = true;
    selectedMessageIds.value = sourceIds;
  }
  function exitSelectMode() {
    isSelectMode.value = false;
    selectedMessageIds.value = [];
  }

  return {
    intoSelectMode,
    exitSelectMode,
    isSelectMode,
    selectedCount,
  }
}

export function useChatSelectionChild(message?: Ref<ChatMessage>) {
  const selectedMessageIds = requireNotNull(inject<Ref<number[]>>('selectedMessageIds', ref([])));
  const isSelectMode = requireNotNull(inject<Ref<boolean>>('isSelectMode', ref(false)));

  const isThisItemSelected = computed(() => {
    if (!message)
      return false;
    return selectedMessageIds.value?.includes(message.value.id);
  });

  const isAnyItemSelected = computed(() => {
    return selectedMessageIds.value.length > 0;
  });

  function setSelected(value: boolean) {
    assertNotNull(message?.value, 'message is not set');
    assertNotNull(selectedMessageIds.value, 'selectedMessageIds is not set');
    if (value) {
      selectedMessageIds.value.push(message.value.id);
    } else {
      ArrayUtils.remove(selectedMessageIds.value, message.value.id);
    }
  }

  return {
    selectedMessageIds,
    isSelectMode,
    isAnyItemSelected,
    isThisItemSelected,
    setSelected,
  }
}