import { KEYS } from './constants';
export function getFocusableItemsDefaultImpl(items) {
  return items.filter(({
    isDisabled
  }) => !isDisabled);
}
export function getItemsMap(items) {
  const entries = items.map(n => [n.id, n]);
  return new Map(entries);
}
export function setItemState(id, patch, items) {
  return items.map(item => item.id === id ? {
    ...item,
    ...patch
  } : item);
}
export function setAllItemsState(patch, items) {
  return items.map(item => ({
    ...item,
    ...patch
  }));
}
export function getKeyActionFn(key) {
  if (key === KEYS.DOWN) {
    return moveFocusToNextItem;
  }
  if (key === KEYS.UP) {
    return moveFocusToPrevItem;
  }
  if (key === KEYS.HOME) {
    return moveFocusToFirstItem;
  }
  if (key === KEYS.END) {
    return moveFocusToLastItem;
  }
  if (key === KEYS.ENTER || key === KEYS.SPACE) {
    return toggleSelect;
  }
  return null;
}

// action functions start
export function moveFocusToNextItem({
  item,
  context
}) {
  const targetItem = getNextItem(item, context.items);
  if (!targetItem) {
    return;
  }
  const targetElement = context.refs.current.get(targetItem.id);
  context.setItems(items => {
    const allUnfocused = setAllItemsState({
      isFocused: false
    }, items);
    return setItemState(targetItem.id, {
      isFocused: true
    }, allUnfocused);
  });
  targetElement?.focus();
}
export function moveFocusToPrevItem({
  item,
  context
}) {
  const targetItem = getPrevItem(item, context.items);
  if (!targetItem) {
    return;
  }
  const targetElement = context.refs.current.get(targetItem.id);
  context.setItems(items => {
    const allUnfocused = setAllItemsState({
      isFocused: false
    }, items);
    return setItemState(targetItem.id, {
      isFocused: true
    }, allUnfocused);
  });
  targetElement?.focus();
}
export function moveFocusToFirstItem({
  context
}) {
  const targetItem = context.items[0];
  const targetElement = context.refs.current.get(targetItem.id);
  context.setItems(items => {
    const allUnfocused = setAllItemsState({
      isFocused: false
    }, items);
    return setItemState(targetItem.id, {
      isFocused: true
    }, allUnfocused);
  });
  targetElement?.focus();
}
export function moveFocusToLastItem({
  context
}) {
  const targetItem = context.items[context.items.length - 1];
  const targetElement = context.refs.current.get(targetItem.id);
  context.setItems(items => {
    const allUnfocused = setAllItemsState({
      isFocused: false
    }, items);
    return setItemState(targetItem.id, {
      isFocused: true
    }, allUnfocused);
  });
  targetElement?.focus();
}
export function toggleSelect({
  onToggleSelected,
  isSelected
}) {
  onToggleSelected(!isSelected);
}

// action functions end
export function getNextItem(item, items) {
  const index = items.indexOf(item);
  return items.find((n, i) => i > index) ?? null;
}
export function getPrevItem(item, items) {
  const index = items.indexOf(item);
  return items[index - 1] ?? null;
}
export function getDummyItem(id) {
  return {
    id,
    isDisabled: true,
    isFocused: false,
    isSelected: false
  };
}
export function getElementId(listId, id) {
  return `list-${listId}-item-${id}`;
}