import type { FlingGestureNativeProperties } from '../hooks/gestures/fling/FlingTypes';
import type { HoverGestureNativeProperties } from '../hooks/gestures/hover/HoverTypes';
import type { LongPressGestureNativeProperties } from '../hooks/gestures/longPress/LongPressTypes';
import type { NativeGestureNativeProperties } from '../hooks/gestures/native/NativeTypes';
import type { PanGestureNativeProperties } from '../hooks/gestures/pan/PanTypes';
import type { TapGestureNativeConfig } from '../hooks/gestures/tap/TapTypes';
import type { InternalConfigProps } from './ConfigTypes';

export type HandlersPropsWhiteList =
  | Set<keyof PanGestureNativeProperties>
  | Set<keyof FlingGestureNativeProperties>
  | Set<keyof HoverGestureNativeProperties>
  | Set<keyof LongPressGestureNativeProperties>
  | Set<keyof NativeGestureNativeProperties>
  | Set<keyof TapGestureNativeConfig>;

// Some handlers do not have specific properties (e.g. `Pinch`), therefore we mark those prop types as `Record<string, never>`.
// Doing intersection with those types results in type which cannot have any property. In order to fix that,
// we filter out properties with `never` values.
//
// This piece of magic works like this:
// 1. We iterate over all keys of T using `keyof T`
// 2. We check if the type of property is `never` using conditional types (`T[K] extends never ? never : K`).
//    If it is, we replace the key with `never`, i.e. we delete it. Otherwise we keep it as is.
export type FilterNeverProperties<T> = {
  [K in keyof T as T[K] extends never ? never : K]: T[K];
};

export type ExcludeInternalConfigProps<T> = Omit<
  T,
  keyof InternalConfigProps<unknown>
>;
