/**
 * Tracks which video asset ids are currently visible in the chat
 * FlatList's viewport. The chat tile (`VideoRenderer`) gates its
 * `VideoPlayerPool.acquire` call on this so we only spawn / hold a
 * native player for videos the user can actually see — not the dozen
 * tiles the FlatList keeps mounted off-screen for recycling.
 *
 * `Messages` pushes the set on every `onViewableItemsChanged` callback;
 * the chat screen `clear()`s it on unmount (alongside the player pool).
 */
import {useSyncExternalStore} from 'react';

let visible: ReadonlySet<number> = new Set();
const listeners = new Set<() => void>();

const emit = (): void => {
  listeners.forEach(l => l());
};

export const VisibleVideoAssets = {
  /** Replace the visible set wholesale. */
  set(assetIds: ReadonlyArray<number>): void {
    // Cheap structural check — skip the listener fan-out if nothing
    // changed (the throttle upstream re-fires on the trailing edge
    // even when the set is stable).
    if (assetIds.length === visible.size) {
      let same = true;
      for (const id of assetIds) {
        if (!visible.has(id)) {
          same = false;
          break;
        }
      }
      if (same) return;
    }
    visible = new Set(assetIds);
    emit();
  },

  has(assetId: number): boolean {
    return visible.has(assetId);
  },

  subscribe(listener: () => void): () => void {
    listeners.add(listener);
    return () => {
      listeners.delete(listener);
    };
  },

  clear(): void {
    if (visible.size === 0) return;
    visible = new Set();
    emit();
  },
};

const subscribe = (l: () => void) => VisibleVideoAssets.subscribe(l);

export const useIsVisibleVideoAsset = (assetId: number): boolean =>
  useSyncExternalStore(subscribe, () => VisibleVideoAssets.has(assetId));
