import { queryClient } from '$lib/query/client';
import { qk } from '$lib/api/queries';
import { user } from '$lib/auth/store.svelte';

// Inbound server events over SSE (#968). The web client's OUTBOUND half
// (play events) lives in player/events.svelte.ts; this is the inbound
// listener it never had. Today it reacts to `playlist.system_rebuilt` — the
// daily 03:00 rebuild or a manual refresh — by invalidating the home +
// system-playlist query caches so a tab left open across the rebuild stops
// serving yesterday's snapshot (the stale-browse-view bug). Active playback
// self-heals separately on the failure path (store.handleLoadFailure); we
// deliberately do NOT yank a playing queue here — that would interrupt a
// mid-song listen to restart the new mix at track 0.

// Monotonic rebuild counter (#980). Bumped on every playlist.system_rebuilt.
// An open system-playlist DETAIL page can't be invalidated in place (its id
// rotates on rebuild — a refetch would 404), so instead it watches this
// counter and offers a "this mix was refreshed → Refresh" affordance that
// re-resolves the variant to the new playlist.
let _systemRebuildCount = $state(0);
export const systemRebuilt = {
  get count(): number {
    return _systemRebuildCount;
  }
};

function onSystemRebuilt(): void {
  _systemRebuildCount++;
  queryClient.invalidateQueries({ queryKey: qk.home() });
  // Prefix match invalidates every kind ('user' | 'system' | 'all').
  queryClient.invalidateQueries({ queryKey: ['playlists'] });
  queryClient.invalidateQueries({ queryKey: qk.systemPlaylistsStatus() });
}

// Wire once from +layout.svelte's mount. Opens the stream only while
// authenticated and closes it on logout; EventSource auto-reconnects on
// transient network drops.
export function useServerEvents(): void {
  $effect(() => {
    if (!user.value) return;
    // Absent under SSR / jsdom — the listener simply no-ops there.
    if (typeof EventSource === 'undefined') return;
    const es = new EventSource('/api/events/stream');
    es.addEventListener('playlist.system_rebuilt', onSystemRebuilt);
    return () => {
      es.removeEventListener('playlist.system_rebuilt', onSystemRebuilt);
      es.close();
    };
  });
}
