/* ============================================================
   CAMPAIGN LIBRARY BRIDGE — make a campaign's CLOUD assets
   (the Items / NPCs / Enemies / Bosses / Maps uploaded to
   Supabase + Cloudflare) usable IN-GAME, alongside the
   device-local setup library.

   The two prep systems used to be separate: the moderator
   console reads the device-local `setupStore` (compressed
   data-URLs), while the campaign tabs uploaded to the cloud and
   those never appeared in play. This bridge surfaces the cloud
   assets in the console's Reveal & Hand Out, enemy spawns, and
   maps — so what you upload to a campaign actually shows up when
   you run it.

   Cloud asset rows have no name column, so nicknames are kept
   CLIENT-SIDE per campaign (localStorage). Pushing a cloud asset
   to the Main puts only its URL into synced state (small + safe).
   ============================================================ */
const { useState: useS_cl, useEffect: useE_cl } = React;

/* ---------- client-side nicknames (assets table has no name) ---------- */
function assetNameKey(gameId){ return 'torchlit-asset-names-' + gameId; }
function assetNames(gameId){
  try{ return JSON.parse(localStorage.getItem(assetNameKey(gameId)) || '{}'); }catch(_){ return {}; }
}
function setAssetName(gameId, id, name){
  const m = assetNames(gameId);
  if(name && name.trim()) m[id] = name.trim(); else delete m[id];
  try{ localStorage.setItem(assetNameKey(gameId), JSON.stringify(m)); }catch(_){}
  try{ window.dispatchEvent(new CustomEvent('asset-name-change', { detail:{ gameId } })); }catch(_){}
}
window.assetNames = assetNames;
window.setAssetName = setAssetName;

/* ---------- best display/usage URL ----------
   Cloudflare Images variants must be configured; the 'public' variant always
   exists, but a 'thumbnail' variant may not (it 404s — that's the broken
   thumbnails in the campaign grid). Prefer the /public image; for video, use
   the poster thumbnail. */
function assetSrc(a){
  if(!a) return '';
  if(a.kind === 'video') return a.thumbnail_url || a.playback_url || '';
  return a.playback_url || a.thumbnail_url || '';
}
window.assetSrc = assetSrc;

/* map a cloud asset row -> a moderator "library entry" {id,kind,name,src,desc} */
const CAT_TO_KIND = { npc:'npc', enemy:'enemy', boss:'boss', knowledge:'knowledge' };
function cloudEntry(a, gameId){
  const nm = (assetNames(gameId)||{})[a.id];
  return { id:a.id, kind: CAT_TO_KIND[a.category] || a.category,
           name: nm || '', src: assetSrc(a), desc:'', cloud:true, video: a.kind==='video' };
}
window.cloudEntry = cloudEntry;

/* ---------- hook: a campaign's READY cloud assets, live ----------
   Returns { loading, list, byCat:{npc,enemy,boss,map,item} }. Re-renders on a
   nickname change too, so freshly-named assets show their name immediately. */
function useCampaignAssets(gameId){
  const [assets, setAssets] = useS_cl(null);
  const [, setBump] = useS_cl(0);
  useE_cl(()=>{
    if(!gameId || !window.Assets){ setAssets([]); return; }
    let alive = true, ch = null;
    const load = ()=> Assets.listForGame(gameId)
      .then(rows=>{ if(alive) setAssets((rows||[]).filter(r=> r.status==='ready')); })
      .catch(()=>{ if(alive) setAssets([]); });
    load();
    try{ if(window.watchGameAssets) ch = watchGameAssets(gameId, load); }catch(_){}
    const onName = (e)=>{ if(!e || !e.detail || e.detail.gameId===gameId) setBump(b=>b+1); };
    window.addEventListener('asset-name-change', onName);
    return ()=>{ alive=false; window.removeEventListener('asset-name-change', onName);
      try{ if(ch && window.sb) sb.removeChannel(ch); }catch(_){} };
  }, [gameId]);
  const byCat = { npc:[], enemy:[], boss:[], map:[], item:[] };
  (assets||[]).forEach(a=>{ if(byCat[a.category]) byCat[a.category].push(a); });
  return { loading: assets===null, list: assets||[], byCat };
}
window.useCampaignAssets = useCampaignAssets;

/* convenience for the console: the current campaign's cloud entries for a kind
   (npc|enemy|boss), already mapped to library-entry shape. */
function useCloudLibrary(game){
  const gameId = game && game.campaign && game.campaign.id;
  const { byCat } = useCampaignAssets(gameId);
  return {
    gameId,
    npc:   (byCat.npc||[]).map(a=> cloudEntry(a, gameId)),
    enemy: (byCat.enemy||[]).map(a=> cloudEntry(a, gameId)),
    boss:  (byCat.boss||[]).map(a=> cloudEntry(a, gameId)),
    map:   byCat.map||[],
    item:  byCat.item||[],
  };
}
window.useCloudLibrary = useCloudLibrary;
