import { useEffect, useSyncExternalStore } from 'react';
import { api } from '@/api/client';
import type { ProviderSnapshotEntry } from '@/api/types';

let cached: ProviderSnapshotEntry[] | null = null;
let inflight: Promise<ProviderSnapshotEntry[]> | null = null;
const listeners = new Set<() => void>();

function notify(): void {
  for (const fn of listeners) fn();
}

function subscribe(fn: () => void): () => void {
  listeners.add(fn);
  return () => listeners.delete(fn);
}

function getSnapshot(): ProviderSnapshotEntry[] | null {
  return cached;
}

async function doFetch(cwd?: string): Promise<ProviderSnapshotEntry[]> {
  const data = await api.coder.snapshot(cwd);
  cached = data;
  inflight = null;
  notify();
  return data;
}

function ensureLoaded(cwd?: string): void {
  if (cached || inflight) return;
  inflight = doFetch(cwd).catch((err) => {
    inflight = null;
    console.error('provider snapshot fetch failed:', err);
    return [];
  });
}

export function refreshProviderSnapshot(cwd?: string): Promise<ProviderSnapshotEntry[]> {
  cached = null;
  inflight = null;
  return doFetch(cwd);
}

export function useProviderSnapshot(cwd?: string): ProviderSnapshotEntry[] | null {
  const entries = useSyncExternalStore(subscribe, getSnapshot);
  useEffect(() => { ensureLoaded(cwd); }, [cwd]);
  return entries;
}
