/* ============================================================
   Wildlife Kingdom — js/ui.js
   HUD · toolbar & palettes · side panel · selection cards ·
   toasts · modals. Original cream/rounded visual identity.
   ============================================================ */
(function(){
'use strict';
const WK = window.WK;
const D = WK.Data;

const $=id=>document.getElementById(id);
const UI = (WK.UI = {});

UI.game=null; UI.cam=null; UI.renderer=null;
UI.tool=null; UI.bulldoze=false;
UI._last={}; UI._selTarget=null; UI._sideTab='objectives';
UI._sideT=0; UI._hudT=0;

UI.init=function(game,cam,renderer){
  if(UI._inited){
    // re-attach to a fresh game without duplicating DOM work
    UI.game=game; UI.cam=cam; UI.renderer=renderer;
    game.ui=UI;
    UI._last={}; UI._selTarget=null;
    UI.cancelTool();
    UI.hideSelection();
    UI.renderSide();
    return;
  }
  UI._inited=true;
  UI.game=game; UI.cam=cam; UI.renderer=renderer;
  game.ui=UI;
  // inject resource icons
  document.querySelectorAll('.stat .ic[data-ic]').forEach(el=>{
    const s=WK.Sprites.getIcon('res:'+el.dataset.ic,26);
    s.cv.style.width='100%'; s.cv.style.height='100%';
    el.appendChild(s.cv);
  });
  $('btn-sound').textContent = WK.AudioSys.enabled?'🔊':'🔇';
  $('btn-settings').textContent='⚙';
  const spdIcons={ 'spd-pause':'⏸', 'spd-play':'▶', 'spd-fast':'⏩', 'spd-ultra':'⚡' };
  for(const id in spdIcons) $(id).textContent=spdIcons[id];
  $('btn-bulldoze').appendChild(WK.Sprites.getIcon('res:dozer',30).cv);
  UI.buildToolbar();
  UI.bind();
  UI.selectCat('paths'); // sensible default tab shown when opened
};

/* ---------------- toolbar ---------------- */
const CAT_ICON={ ground:'ground:grass', paths:'path:gravel', fences:'fence:wood',
                 nature:'nature:tree', animals:'animal:zebra', facilities:'facility:restroom' };
const FENCE_ITEMS=[['wood','Wood Fence'],['hedge','Hedge'],['gate','Keeper Gate']];

UI.buildToolbar=function(){
  const cats=$('tb-categories');
  cats.innerHTML='';
  for(const c of D.TOOLCATS){
    const b=document.createElement('button');
    b.className='tb-cat'+(c.id===UI._cat?' active':'');
    b.appendChild(WK.Sprites.getIcon(CAT_ICON[c.id],34).cv);
    const l=document.createElement('span'); l.className='lbl'; l.textContent=c.label;
    b.appendChild(l);
    b.onclick=()=>{ WK.AudioSys.sfx('click'); UI.selectCat(c.id); };
    b.dataset.cat=c.id;
    cats.appendChild(b);
  }
};

UI.paletteItems=function(cat){
  switch(cat){
    case 'ground': return Object.keys(D.GROUND).map(id=>({id,name:D.GROUND[id].name,cost:D.GROUND[id].cost,tier:D.GROUND[id].tier}));
    case 'paths': return Object.keys(D.PATH).map(id=>({id,name:D.PATH[id].name,cost:D.PATH[id].cost,tier:D.PATH[id].tier}));
    case 'fences': return FENCE_ITEMS.map(([id,name])=>({id,name,cost:id==='wood'?12:id==='hedge'?18:40,tier:id==='hedge'?2:1}));
    case 'nature': return Object.keys(D.NATURE).map(id=>({id,name:D.NATURE[id].name,cost:D.NATURE[id].cost,tier:D.NATURE[id].tier}));
    case 'animals': return Object.keys(D.SPECIES).sort((a,b)=>D.SPECIES[a].cost-D.SPECIES[b].cost)
      .map(id=>({id,name:D.SPECIES[id].name,cost:D.SPECIES[id].cost,tier:D.SPECIES[id].tier}));
    case 'facilities': return Object.keys(D.BUILDING).sort((a,b)=>D.BUILDING[a].cost-D.BUILDING[b].cost)
      .map(id=>({id,name:D.BUILDING[id].name,cost:D.BUILDING[id].cost,tier:D.BUILDING[id].tier}));
  }
  return [];
};
UI.iconKind=function(cat,id){
  switch(cat){
    case 'ground': return 'ground:'+id;
    case 'paths': return 'path:'+id;
    case 'fences': return 'fence:'+id;
    case 'nature': return 'nature:'+id;
    case 'animals': return 'animal:'+id;
    case 'facilities': return 'facility:'+id;
  }
};

UI.selectCat=function(cat){
  UI._cat=cat;
  document.querySelectorAll('.tb-cat').forEach(b=>b.classList.toggle('active',b.dataset.cat===cat));
  const pal=$('tb-palette');
  pal.innerHTML='';
  for(const it of UI.paletteItems(cat)){
    const locked=(it.tier||1)>UI.game.researchTier;
    const d=document.createElement('button');
    d.className='pal-item'+(locked?' locked':'')+((UI.tool&&UI.tool.item===it.id&&UI.tool.cat===cat)?' active':'');
    const cv=WK.Sprites.getIcon(UI.iconKind(cat,it.id),54);
    d.appendChild(cv.cv);
    const nm=document.createElement('span'); nm.className='nm'; nm.textContent=it.name;
    const pr=document.createElement('span'); pr.className='pr'; pr.textContent=locked?('Tier '+it.tier):WK.fmtMoney(it.cost);
    d.appendChild(nm); d.appendChild(pr);
    d.title=locked?'Unlock via Research':(D.BUILDING[it.id]&&D.BUILDING[it.id].desc||D.SPECIES[it.id]&&(D.SPECIES[it.id].minArea+'+ tiles · likes '+Object.keys(D.SPECIES[it.id].biome).join('/'))||'');
    d.onclick=()=>{
      WK.AudioSys.sfx('click');
      if(locked){ UI.toast('Locked! Unlock Tier '+it.tier+' in the Research panel.','bad'); return; }
      UI.bulldoze=false; $('btn-bulldoze').classList.remove('active');
      UI.selectTool({cat,item:it.id});
      pal.querySelectorAll('.pal-item').forEach(x=>x.classList.remove('active'));
      d.classList.add('active');
    };
    pal.appendChild(d);
  }
  pal.classList.add('hidden');
  if(UI.tool||UI.bulldoze) pal.classList.remove('hidden');
};
UI.selectTool=function(t){
  UI.tool=t; UI.bulldoze=false;
  $('btn-bulldoze').classList.toggle('active',false);
  const pal=$('tb-palette'), info=$('tool-info');
  if(t){
    pal.classList.remove('hidden');
    info.classList.remove('hidden');
    const def= t.cat==='animals'?D.SPECIES[t.item] : t.cat==='facilities'?D.BUILDING[t.item]
      : t.cat==='fences'?{name:t.item[0].toUpperCase()+t.item.slice(1)+' Fence'} : null;
    $('tool-name').textContent=def?def.name:t.item;
    const cost=def?(typeof def.cost==='number'?def.cost:null):null;
    $('tool-cost').textContent=cost!=null?WK.fmtMoney(cost)+(t.cat==='animals'?' · needs suitable habitat':''):'paint';
    document.querySelectorAll('#game').forEach(c=>c.classList.add('tooling'));
    document.querySelectorAll('.pal-item').forEach(x=>x.classList.toggle('active',x.querySelector('.nm') && x.querySelector('.nm').textContent===($('tool-name').textContent)));
    // re-mark active within current cat
    UI.selectCatRefreshActive();
  }else{
    pal.classList.add('hidden');
    info.classList.add('hidden');
    document.getElementById('game').classList.remove('tooling');
    document.querySelectorAll('.pal-item').forEach(x=>x.classList.remove('active'));
  }
};
UI.selectCatRefreshActive=function(){
  document.querySelectorAll('.pal-item').forEach(x=>x.classList.remove('active'));
};
UI.toggleBulldoze=function(){
  UI.bulldoze=!UI.bulldoze;
  if(UI.bulldoze){ UI.tool=null; $('tb-palette').classList.add('hidden'); $('tool-info').classList.add('hidden'); }
  $('btn-bulldoze').classList.toggle('active',UI.bulldoze);
  document.getElementById('game').classList.toggle('tooling',UI.bulldoze);
};
UI.cancelTool=function(){ UI.selectTool(null); UI.bulldoze=false; $('btn-bulldoze').classList.remove('active'); document.getElementById('game').classList.remove('tooling'); };

/* ---------------- HUD ---------------- */
UI.setSpeed=function(s){
  UI.game.speed=s;
  ['spd-pause','spd-play','spd-fast','spd-ultra'].forEach(id=>$(id).classList.remove('active'));
  $({'0':'spd-pause','1':'spd-play','2':'spd-fast','4':'spd-ultra'}[s]).classList.add('active');
};
UI.togglePause=function(){ UI.setSpeed(UI.game.speed===0?(UI._lastSpeed||1):(UI._lastSpeed=UI.game.speed,0)); };

UI.updateHUD=function(){
  const g=UI.game, L=UI._last;
  const set=(id,v)=>{ if(L[id]!==v){ L[id]=v; $(id).querySelector('b').textContent=v; } };
  set('st-money',WK.fmtMoney(g.money));
  set('st-guests',String(g.guests.length));
  const joy=g.guests.length?Math.round(g.guests.reduce((s,x)=>s+x.joy,0)/g.guests.length):null;
  set('st-joy',(joy!=null?joy+'%':'—'));
  set('st-research',Math.floor(g.rp)+' RP');
  set('st-stars',g.rating.toFixed(1)+'★');
  $('st-day').textContent='Day '+g.day;
  $('st-clock').textContent=WK.fmtClock(g.minutes);
  // side panel throttle
  UI._sideT++;
  if(UI._sideT>30){ UI._sideT=0; UI.renderSide(); }
  // selection follow
  UI.trackSelection();
};
UI.flashStat=function(id){
  const el=$(id==='money'?'st-money':id);
  el.classList.remove('flash'); void el.offsetWidth; el.classList.add('flash');
};

/* ---------------- side panel ---------------- */
UI.renderSide=function(){
  const g=UI.game;
  const c=$('sp-content');
  document.querySelectorAll('.sp-tab').forEach(b=>b.classList.toggle('active',b.dataset.tab===UI._sideTab));
  if(UI._sideTab==='objectives'){
    let h='';
    D.MISSIONS.forEach((m,i)=>{
      const done=i<g.missionIdx, cur=i===g.missionIdx;
      if(i>g.missionIdx&&!cur){}
      if(done||cur){
        const rw= typeof m.reward==='number'? WK.fmtMoney(m.reward)
          : (m.reward.cash?WK.fmtMoney(m.reward.cash):'')+(m.reward.rp?(' +'+m.reward.rp+' RP'):'');
        h+=`<div class="mission ${done?'done':''} ${cur?'current':''}">
          <div class="m-title"><span>${m.label}</span></div>
          ${m.hint&&!done?`<div class="m-hint">${m.hint}</div>`:''}
          ${!done?`<div class="m-reward">Reward: ${rw}</div>`:''}
        </div>`;
      }
    });
    if(g.missionIdx>=D.MISSIONS.length) h+='<div class="mission done"><div class="m-title"><span>All missions complete — Wildlife Legend! 🏆</span></div></div>';
    c.innerHTML=h;
  }else if(UI._sideTab==='research'){
    const next=g.researchCost();
    let h=`<div class="res-row"><span>Research points<small>Earn passively · Research Center boosts</small></span><b>${Math.floor(g.rp)} RP</b></div>`;
    for(const t of D.RESEARCH_TIERS){
      const owned=g.researchTier>=t.tier;
      h+=`<div class="res-row">
        <span>${t.label}<small>${owned?'Unlocked ✔':t.cost+' RP'}</small></span>
        ${owned?'':`<button class="btn" data-unlock="${t.tier}" ${(next!==t.cost)?'disabled':''}>Unlock</button>`}
      </div>`;
    }
    h+='<p style="font-size:11px;color:var(--ink-soft);margin:6px 2px;">New terrain, buildings & rare animals arrive with each tier.</p>';
    c.innerHTML=h;
    c.querySelectorAll('[data-unlock]').forEach(b=>{
      b.onclick=()=>{ g.buyResearch(); UI.renderSide(); };
    });
  }else{
    const P=g.ratingParts||{};
    const pc=k=>Math.round((P[k]||0)*100);
    let occ={};
    for(const a of g.animals) occ[a.species]=(occ[a.species]||0)+1;
    let occStr=Object.keys(occ).map(s=>`${D.SPECIES[s].name} ×${occ[s]}`).join(', ')||'None yet';
    c.innerHTML=`
      <div class="zoo-stat"><span>Rating</span><b>${g.rating.toFixed(1)}★</b></div>
      <div class="zoo-stat"><span>Animal welfare</span><b>${pc('welfare')}%</b></div>
      <div class="zoo-stat"><span>Guest joy</span><b>${pc('joy')}%</b></div>
      <div class="zoo-stat"><span>Species variety</span><b>${pc('variety')}%</b></div>
      <div class="zoo-stat"><span>Facilities</span><b>${pc('facilities')}%</b></div>
      <div class="zoo-stat"><span>Decor</span><b>${pc('decor')}%</b></div>
      <div class="zoo-stat"><span>Species kept</span><b>${g.speciesCount()}/15</b></div>
      <div class="zoo-stat"><span>Animals</span><b>${g.animals.length}</b></div>
      <div class="zoo-stat"><span>Staff</span><b>${g.staff.length}</b></div>
      <div class="zoo-stat"><span>Guests today</span><b>${g.stats.guestsToday}</b></div>
      <div class="zoo-stat"><span>Total revenue</span><b>${WK.fmtMoney(g.stats.revenueTotal)}</b></div>
      <div style="margin-top:8px;font-size:12px;line-height:1.4;color:var(--ink-soft)"><b>Inhabitants:</b> ${occStr}</div>`;
  }
};
UI.switchTab=function(tab){ UI._sideTab=tab; UI.renderSide(); };

/* ---------------- selection popup ---------------- */
UI.showSelection=function(target){
  UI._selTarget=target;
  const el=$('sel-popup');
  const g=UI.game;
  let html='';
  if(target.kind==='animal'){
    const sp=D.SPECIES[target.species];
    const score=Math.round(g.habitatScore(target));
    html=`
      <h3>${WK.Sprites.iconImg('animal:'+target.species,40)}<span>${target.name}</span></h3>
      <div class="row"><span>${sp.name} · appeal ${'★'.repeat(Math.min(5,Math.ceil(sp.appeal/1.6)))}</span></div>
      <div class="row"><span>Happiness</span></div>
      <div class="bar"><i style="width:${target.happiness|0}%;background:${barColor(target.happiness)}"></i></div>
      <div class="row"><span>Hunger</span></div>
      <div class="bar"><i style="width:${target.hunger|0}%;background:${barColor(100-target.hunger)}"></i></div>
      <div class="row"><span>Habitat match</span><b>${score}%</b></div>
      ${target.sick?'<div class="row"><b style="color:var(--red)">Sick — needs a vet!</b></div>':''}
      <div class="btns"><button class="btn danger" data-sell="${target.id}">Rehome +${WK.fmtMoney(sp.cost*0.45)}</button></div>`;
  }else if(target.kind==='guest'){
    html=`
      <h3><span>${target.kid?'Young guest':'Guest'}</span></h3>
      <div class="row"><span>Joy</span></div>
      <div class="bar"><i style="width:${target.joy|0}%;background:${barColor(target.joy)}"></i></div>
      ${target.wantsRestroom?'<div class="row"><b style="color:var(--orange)">Looking for a restroom…</b></div>':''}`;
  }else if(target.kind==='staff'){
    html=`
      <h3><span>${target.role==='keeper'?'Keeper':'Vet'}</span></h3>
      <div class="row"><span>${target.workT>0?'Working…':target.job?'On the way!':'Patrolling the zoo'}</span></div>`;
  }else if(target.w&&target.h){ // building
    const def=D.BUILDING[target.type];
    html=`
      <h3>${WK.Sprites.iconImg('facility:'+target.type,40)}<span>${def.name}</span></h3>
      ${def.desc?`<div class="row"><span>${def.desc}</span></div>`:''}
      ${def.income?`<div class="row"><span>Avg spend per guest</span><b>${WK.fmtMoney(def.income)}</b></div>`:''}
      ${def.rp?`<div class="row"><span>Generates</span><b>+${def.rp} RP/min</b></div>`:''}
      <div class="btns"><button class="btn danger" data-demo="${target.id}">Demolish +${WK.fmtMoney(def.cost*0.5)}</button></div>`;
  }else if(target.kind==='habitat'){
    const reg=g.world.regions.find(r=>r.id===target.regionId);
    const anims=g.animals.filter(a=>a.regionId===target.regionId);
    const occ={};
    for(const a of anims) occ[a.name]=D.SPECIES[a.species].name;
    const occStr=anims.map(a=>a.name+' ('+D.SPECIES[a.species].name+')').join('<br>')||'<i>Empty habitat</i>';
    html=`
      <h3><span>Habitat</span></h3>
      <div class="row"><span>Area</span><b>${reg.area} tiles</b></div>
      <div class="row"><span>Inhabitants</span></div>
      <div style="font-size:12px;margin:2px 0 4px">${occStr}</div>`;
  }else return;
  el.innerHTML=html;
  el.classList.remove('hidden');
  const sellBtn=el.querySelector('[data-sell]');
  if(sellBtn) sellBtn.onclick=()=>{
    const a=g.animals.find(x=>x.id==sellBtn.dataset.sell);
    if(a) g.sellAnimal(a);
  };
  const demoBtn=el.querySelector('[data-demo]');
  if(demoBtn) demoBtn.onclick=()=>{
    const b=g.world.buildings.find(x=>x.id==demoBtn.dataset.demo);
    if(b) g.demolishBuilding(b);
  };
  UI.positionSelection();
};
function barColor(v){ return v>60?'#63b34c':v>30?'#ffc93c':'#e85d5d'; }
UI.positionSelection=function(){
  const el=$('sel-popup'), t=UI._selTarget;
  if(!el||!t||el.classList.contains('hidden'))return;
  const p=UI.cam.project(t.x,t.y);
  let x=p.x+24,y=p.y-70;
  x=WK.clamp(x,8,UI.cam.w-el.offsetWidth-8);
  y=WK.clamp(y,60,UI.cam.h-el.offsetHeight-90);
  el.style.left=x+'px'; el.style.top=y+'px';
};
UI.trackSelection=function(){
  const t=UI._selTarget;
  if(!t)return;
  if(t.kind==='animal'&&!UI.game.animals.includes(t)){ UI.hideSelection(); return; }
  if(t.kind==='guest'&&!UI.game.guests.includes(t)){ UI.hideSelection(); return; }
  if(t.kind==='staff'&&!UI.game.staff.includes(t)){ UI.hideSelection(); return; }
  if(t.w&&!UI.game.world.buildings.includes(t)){ UI.hideSelection(); return; }
  UI.positionSelection();
};
UI.hideSelection=function(){
  UI._selTarget=null;
  $('sel-popup').classList.add('hidden');
};

/* ---------------- toasts ---------------- */
UI.toast=function(msg,type){
  const box=$('toasts');
  while(box.children.length>=4) box.firstChild.remove();
  const t=document.createElement('div');
  t.className='toast '+(type||'');
  t.textContent=msg;
  box.appendChild(t);
  setTimeout(()=>t.classList.add('fade'),3200);
  setTimeout(()=>t.remove(),3700);
};

/* ---------------- modals ---------------- */
UI.modal=function(inner,opts){
  opts=opts||{};
  const root=$('modal-root');
  root.innerHTML=`<div class="modal-backdrop"><div class="modal panel">${inner}</div></div>`;
  root.firstChild.addEventListener('pointerdown',e=>{ if(e.target===root.firstChild&&!opts.sticky) UI.closeModal(); });
  return root.querySelector('.modal');
};
UI.closeModal=function(){ $('modal-root').innerHTML=''; };

UI.settingsModal=function(){
  const g=UI.game;
  const m=UI.modal(`
    <h2>Settings</h2>
    <div class="set-row"><span>Sound effects</span><button class="btn" id="set-sfx">${WK.AudioSys.enabled?'On':'Off'}</button></div>
    <div class="set-row"><span>Music</span><button class="btn" id="set-music">${WK.AudioSys.musicOn?'On':'Off'}</button></div>
    <div class="set-row"><span>Save game</span><button class="btn" id="set-save">Save now</button></div>
    <div class="set-row"><span>New zoo</span><button class="btn danger" id="set-new">Start over</button></div>
    <div class="modal-btns"><button class="btn primary" id="set-close">Done</button></div>`);
  m.querySelector('#set-sfx').onclick=e=>{ WK.AudioSys.toggleSound(); e.target.textContent=WK.AudioSys.enabled?'On':'Off'; $('btn-sound').textContent=WK.AudioSys.enabled?'🔊':'🔇'; };
  m.querySelector('#set-music').onclick=e=>{ WK.AudioSys.ensure(); WK.AudioSys.toggleMusic(); e.target.textContent=WK.AudioSys.musicOn?'On':'Off'; };
  m.querySelector('#set-save').onclick=()=>{ g.save(); UI.toast('Zoo saved!','good'); };
  m.querySelector('#set-new').onclick=()=>{
    UI.modal(`<h2>Start a new zoo?</h2><p>Your current zoo and progress will be lost.</p>
      <div class="modal-btns"><button class="btn" id="nc">Cancel</button><button class="btn danger" id="ny">Yes, start over</button></div>`,{sticky:true});
    $('nc').onclick=()=>UI.settingsModal();
    $('ny').onclick=()=>{ Game_restart(); };
  };
  m.querySelector('#set-close').onclick=()=>UI.closeModal();
};
function Game_restart(){ /* replaced by main.js */ }

/* how-to */
UI.howtoModal=function(fromMenu){
  UI.modal(`
    <h2>How to Play</h2>
    <ul>
      <li><b>Pan</b> by dragging (right-click / empty hand / one finger), <b>zoom</b> with the wheel or pinch.</li>
      <li><b>Paths first!</b> Guests only walk on paths. Connect everything to your entrance.</li>
      <li><b>Habitats:</b> fence an area completely, paint matching terrain inside, then adopt animals into it. Each species has favorite biomes and needs space.</li>
      <li><b>Keepers feed animals</b> — hire one with a Keeper Hut. Add a Keeper Gate so they can walk in.</li>
      <li><b>Guests need</b> restrooms, food stands, benches and beautiful decor. Happy guests pay more entry and spend more.</li>
      <li><b>Research</b> unlocks rare species and fancy buildings. A Research Center speeds it up.</li>
      <li>Watch the <b>Missions</b> panel — rewards guide your way to a 5★ zoo!</li>
    </ul>
    <p style="font-size:12px;color:var(--ink-soft)">Hotkeys: <span class="kbd">Space</span> pause · <span class="kbd">1–3</span> speed · <span class="kbd">X</span> bulldoze · <span class="kbd">Esc</span> cancel tool</p>
    <div class="modal-btns"><button class="btn primary" id="how-ok">Let's build!</button></div>`);
  $('how-ok').onclick=()=>{ UI.closeModal(); if(fromMenu&&UI._onHowClose) UI._onHowClose(); };
};
UI.confirmNewFromMenu=function(){ /* main.js overrides menu flows */ };

/* ---------------- bindings ---------------- */
UI.bind=function(){
  $('spd-pause').onclick=()=>{WK.AudioSys.sfx('click');UI.setSpeed(0);};
  $('spd-play').onclick=()=>{WK.AudioSys.sfx('click');UI.setSpeed(1);};
  $('spd-fast').onclick=()=>{WK.AudioSys.sfx('click');UI.setSpeed(2);};
  $('spd-ultra').onclick=()=>{WK.AudioSys.sfx('click');UI.setSpeed(4);};
  $('btn-sound').onclick=()=>{ WK.AudioSys.ensure(); const on=WK.AudioSys.toggleSound(); $('btn-sound').textContent=on?'🔊':'🔇'; };
  $('btn-settings').onclick=()=>{ WK.AudioSys.sfx('click'); UI.settingsModal(); };
  $('btn-bulldoze').onclick=()=>{ WK.AudioSys.sfx('click'); UI.toggleBulldoze(); };
  document.querySelectorAll('.sp-tab').forEach(b=>b.onclick=()=>{ UI.switchTab(b.dataset.tab); });
  $('sp-toggle').onclick=()=>{
    const sp=$('side-panel');
    sp.classList.toggle('hidden');
  };
  window.Game_restart = function(){
    WK.Main.startNew();
    UI.closeModal();
  };
};
})();
