import { useContext } from 'react';
import { Key } from 'ts-key-enum';

import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { useRecordBoardCardNavigation } from '@/object-record/record-board/hooks/useRecordBoardCardNavigation';
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
import { BoardHotkeyScope } from '@/object-record/record-board/types/BoardHotkeyScope';
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
import { RecordIndexHotkeyScope } from '@/object-record/record-index/types/RecordIndexHotkeyScope';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { useRecoilCallback } from 'recoil';

const BOARD_NAVIGATION_CUSTOM_SCOPES = {
  goto: true,
  keyboardShortcutMenu: true,
  searchRecords: true,
};

export const RecordBoardHotkeyEffect = () => {
  const { recordBoardId } = useContext(RecordBoardContext);

  const { move } = useRecordBoardCardNavigation(recordBoardId);

  const { setHotkeyScopeAndMemorizePreviousScope } = usePreviousHotkeyScope();

  const recordIndexAllRecordIdsState = useRecoilComponentCallbackStateV2(
    recordIndexAllRecordIdsComponentSelector,
  );

  const { setRecordAsSelected } = useRecordBoardSelection(recordBoardId);

  const selectAll = useRecoilCallback(
    ({ snapshot }) =>
      () => {
        const allRecordIds = getSnapshotValue(
          snapshot,
          recordIndexAllRecordIdsState,
        );

        for (const recordId of allRecordIds) {
          setRecordAsSelected(recordId, true);
        }
      },
    [recordIndexAllRecordIdsState, setRecordAsSelected],
  );

  useScopedHotkeys(
    'ctrl+a,meta+a',
    selectAll,
    RecordIndexHotkeyScope.RecordIndex,
  );

  useScopedHotkeys('ctrl+a,meta+a', selectAll, BoardHotkeyScope.BoardFocus);

  useScopedHotkeys(
    Key.ArrowLeft,
    () => {
      setHotkeyScopeAndMemorizePreviousScope({
        scope: BoardHotkeyScope.BoardFocus,
        customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
      });
      move('left');
    },
    RecordIndexHotkeyScope.RecordIndex,
  );

  useScopedHotkeys(
    Key.ArrowRight,
    () => {
      setHotkeyScopeAndMemorizePreviousScope({
        scope: BoardHotkeyScope.BoardFocus,
        customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
      });
      move('right');
    },
    RecordIndexHotkeyScope.RecordIndex,
  );

  useScopedHotkeys(
    Key.ArrowUp,
    () => {
      setHotkeyScopeAndMemorizePreviousScope({
        scope: BoardHotkeyScope.BoardFocus,
        customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
      });
      move('up');
    },
    RecordIndexHotkeyScope.RecordIndex,
  );

  useScopedHotkeys(
    Key.ArrowDown,
    () => {
      setHotkeyScopeAndMemorizePreviousScope({
        scope: BoardHotkeyScope.BoardFocus,
        customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
      });
      move('down');
    },
    RecordIndexHotkeyScope.RecordIndex,
  );

  useScopedHotkeys(
    Key.ArrowLeft,
    () => {
      move('left');
    },
    BoardHotkeyScope.BoardFocus,
  );

  useScopedHotkeys(
    Key.ArrowRight,
    () => {
      move('right');
    },
    BoardHotkeyScope.BoardFocus,
  );

  useScopedHotkeys(
    Key.ArrowUp,
    () => {
      move('up');
    },
    BoardHotkeyScope.BoardFocus,
  );

  useScopedHotkeys(
    Key.ArrowDown,
    () => {
      move('down');
    },
    BoardHotkeyScope.BoardFocus,
  );

  return null;
};
