/* eslint-disable  @typescript-eslint/no-explicit-any */
import type { RefObject } from 'react'
import { useEffect, useRef } from 'react'

type EventMap = HTMLElementEventMap & WindowEventMap

type Target = RefObject<HTMLElement> | HTMLElement | Window

type Args<E extends keyof EventMap> = {
  callback: (e: EventMap[E]) => void,
  event: E,
  target?: Target,
}

/**
 * Хук для подписки и отписки на события
 * на html element и window
 */
export const useEventListener = <E extends keyof EventMap>({
  callback,
  event,
  target = window,
}: Args<E>) => {
  const callbackRef = useRef(callback)

  useEffect(() => {
    callbackRef.current = callback
  }, [callback])

  useEffect(() => {
    const windowOrElement: HTMLElement | Window | null = 'current' in target
      ? target.current
      : target

    // типизировать сложно без any из за того что
    // у window есть события которых нет у html element
    // и наоборот
    const listener = (e: any) => {
      callbackRef.current(e)
    }

    windowOrElement?.addEventListener(event, listener)
    return () => {
      windowOrElement?.removeEventListener(event, listener)
    }
  }, [event, target])
}
