/* ============================================================
   SETUP LIBRARY — the moderator's pre-game prep.
   Holds uploaded NPC / Enemy / Boss portraits and Knowledge
   handouts (image + description). This library lives ONLY on the
   moderator's device (a separate localStorage key) and is NOT synced
   over the network — keeping the live game state small. When the
   moderator PUSHES an entry, only that single entry travels to the
   Main screen or a player (via the synced game state).

   A whole setup can be saved to a .json file (images embedded) and
   loaded back later to continue or start a fresh game with the same prep.
   ============================================================ */

// downscale + compress an uploaded image to a compact data URL.
// Aggressive by default so pushed entries stay small enough to sync.
function compressImage(file, maxDim=900, quality=0.62){
  return new Promise((resolve)=>{
    const url = URL.createObjectURL(file);
    const img = new Image();
    img.onload = ()=>{
      let { width, height } = img;
      const scale = Math.min(1, maxDim/Math.max(width, height));
      const w = Math.max(1, Math.round(width*scale)), h = Math.max(1, Math.round(height*scale));
      const c = document.createElement('canvas'); c.width=w; c.height=h;
      const ctx = c.getContext('2d');
      ctx.drawImage(img, 0, 0, w, h);
      URL.revokeObjectURL(url);
      try{ resolve(c.toDataURL('image/jpeg', quality)); }catch(_){ resolve(null); }
    };
    img.onerror = ()=>{ URL.revokeObjectURL(url); resolve(null); };
    img.src = url;
  });
}
window.compressImage = compressImage;

const KIND_META = {
  npc:       { label:'NPC',       plural:'NPCs',       sub:'Portrait — appears on the LEFT of the Main screen',  hasDesc:false },
  boss:      { label:'Boss',      plural:'Bosses',     sub:'Portrait — appears in the MIDDLE of the Main screen', hasDesc:true },
  enemy:     { label:'Enemy',     plural:'Enemies',    sub:'Portrait + lore — reveal as a codex card',            hasDesc:true },
  knowledge: { label:'Knowledge', plural:'Knowledge',  sub:'Image and/or description — a clue, letter or relic',  hasDesc:true },
};
const KIND_ORDER = ['npc','enemy','boss','knowledge'];
window.KIND_META = KIND_META;
window.KIND_ORDER = KIND_ORDER;

const SETUP_KEY = 'torchlit-setup-v1';

class SetupStore {
  constructor(){
    this.listeners = new Set();
    this.lib = this._load();
  }
  _load(){
    try{ const s = localStorage.getItem(SETUP_KEY); if(s){ const o=JSON.parse(s); return this._normalize(o); } }catch(_){}
    return { name:'', npc:[], enemy:[], boss:[], knowledge:[] };
  }
  _normalize(o){
    o = o || {};
    return { name:o.name||'', npc:o.npc||[], enemy:o.enemy||[], boss:o.boss||[], knowledge:o.knowledge||[] };
  }
  _persist(){ try{ localStorage.setItem(SETUP_KEY, JSON.stringify(this.lib)); }catch(e){ /* quota */ } }
  _notify(){ this.listeners.forEach(l=>l(this.lib)); }
  subscribe(fn){ this.listeners.add(fn); return ()=>this.listeners.delete(fn); }
  get(){ return this.lib; }
  set(next){ this.lib = this._normalize(next); this._persist(); this._notify(); }
  add(kind, entry){
    const id = 'k'+Date.now().toString(36)+Math.floor(Math.random()*900+100).toString(36);
    const e = { id, kind, name:entry.name||KIND_META[kind].label, src:entry.src||'', desc:entry.desc||'',
                intel: entry.intel!==undefined ? entry.intel : true,   // show description when revealed
                sound: entry.sound||'', soundName: entry.soundName||'' };
    this.set({ ...this.lib, [kind]: [...this.lib[kind], e] });
    return id;
  }
  update(kind, id, patch){
    this.set({ ...this.lib, [kind]: this.lib[kind].map(e=> e.id===id ? {...e, ...patch} : e) });
  }
  remove(kind, id){
    this.set({ ...this.lib, [kind]: this.lib[kind].filter(e=> e.id!==id) });
  }
  setName(name){ this.set({ ...this.lib, name }); }
  clear(){ this.set({ name:'', npc:[], enemy:[], boss:[], knowledge:[] }); }
  count(){ return KIND_ORDER.reduce((n,k)=> n + (this.lib[k]?this.lib[k].length:0), 0); }
}
const setupStore = (window.__torchlit_setup ||= new SetupStore());
window.setupStore = setupStore;

function useSetup(){
  const [lib, setLib] = useState(setupStore.get());
  useEffect(()=> setupStore.subscribe(()=> setLib({...setupStore.get()})), []);
  return lib;
}
window.useSetup = useSetup;

/* ---------- save / load to a .json file ---------- */
function downloadSetup(){
  const lib = setupStore.get();
  const data = JSON.stringify(lib, null, 0);
  const blob = new Blob([data], {type:'application/json'});
  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  const safe = (lib.name||'torchlit-setup').replace(/[^a-z0-9-_]+/gi,'-').slice(0,40);
  a.download = safe + '.json';
  document.body.appendChild(a); a.click();
  setTimeout(()=>{ URL.revokeObjectURL(a.href); a.remove(); }, 1000);
}
function loadSetupFile(file){
  return new Promise((resolve,reject)=>{
    const r = new FileReader();
    r.onload = ()=>{ try{ const o = JSON.parse(r.result); setupStore.set(o); resolve(o); }catch(e){ reject(e); } };
    r.onerror = reject;
    r.readAsText(file);
  });
}
window.downloadSetup = downloadSetup;
window.loadSetupFile = loadSetupFile;
