import { useEffect } from 'react';
// eslint-disable-next-line no-unused-vars
type Callback = (entry: IntersectionObserverEntry) => void;

class IntersectionObserverManager {
  private observer: IntersectionObserver;
  private callbacks: Map<Element, Callback>;

  // eslint-disable-next-line no-undef
  constructor(options: IntersectionObserverInit) {
    this.callbacks = new Map();

    this.observer = new IntersectionObserver(this.handleIntersect.bind(this), options);
  }

  private handleIntersect(entries: IntersectionObserverEntry[]) {
    entries.forEach((entry) => {
      const callback = this.callbacks.get(entry.target);
      if (callback) {
        callback(entry);
      }
    });
  }

  observe(element: Element, callback: Callback) {
    if (element && callback) {
      this.callbacks.set(element, callback);
      this.observer.observe(element);
    }
  }

  unobserve(element: Element) {
    if (element) {
      this.callbacks.delete(element);
      this.observer.unobserve(element);
    }
  }

  disconnect() {
    this.observer.disconnect();
    this.callbacks.clear();
  }
}

let manager: IntersectionObserverManager | null = null;

// eslint-disable-next-line no-undef
const getObserverManager = (options: IntersectionObserverInit) => {
  if (!manager) {
    manager = new IntersectionObserverManager(options);
  }
  return manager;
};

export const useSharedIntersectionObserver = (
  // eslint-disable-next-line no-undef
  options: IntersectionObserverInit,
) => {
  useEffect(() => {
    return () => {
      // Cleanup logic if needed
      // For example, disconnect the observer when the component unmounts entirely
      // This depends on your application's lifecycle
    };
  }, []);

  if (typeof window === 'undefined') {
    // Return a dummy manager for SSR
    return {
      observe: () => {},
      unobserve: () => {},
      disconnect: () => {},
    } as unknown as IntersectionObserverManager;
  }

  return getObserverManager(options);
};
