import { useCallback } from 'react';

export type PointerEventLike = MouseEvent | PointerEvent;

export const isPointerModifierEvent = (event?: PointerEventLike | null): boolean =>
  Boolean(event && (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey));

export const isPrimaryPointerEvent = (event?: PointerEventLike | null): boolean => {
  if (!event) {
    return true;
  }
  if (typeof event.button === 'number' && event.button !== 0) {
    return false;
  }
  const type = event?.type?.toLowerCase?.() ?? '';
  return type === 'click' || type === 'pointerdown' || type === 'pointerup';
};

export type EntryType = 'document' | 'folder';

export interface WorkspaceEntry {
  id: string | number;
  key?: string;
  type: EntryType;
  [key: string]: unknown;
}

interface UseEntryPointerOptions {
  resolveDocumentRowKey?: (id: string | number) => string | null | undefined;
  resolveFolderRowKey?: (id: string | number) => string | null | undefined;
  onSelectEntry?: (entry: WorkspaceEntry, event?: PointerEventLike | null, metadata?: EntryPointerMetadata) => void;
  onInspectDocument?: (id: string | number, metadata?: EntryPointerMetadata) => void;
}

export interface EntryPointerMetadata {
  modifierClick: boolean;
  primaryClick: boolean;
  rowKey: string;
  type: EntryType;
  id: string | number;
}

export const useEntryPointer = ({
  resolveDocumentRowKey,
  resolveFolderRowKey,
  onSelectEntry,
  onInspectDocument,
}: UseEntryPointerOptions) =>
  useCallback(
    (entry?: WorkspaceEntry | null, event?: PointerEventLike | null) => {
      if (!entry || !entry.id) {
        return;
      }

      const { type, id } = entry;
      if (type !== 'document' && type !== 'folder') {
        return;
      }

      const rowKey = entry.key
        || (type === 'document' ? resolveDocumentRowKey?.(id) : resolveFolderRowKey?.(id));
      if (!rowKey) {
        return;
      }

      const modifierClick = isPointerModifierEvent(event);
      const primaryClick = isPrimaryPointerEvent(event);
      const metadata: EntryPointerMetadata = { modifierClick, primaryClick, rowKey, type, id };

      onSelectEntry?.(entry, event, metadata);

      if (type === 'document' && !modifierClick && primaryClick) {
        onInspectDocument?.(id, metadata);
      }
    },
    [resolveDocumentRowKey, resolveFolderRowKey, onSelectEntry, onInspectDocument],
  );

export default useEntryPointer;
