const root=document.getElementById('reward-odds'),message=document.getElementById('odds-status');
const el=(tag,text)=>{const n=document.createElement(tag);if(text)n.textContent=text;return n;};let snapshot,busy=false,seq=0;
async function api(b){const r=await fetch('/api/hole/reward-odds',{method:b?'POST':'GET',credentials:'same-origin',cache:'no-store',headers:b?{'Content-Type':'application/json'}:{},...(b?{body:JSON.stringify({...b,scope:snapshot?.scope})}:{}),signal:AbortSignal.timeout(25000)}),d=await r.json();if(!r.ok)throw Error(r.status===401?'Sign in through Profile with your owner email.':r.status===403?'Use an approved owner account to manage reward odds.':d.error||'Could not load reward odds.');return d;}
function render(){root.replaceChildren();for(const [game,title]of [['spin','Wabbit Spin'],['scratch','Wabbit Scratcher']]){
 const p=snapshot.plans.find(p=>p.game===game),f=el('form');f.className='wh-content-card odds-draft';f.append(el('h3',title+' odds draft'),el('p',p?'Saved draft version '+p.version+'. Not active in prize games.':'No odds saved yet. All rewards start excluded.'));
 const entries=[];
 for(const a of snapshot.rewards){const r=p?.rows.find(r=>r.assetId===a.id),box=el('fieldset'),legend=el('legend',a.name+' · '+a.available+' available');box.className='odds-row';box.append(legend);const chanceLabel=el('label','Chance per play (%)'),chance=el('input');chance.type='number';chance.min='0';chance.max='100';chance.step='0.01';chance.value=String((r?.chanceBps||0)/100);chance.required=true;chanceLabel.append(chance);const capLabel=el('label','Maximum awards in this draft'),cap=el('input');cap.type='number';cap.min='0';cap.max=String(a.available);cap.step='1';cap.value=String(r?.maxAwards||0);cap.required=true;capLabel.append(cap);box.append(chanceLabel,capLabel);f.append(box);entries.push({a,chance,cap});}
 const summary=el('p'),update=()=>{const total=entries.reduce((n,e)=>n+Math.round(Number(e.chance.value)*100),0);summary.textContent=total>10000?'Chances exceed 100%. Lower them before saving.':'Total reward chance: '+(total/100).toFixed(2)+'%. No-reward chance: '+((10000-total)/100).toFixed(2)+'%.';};entries.forEach(e=>e.chance.oninput=update);update();f.append(summary);const submit=el('button','Save '+title+' draft');submit.className='button primary';submit.type='submit';f.append(submit);
 f.onsubmit=async e=>{e.preventDefault();if(busy)return;busy=true;submit.disabled=true;const g=seq;message.textContent='Saving odds draft…';try{const next=await api({game,version:p?.version||0,rows:entries.map(e=>({assetId:e.a.id,chanceBps:Math.round(Number(e.chance.value)*100),maxAwards:Number(e.cap.value)}))});if(g!==seq)return;snapshot=next;render();message.textContent='Draft saved. These odds apply equally to all entry routes when attached to a future approved prize campaign. No prize game was enabled.';}catch(e){if(g===seq)message.textContent=e.message;}finally{busy=false;submit.disabled=false;}};root.append(f);
}}
async function load(){if(busy)return;const g=++seq;try{const d=await api();if(g!==seq)return;snapshot=d;render();message.textContent='';}catch(e){if(g===seq){root.replaceChildren();message.textContent=e.message;}}}
document.getElementById('refresh-odds').onclick=load;window.addEventListener('wabbit:member',()=>{seq++;snapshot=null;root.replaceChildren();load();});load();
