'use strict';
(function(){
  const clampN=(n,a,b)=>Math.max(a,Math.min(b,n));
  const roles=['Ergänzungsspieler','Rotation','Stammspieler','Schlüsselspieler'];
  function ensureContracts(){
    if(typeof state==='undefined'||!state||!getUserClub())return;
    const c=getUserClub();
    state.contractSystem ||= {active:null,history:[],lastTickWeek:-1,version:'4.4'};
    c.squad.forEach(p=>{
      p.contract=Number.isFinite(+p.contract)?+p.contract:2;
      p.wage=Math.max(500,Math.round(+p.wage||p.rating*p.rating*18));
      p.signingBonus=Math.max(25000,Math.round(+p.signingBonus||p.wage*12));
      p.releaseClause=Math.max(p.value||100000,Math.round(+p.releaseClause||Math.max(p.value*1.8,p.wage*180)));
      p.agent=p.agent||['FairPlay Management','Elite Football Group','ProStar Agency','Alpen Sports','Global Eleven'][Math.floor(Math.random()*5)];
      p.loyalty=clampN(+p.loyalty||Math.round(45+Math.random()*40),1,100);
      p.squadRole=p.squadRole||roleFor(p,c);
      p.negotiationCooldown=Math.max(0,+p.negotiationCooldown||0);
    });
  }
  function roleFor(p,c){
    const rank=[...c.squad].sort((a,b)=>b.rating-a.rating).findIndex(x=>x.id===p.id);
    if(rank<4)return 'Schlüsselspieler';if(rank<12)return 'Stammspieler';if(rank<19)return 'Rotation';return 'Ergänzungsspieler';
  }
  function demandFor(p){
    const years=p.age>=32?2:p.age<=22?4:3;
    const role=roleFor(p,getUserClub());
    const roleFactor={Ergänzungsspieler:.95,Rotation:1.04,Stammspieler:1.15,Schlüsselspieler:1.3}[role];
    const formFactor=.92+(p.form||70)/500;
    const moraleFactor=.95+(p.morale||70)/700;
    const wage=Math.round(Math.max(p.wage*1.05,p.rating*p.rating*19)*roleFactor*formFactor*moraleFactor/100)*100;
    return {years,wage,bonus:Math.round(wage*(10+Math.max(0,80-(p.loyalty||60))/10)/1000)*1000,clause:Math.round(Math.max(p.value*1.55,wage*150)/10000)*10000,role};
  }
  function startNegotiation(id){
    ensureContracts();const p=getUserClub().squad.find(x=>x.id===id);if(!p)return;
    if(p.negotiationCooldown>0)return alert(`Der Berater verhandelt erst in ${p.negotiationCooldown} Wochen wieder.`);
    const d=demandFor(p);state.contractSystem.active={playerId:p.id,round:1,maxRounds:3,demand:d,offer:{...d},message:`${p.agent} legt die erste Forderung vor.`};save();render();
  }
  function scoreOffer(p,a){
    const d=a.demand,o=a.offer;
    const wage=clampN(o.wage/d.wage,0,1.35)*42;
    const bonus=clampN(o.bonus/Math.max(1,d.bonus),0,1.4)*15;
    const years=Math.min(o.years,d.years)/d.years*12;
    const role=roles.indexOf(o.role)>=roles.indexOf(d.role)?12:Math.max(0,8-(roles.indexOf(d.role)-roles.indexOf(o.role))*5);
    const clause=o.clause<=d.clause?11:clampN(d.clause/o.clause,0,1)*11;
    const soft=((p.loyalty||50)-50)/5+((p.morale||70)-70)/6+(p.contract<.75?4:0);
    return wage+bonus+years+role+clause+soft;
  }
  function submitOffer(){
    ensureContracts();const a=state.contractSystem.active;if(!a)return;const c=getUserClub(),p=c.squad.find(x=>x.id===a.playerId);if(!p)return;
    const y=+document.querySelector('#contractYears')?.value,w=+document.querySelector('#contractWage')?.value,b=+document.querySelector('#contractBonus')?.value,cl=+document.querySelector('#contractClause')?.value,r=document.querySelector('#contractRole')?.value;
    if(!y||!w||b<0||!cl||!roles.includes(r))return alert('Bitte alle Vertragswerte vollständig eingeben.');
    a.offer={years:clampN(y,1,5),wage:Math.max(500,Math.round(w/100)*100),bonus:Math.max(0,Math.round(b/1000)*1000),clause:Math.max(0,Math.round(cl/10000)*10000),role:r};
    if(c.balance<a.offer.bonus)return alert('Der Kontostand reicht für das Handgeld nicht aus.');
    const s=scoreOffer(p,a),roll=Math.random()*100;
    if(s>=87||roll<s-8){
      c.balance-=a.offer.bonus;p.contract=a.offer.years;p.wage=a.offer.wage;p.signingBonus=a.offer.bonus;p.releaseClause=a.offer.clause;p.squadRole=a.offer.role;p.morale=clampN((p.morale||70)+6,0,100);p.loyalty=clampN((p.loyalty||50)+4,0,100);
      state.contractSystem.history.unshift({week:state.week,season:state.season,player:p.name,result:'Verlängert',years:p.contract,wage:p.wage,bonus:p.signingBonus,role:p.squadRole});
      state.news.unshift(`${p.name} verlängert um ${p.contract} Jahre. Wochengehalt: ${money(p.wage)}.`);state.contractSystem.active=null;save();render();return;
    }
    if(a.round<a.maxRounds&&s>=58){
      a.round++;const d=a.demand;
      a.demand={years:Math.max(a.offer.years,d.years),wage:Math.round((a.offer.wage+d.wage*1.03)/200)*100,bonus:Math.round((a.offer.bonus+d.bonus)/2000)*1000,clause:Math.round(Math.min(a.offer.clause,d.clause)*.98/10000)*10000,role:roles[Math.max(roles.indexOf(a.offer.role),roles.indexOf(d.role))]};
      a.offer={...a.demand};a.message=`Gegenforderung in Runde ${a.round}: Der Berater kommt dir etwas entgegen.`;save();render();return;
    }
    p.negotiationCooldown=4;p.morale=clampN((p.morale||70)-6,0,100);state.contractSystem.history.unshift({week:state.week,season:state.season,player:p.name,result:'Gescheitert'});state.news.unshift(`Die Vertragsverhandlung mit ${p.name} ist gescheitert.`);state.contractSystem.active=null;save();render();
  }
  function cancelNegotiation(){if(!state?.contractSystem?.active)return;const p=getUserClub().squad.find(x=>x.id===state.contractSystem.active.playerId);if(p)p.negotiationCooldown=2;state.contractSystem.active=null;save();render();}
  function statusLabel(p){if(p.contract<=.5)return '<span class="bad"><b>Läuft aus</b></span>';if(p.contract<=1)return '<span class="warn"><b>Verlängern</b></span>';return '<span class="good">Gebunden</span>';}
  function contractPanel(){
    ensureContracts();const c=getUserClub(),a=state.contractSystem.active;
    const rows=[...c.squad].sort((x,y)=>x.contract-y.contract||y.rating-x.rating).map(p=>`<tr><td>${esc(p.name)}<br><small>${esc(p.agent)}</small></td><td>${p.age}</td><td>${p.rating}</td><td>${(+p.contract).toFixed(1)} J.</td><td>${money(p.wage)}/W.</td><td>${esc(p.squadRole)}</td><td>${money(p.releaseClause)}</td><td>${statusLabel(p)}</td><td><button data-contract-negotiate="${p.id}" ${p.negotiationCooldown>0?'disabled':''}>${p.negotiationCooldown>0?`${p.negotiationCooldown} Wo. warten`:'Verhandeln'}</button></td></tr>`).join('');
    const negotiation=a?negotiationCard(a,c.squad.find(x=>x.id===a.playerId)):'';
    const hist=state.contractSystem.history.slice(0,15).map(x=>`<tr><td>${x.season}</td><td>${esc(x.player)}</td><td>${x.result}</td><td>${x.years?`${x.years} Jahre · ${money(x.wage)}/W.`:'–'}</td></tr>`).join('');
    return `<div class="card contract-summary"><h2>Spielerverträge & Verhandlungen</h2><div class="grid cols-3"><div class="metric-card"><span>Wochengehälter</span><div class="viz-stat-value">${money(c.squad.reduce((s,p)=>s+p.wage,0))}</div></div><div class="metric-card"><span>Läuft binnen 1 Jahr aus</span><div class="viz-stat-value">${c.squad.filter(p=>p.contract<=1).length}</div></div><div class="metric-card"><span>Kontostand</span><div class="viz-stat-value">${money(c.balance)}</div></div></div>${negotiation}<div class="table-scroll"><table><thead><tr><th>Spieler/Berater</th><th>Alter</th><th>St.</th><th>Restlaufzeit</th><th>Gehalt</th><th>Rolle</th><th>Klausel</th><th>Status</th><th></th></tr></thead><tbody>${rows}</tbody></table></div><h3>Letzte Verhandlungen</h3><table><thead><tr><th>Saison</th><th>Spieler</th><th>Ergebnis</th><th>Vertrag</th></tr></thead><tbody>${hist||'<tr><td colspan="4">Noch keine Verhandlungen.</td></tr>'}</tbody></table></div>`;
  }
  function negotiationCard(a,p){if(!p)return'';const d=a.demand,o=a.offer;return `<section class="contract-negotiation"><div><h3>Verhandlung: ${esc(p.name)}</h3><p>${esc(a.message)}</p><small>Runde ${a.round}/${a.maxRounds} · Forderung: ${d.years} Jahre, ${money(d.wage)}/Woche, ${money(d.bonus)} Handgeld, Rolle ${esc(d.role)}</small></div><div class="contract-form"><label>Laufzeit<select id="contractYears">${[1,2,3,4,5].map(x=>`<option value="${x}" ${x===o.years?'selected':''}>${x} Jahre</option>`).join('')}</select></label><label>Wochengehalt<input id="contractWage" type="number" step="100" min="500" value="${o.wage}"></label><label>Handgeld<input id="contractBonus" type="number" step="1000" min="0" value="${o.bonus}"></label><label>Ausstiegsklausel<input id="contractClause" type="number" step="10000" min="0" value="${o.clause}"></label><label>Kaderrolle<select id="contractRole">${roles.map(x=>`<option ${x===o.role?'selected':''}>${x}</option>`).join('')}</select></label></div><div><button id="submitContractOffer" class="primary">Angebot abgeben</button> <button id="cancelContractOffer">Abbrechen</button></div></section>`;}

  const oldTransfers=window.v20Transfers;
  window.v20Transfers=function(){ensureContracts();return `<div class="card transfer-budget-banner"><span>Verfügbares Transferbudget</span><b>${money(getUserClub().budget)}</b></div>${transfers()}${contractPanel()}<div class="card" style="margin-top:16px"><h2>Leihliste</h2><p class="muted">Spieler können weiterhin im Kader oder über die Transferaktionen zur Leihe angeboten werden.</p></div>`;};
  const oldBind=window.v20Bind;
  window.v20Bind=function(){if(oldBind)oldBind();ensureContracts();document.querySelectorAll('[data-contract-negotiate]').forEach(b=>b.onclick=()=>startNegotiation(b.dataset.contractNegotiate));const s=document.querySelector('#submitContractOffer');if(s)s.onclick=submitOffer;const c=document.querySelector('#cancelContractOffer');if(c)c.onclick=cancelNegotiation;};
  const oldProcess=window.v20ProcessWeek;
  window.v20ProcessWeek=function(){if(oldProcess)oldProcess();ensureContracts();if(state.contractSystem.lastTickWeek===state.week)return;state.contractSystem.lastTickWeek=state.week;const c=getUserClub();c.squad.forEach(p=>{p.negotiationCooldown=Math.max(0,(p.negotiationCooldown||0)-1);});if(state.week%6===0){const exp=c.squad.filter(p=>p.contract<=.5);exp.forEach(p=>state.news.unshift(`Achtung: Der Vertrag von ${p.name} läuft am Saisonende aus.`));}save();};
  const oldEnd=window.endSeason;
  window.endSeason=function(){ensureContracts();const c=getUserClub();const expired=c.squad.filter(p=>p.contract<=.15);expired.forEach(p=>{state.news.unshift(`${p.name} verlässt den Verein ablösefrei nach Vertragsende.`);state.contractSystem.history.unshift({week:state.week,season:state.season,player:p.name,result:'Ablösefrei gegangen'});});if(expired.length){const ids=new Set(expired.map(p=>p.id));c.squad=c.squad.filter(p=>!ids.has(p.id));state.lineup=(state.lineup||[]).filter(id=>!ids.has(id));}oldEnd();};
  const oldNew=window.newGame;
  window.newGame=function(){oldNew.apply(this,arguments);ensureContracts();save();};
  const oldLoad=window.load;
  window.load=function(){oldLoad.apply(this,arguments);ensureContracts();save();};
  window.ContractSystemV44={ensureContracts,startNegotiation};
  if(typeof state!=='undefined'&&state)ensureContracts();
})();
