import { useEffect } from 'react';
import type { Campaign } from '@/lib/schemas';
import { useDebouncedCallback } from '@/lib/useDebouncedCallback';
import { useSessionStore } from '@/stores/sessionStore';
import { useUiStore } from '@/stores/uiStore';
import { buildSnapshot } from '@/lib/sync/snapshot';
import type { Snapshot } from '@/lib/sync/messages';
import { pushSnapshot, pushImage } from '@/lib/sync/wsSync';
import { useCharacters } from '@/features/characters/hooks';
import { useEncounters } from '@/features/combat/hooks';
import { useMaps, useCalendar, useQuests } from '@/features/world/hooks';

/**
 * While the GM is hosting, mirror local state to the room: a debounced
 * player-safe snapshot on any change, plus the active map image (sent once per id).
 * Inert unless role === 'gm'. Mounted once in the app shell.
 */
export function useSessionBroadcaster(campaign: Campaign | null): void {
  const role = useSessionStore((s) => s.role);
  const status = useSessionStore((s) => s.status);
  const cid = campaign?.id ?? '';
  const characters = useCharacters(cid);
  const encounters = useEncounters(cid);
  const maps = useMaps(cid);
  const calendar = useCalendar(cid);
  const quests = useQuests(cid);
  const activeEncounterId = useUiStore((s) => s.activeEncounterId);
  const activeMapId = useUiStore((s) => s.activeMapId);
  const activeHandout = useUiStore((s) => s.activeHandout);

  const debouncedPush = useDebouncedCallback((s: Snapshot) => pushSnapshot(s), 250);

  useEffect(() => {
    if (role !== 'gm' || status !== 'connected' || !campaign) return;
    const { snapshot, images } = buildSnapshot({ campaign, characters, encounters, maps, calendar: calendar ?? null, activeEncounterId, activeMapId, handout: activeHandout, quests });
    debouncedPush(snapshot);
    for (const [id, dataUrl] of Object.entries(images)) pushImage(id, dataUrl);
  }, [role, status, campaign, characters, encounters, maps, calendar, activeEncounterId, activeMapId, activeHandout, quests, debouncedPush]);
}
