(() => {
"use strict";
const $=id=>document.getElementById(id),E=Engine;
function defaultLegacy(){return{trophies:[],seasonArchive:[],consequences:[],prestige:0,pendingBudget:0,qualifications:[],careerCompetitionOverrides:{}}}
const PLAYER_BASE=new Map(FOOTBALL_DATA.players.map(p=>[p.id,{clubId:p.clubId,club:p.club,age:p.age,rating:p.rating,potential:p.potential,fitness:p.fitness,morale:p.morale,sharpness:p.sharpness,injury:p.injury,suspension:p.suspension,apps:p.apps,goals:p.goals,assists:p.assists}]));
function fresh(legacy=null){return{clubId:null,mode:null,season:1,week:0,formation:"4-3-3",tactic:"Équilibré",xi:[],budget:0,calendar:[],table:{},history:[],match:null,inbox:[],tournament:null,playerState:{},legacy:legacy||defaultLegacy()}}
function ensureLegacy(){if(!state.legacy)state.legacy=defaultLegacy();const d=defaultLegacy();for(const [k,v] of Object.entries(d))if(state.legacy[k]==null)state.legacy[k]=Array.isArray(v)?[]:typeof v==="object"?{}:v;if(!state.legacy.careerCompetitionOverrides)state.legacy.careerCompetitionOverrides={};return state.legacy}
function restorePlayerBase(){for(const p of FOOTBALL_DATA.players){const b=PLAYER_BASE.get(p.id);if(b)Object.assign(p,b)}E.reindexPlayers()}
function capturePlayerState(){const out={};for(const p of FOOTBALL_DATA.players){const b=PLAYER_BASE.get(p.id);if(!b)continue;const cur={clubId:p.clubId,club:p.club,age:p.age,rating:p.rating,potential:p.potential,fitness:p.fitness,morale:p.morale,sharpness:p.sharpness,injury:p.injury,suspension:p.suspension,apps:p.apps,goals:p.goals,assists:p.assists};if(Object.keys(cur).some(k=>cur[k]!==b[k]))out[p.id]=cur}state.playerState=out;return out}
function applyPlayerState(){restorePlayerBase();for(const [id,chg] of Object.entries(state.playerState||{})){const p=E.player(id);if(p)Object.assign(p,chg)}E.reindexPlayers()}
function validSavedXI(clubId,xi,formation){
 const squad=E.squad(clubId),eligible=new Map(squad.filter(p=>!p.injury&&!p.suspension).map(p=>[p.id,p])),out=[],seen=new Set();
 for(const id of Array.isArray(xi)?xi:[]){if(out.length>=11)break;if(eligible.has(id)&&!seen.has(id)){out.push(id);seen.add(id)}}
 for(const id of E.autoXI(clubId,formation||"4-3-3")){if(out.length>=11)break;if(eligible.has(id)&&!seen.has(id)){out.push(id);seen.add(id)}}
 if(out.length<11){for(const p of squad.filter(p=>!p.injury&&!p.suspension).sort((a,b)=>b.rating-a.rating)){if(out.length>=11)break;if(!seen.has(p.id)){out.push(p.id);seen.add(p.id)}}}
 return out;
}
function normalizeUserXI(){if(state.clubId&&E.squad(state.clubId).length>=11)state.xi=validSavedXI(state.clubId,state.xi,state.formation);else if(!Array.isArray(state.xi))state.xi=[];return state.xi}
function normalizeState(){if(!state||typeof state!=="object")state=fresh();ensureLegacy();if(!state.playerState)state.playerState={};if(!Array.isArray(state.calendar))state.calendar=[];if(!state.table||typeof state.table!=="object")state.table={};if(!Array.isArray(state.history))state.history=[];if(!Array.isArray(state.inbox))state.inbox=[];if(!state.formation)state.formation="4-3-3";if(!state.tactic)state.tactic="Équilibré";if(!Number.isFinite(state.season))state.season=1;if(!Number.isFinite(state.week))state.week=0;applyPlayerState();normalizeUserXI()}
let state=fresh();
function clear(){ $("actions").innerHTML="" }
function btn(t,f){const b=document.createElement("button");b.type="button";b.textContent=t;b.onclick=f;$("actions").appendChild(b)}
function text(lines){$("screen").innerHTML="";lines.forEach(t=>{const p=document.createElement("p");p.textContent=t;$("screen").appendChild(p)})}
function log(t,c=""){const p=document.createElement("p");p.textContent=t;if(c)p.className=c;$("log").prepend(p);while($("log").children.length>30)$("log").lastChild.remove()}
function status(){
 $("status").innerHTML="";
 const a=!state.clubId?[`${FOOTBALL_DATA.meta.clubCount} clubs — ${FOOTBALL_DATA.meta.mappedActiveCount} joueurs actifs — ${FOOTBALL_DATA.meta.profileCount} profils`]:
 [state.tournament?`${E.club(state.clubId).name} — ${state.tournament.name} — ${state.tournament.phase==="knockout"?(state.tournament.koNames[state.tournament.koRound]||"phase finale"):state.tournament.phase==="group"?"phase de groupes":"phase de ligue"}`:`${E.club(state.clubId).name} — ${careerCompetition()} — saison ${state.season}, journée ${Math.min(state.week+1,state.calendar.length)}`,
 `Budget ${E.formatMoney(state.budget)} — formation ${state.formation} — style ${state.tactic}`];
 a.forEach(t=>{const p=document.createElement("p");p.textContent=t;$("status").appendChild(p)})
}
function render(){status();state.clubId?home():menu()}
function menu(){clear();text(["Choisis un mode."]);btn("Carrière entraîneur",()=>countryMenu(false));btn("Coupes et tournois",tournamentMenu);btn("Match rapide",()=>countryMenu(true));btn("Rechercher un club ou joueur",()=>searchMenu(menu));btn("Palmarès et conséquences",legacyScreen);btn("À propos de la base",info)}
function info(){clear();text([`Profils : ${FOOTBALL_DATA.meta.profileCount}.`,`Joueurs actifs liés à un club : ${FOOTBALL_DATA.meta.mappedActiveCount}.`,`Clubs : ${FOOTBALL_DATA.meta.clubCount}.`,`Clubs jouables avec au moins 18 joueurs : ${FOOTBALL_DATA.meta.playableClubCount}.`,FOOTBALL_DATA.meta.note]);btn("Retour",menu)}
function countries(){return [...new Set(FOOTBALL_DATA.clubs.filter(c=>E.squad(c.id).length>=18).map(c=>c.countryFr))].filter(Boolean).sort()}
function countryMenu(quick=false){quick=(quick===true);clear();text(["Choisis un pays."]);countries().forEach(fr=>btn(fr,()=>competitionMenu(fr,quick)));btn("Recherche directe",()=>searchClubForMode(quick));btn("Retour",menu)}
function competitionMenu(countryFr,quick){
 clear();
 const clubs=FOOTBALL_DATA.clubs.filter(c=>c.countryFr===countryFr&&c.competitionId&&!String(c.competitionId).startsWith("ARCH_"));
 const comps=[...new Set(clubs.map(c=>c.competitionFr||c.division||"Autres"))].sort();
 text([countryFr]);comps.forEach(x=>btn(x,()=>clubMenu(countryFr,x,quick)));btn("Retour",()=>countryMenu(quick))
}
function clubMenu(countryFr,compFr,quick){
 clear();
 const cs=FOOTBALL_DATA.clubs.filter(c=>c.countryFr===countryFr&&(c.competitionFr||c.division||"Autres")===compFr).sort((a,b)=>a.name.localeCompare(b.name));
 text([`${countryFr} — ${compFr} — ${cs.length} clubs.`]);
 cs.forEach(c=>{const n=E.squad(c.id).length;if(n>=18)btn(`${c.name} (${n} joueurs)`,()=>quick?quickOpponent(c.id):startCareer(c.id));else btn(`${c.name} — effectif absent du snapshot`,()=>{clear();text([`${c.name} est intégré au championnat et au calendrier 2026-27. Son effectif n’existait pas dans la base source : aucun faux joueur n’a été inventé, ses rencontres sont donc auto-simulées.`]);btn("Retour",()=>clubMenu(countryFr,compFr,quick))})});
 btn("Retour",()=>competitionMenu(countryFr,quick))
}
function searchClubForMode(quick){
 clear();text(["Écris une partie du nom du club."]);
 const i=document.createElement("input");i.placeholder="Ex. Barcelona, Toulouse, Arsenal";$("actions").appendChild(i);
 btn("Rechercher",()=>{const q=i.value.trim().toLowerCase();clear();const a=FOOTBALL_DATA.clubs.filter(c=>c.name.toLowerCase().includes(q)&&E.squad(c.id).length>=18).slice(0,50);text([`${a.length} résultat(s).`]);a.forEach(c=>btn(`${c.name} — ${c.countryFr} — ${c.competitionFr}`,()=>quick?quickOpponent(c.id):startCareer(c.id)));btn("Retour",()=>countryMenu(quick))});
 btn("Retour",()=>countryMenu(quick))
}

function tournamentMenu(){
 clear();text(["Coupes indépendantes : elles ne créent pas de nouvelle saison. Les classements/poules déterminent réellement les qualifiés pour les phases finales."]);
 FOOTBALL_TOURNAMENTS.forEach(t=>btn(`${t.name} — ${t.description}`,()=>tournamentTeamMenu(t.id)));btn("Retour",menu)
}
function tournamentTeamMenu(tid){
 const t=FOOTBALL_TOURNAMENTS.find(x=>x.id===tid);clear();text([t.name,t.description,"Choisis ton équipe."]);
 t.teams.filter(id=>E.squad(id).length>=18).forEach(id=>btn(E.club(id).name,()=>startTournament(tid,id)));btn("Retour",tournamentMenu)
}
function initTTable(ids){const o={};ids.forEach(id=>o[id]={p:0,w:0,d:0,l:0,gf:0,ga:0,pts:0});return o}
function oneLegSchedule(ids){
 const full=E.schedule(ids),half=full.slice(0,Math.max(1,Math.floor(full.length/2)));return half
}
function leaguePhaseSchedule(ids,matches){
 const rounds=E.schedule(ids).slice(0,matches);return rounds
}
function startTournament(tid,id){
 const t=FOOTBALL_TOURNAMENTS.find(x=>x.id===tid);restorePlayerBase();state=fresh(state.legacy);state.mode="tournament";state.clubId=id;state.xi=E.autoXI(id,state.formation);state.budget=0;
 state.tournament={id:tid,name:t.name,kind:t.kind,teams:[...t.teams],phase:t.kind==="groups"?"group":"league",round:0,history:[],knockout:[],koRound:0,koLeg:1,userAggregate:null,champion:null,eliminated:false};
 if(t.kind==="league36"){state.tournament.calendar=leaguePhaseSchedule(t.teams,t.leagueMatches);state.tournament.table=initTTable(t.teams)}
 else{
   state.tournament.groups=[];for(let i=0;i<t.groups;i++)state.tournament.groups.push(t.teams.slice(i*t.groupSize,(i+1)*t.groupSize));
   state.tournament.groupTables=state.tournament.groups.map(a=>initTTable(a));
   state.tournament.groupCalendars=state.tournament.groups.map(a=>oneLegSchedule(a));
   state.tournament.groupRound=0
 }
 render()
}
function tSort(table){return Object.entries(table).sort((a,b)=>b[1].pts-a[1].pts||((b[1].gf-b[1].ga)-(a[1].gf-a[1].ga))||b[1].gf-a[1].gf)}
function tUpdate(table,h,a,hg,ag){const H=table[h],A=table[a];if(!H||!A)return;H.p++;A.p++;H.gf+=hg;H.ga+=ag;A.gf+=ag;A.ga+=hg;if(hg>ag){H.w++;A.l++;H.pts+=3}else if(ag>hg){A.w++;H.l++;A.pts+=3}else{H.d++;A.d++;H.pts++;A.pts++}}
function simFootball(h,a){return E.realisticScore(E.clubPower(h,E.autoXI(h,"4-3-3"),"Équilibré"),E.clubPower(a,E.autoXI(a,"4-3-3"),"Équilibré"),1)}
function simulateTournamentRound(round,table,userId){
 for(const [h,a] of round||[]){if(userId&&(h===userId||a===userId))continue;const s=simFootball(h,a);tUpdate(table,h,a,s[0],s[1]);state.tournament.history.push({phase:state.tournament.phase,h,a,hg:s[0],ag:s[1]})}
}
function currentTournamentPair(){
 const T=state.tournament;if(!T||T.champion||T.eliminated)return null;
 if(T.phase==="league"){const r=T.calendar[T.round]||[];return r.find(x=>x.includes(state.clubId))||null}
 if(T.phase==="group"){const gi=T.groups.findIndex(g=>g.includes(state.clubId));const r=T.groupCalendars[gi]?.[T.groupRound]||[];return r.find(x=>x.includes(state.clubId))||null}
 if(T.phase==="knockout"){const p=T.knockout[T.koRound]?.find(x=>x.includes(state.clubId))||null;return p&&twoLegTournamentRound(T)&&T.koLeg===2?[p[1],p[0]]:p}
 return null
}
function tournamentNext(){
 const T=state.tournament;if(T.phase==="league"){
  while(T.round<T.calendar.length){let p=(T.calendar[T.round]||[]).find(x=>x.includes(state.clubId));if(p)return p;simulateTournamentRound(T.calendar[T.round],T.table,state.clubId);T.round++}
  buildLeagueKnockout();return currentTournamentPair()
 }
 if(T.phase==="group"){
  const gi=T.groups.findIndex(g=>g.includes(state.clubId));
  while(T.groupRound<T.groupCalendars[gi].length){let p=T.groupCalendars[gi][T.groupRound].find(x=>x.includes(state.clubId));if(p)return p;
   for(let k=0;k<T.groups.length;k++)simulateTournamentRound(T.groupCalendars[k][T.groupRound],T.groupTables[k],state.clubId);T.groupRound++}
  buildGroupKnockout();return currentTournamentPair()
 }
 if(T.phase==="knockout")return currentTournamentPair();
 return null
}
function seedPairs(ids){let a=[...ids],pairs=[];for(let i=0;i<a.length/2;i++)pairs.push([a[i],a[a.length-1-i]]);return pairs}
function twoLegTournamentRound(T){return (T.id==="ucl"||T.id==="uecl")&&T.phase==="knockout"&&T.koRound<T.koNames.length-1}
function simTwoLegFootball(p){const a=simFootball(p[0],p[1]),b=simFootball(p[1],p[0]);let x=a[0]+b[1],y=a[1]+b[0];if(x===y){if(Math.random()<.5)x++;else y++}return{winner:x>y?p[0]:p[1],leg1:a,leg2:b,agg:[x,y]}}
function buildLeagueKnockout(){
 const T=state.tournament,rank=tSort(T.table).map(x=>x[0]),top8=rank.slice(0,8),play=rank.slice(8,24);
 if(!rank.slice(0,24).includes(state.clubId)){T.eliminated=true;return}
 T.phase="knockout";T.koNames=["Barrages","Huitièmes de finale","Quarts de finale","Demi-finales","Finale"];T.koRound=rank.slice(8,24).includes(state.clubId)?0:1;
 const playoff=seedPairs(play);T.prequalified=top8;T.knockout=[playoff,[],[],[],[]];
 if(T.koRound===1){for(const p of playoff){const s=simFootball(p[0],p[1]);T.history.push({phase:"Barrages",h:p[0],a:p[1],hg:s[0],ag:s[1]});(T.playoffWinners||(T.playoffWinners=[])).push(s[0]>=s[1]?p[0]:p[1])}T.knockout[1]=seedPairs([...top8,...T.playoffWinners])}
}
function buildGroupKnockout(){
 const T=state.tournament,conf=FOOTBALL_TOURNAMENTS.find(x=>x.id===T.id),qualified=[],thirds=[];
 for(let i=0;i<T.groups.length;i++){let r=tSort(T.groupTables[i]);qualified.push(r[0][0],r[1][0]);if(r[2])thirds.push(r[2])}
 thirds.sort((a,b)=>b[1].pts-a[1].pts||((b[1].gf-b[1].ga)-(a[1].gf-a[1].ga)));qualified.push(...thirds.slice(0,conf.bestThird).map(x=>x[0]));
 if(!qualified.includes(state.clubId)){T.eliminated=true;return}
 // seed all qualifiers from pool performance; every participant comes directly from the completed pools.
 const score=id=>{for(const tb of T.groupTables){if(tb[id])return tb[id]}return{pts:0,gf:0,ga:0}};
 qualified.sort((a,b)=>score(b).pts-score(a).pts||((score(b).gf-score(b).ga)-(score(a).gf-score(a).ga)));
 T.phase="knockout";T.koNames=qualified.length===32?["Seizièmes de finale","Huitièmes de finale","Quarts de finale","Demi-finales","Finale"]:["Huitièmes de finale","Quarts de finale","Demi-finales","Finale"];
 T.koRound=0;T.knockout=[seedPairs(qualified)];while(T.knockout.length<T.koNames.length)T.knockout.push([])
}
function advanceKnockoutRound(){
 const T=state.tournament,round=T.knockout[T.koRound],w=[];
 for(const p of round){if(p.includes(state.clubId))continue;if(twoLegTournamentRound(T)){const z=simTwoLegFootball(p);w.push(z.winner);T.history.push({phase:`${T.koNames[T.koRound]} — aller`,h:p[0],a:p[1],hg:z.leg1[0],ag:z.leg1[1]});T.history.push({phase:`${T.koNames[T.koRound]} — retour`,h:p[1],a:p[0],hg:z.leg2[0],ag:z.leg2[1],winner:z.winner,note:`cumul ${z.agg[0]}-${z.agg[1]}`})}else{const s=simFootball(p[0],p[1]);let win=s[0]===s[1]?(Math.random()<.5?p[0]:p[1]):(s[0]>s[1]?p[0]:p[1]);w.push(win);T.history.push({phase:T.koNames[T.koRound],h:p[0],a:p[1],hg:s[0],ag:s[1],winner:win})}}
 if(T.pendingUserWinner)w.push(T.pendingUserWinner);T.pendingUserWinner=null;
 if(w.length===1&&round.length===1){T.champion=w[0];return}
 T.koRound++;T.koLeg=1;T.userAggregate=null;
 if(T.koRound>=T.koNames.length){T.champion=w[0];return}
 if(T.id==="ucl"||T.id==="uecl"){
   if(T.koRound===1&&T.prequalified){w.push(...T.prequalified);T.prequalified=null}
 }
 T.knockout[T.koRound]=seedPairs(w)
}
function tournamentTableScreen(){
 const T=state.tournament;clear();
 if(T.phase==="league")text(tSort(T.table).map(([id,r],i)=>`${i+1}. ${E.club(id).name} — ${r.pts} pts — ${r.gf}-${r.ga}`));
 else if(T.phase==="group"){let lines=[];T.groups.forEach((g,i)=>{lines.push(`Groupe ${String.fromCharCode(65+i)}`);tSort(T.groupTables[i]).forEach(([id,r],j)=>lines.push(`${j+1}. ${E.club(id).name} — ${r.pts} pts — ${r.gf}-${r.ga}`))});text(lines)}
 else text((T.knockout[T.koRound]||[]).map(p=>`${E.club(p[0]).name} - ${E.club(p[1]).name}`));
 btn("Retour",home)
}

const OFFICIAL_LEAGUE_ROUNDS={GB1:38,GB2:46,GB3:46,GB4:46,CNAT:46,FR1:34,FR2:34,FR3:34,L1:34,L2:34,L3:38,ES1:38,ES2:42,IT1:38,IT2:38,PO1:34,PO2:34};
function careerCompetitionId(){const c=E.club(state.clubId),target=careerCompetition();if(target===c.competitionFr)return c.competitionId;const hit=FOOTBALL_DATA.clubs.find(x=>x.countryFr===c.countryFr&&x.competitionFr===target);return hit?.competitionId||c.competitionId}
function fitCalendarRounds(ids,rounds){let base=E.schedule(ids);if(!rounds||!base.length)return base;if(base.length===rounds)return base;if(base.length>rounds)return base.slice(0,rounds);let out=[];for(let i=0;i<rounds;i++)out.push(base[i%base.length].map(([h,a])=>i>=base.length&&i%2?[a,h]:[h,a]));return out}
function careerCalendar(ids){const cid=careerCompetitionId(),target=OFFICIAL_LEAGUE_ROUNDS[cid];return fitCalendarRounds(ids,target)}
function simCareerFixture(h,a){const sc=E.realisticScore(E.clubPower(h,E.autoXI(h,'4-3-3'),'Équilibré'),E.clubPower(a,E.autoXI(a,'4-3-3'),'Équilibré'),1);return sc}
function startCareer(id){
 restorePlayerBase();state=fresh(state.legacy);state.mode="career";state.clubId=id;state.budget=clubBudget(id)+ensureLegacy().pendingBudget;ensureLegacy().pendingBudget=0;state.xi=E.autoXI(id,state.formation);initSeason();
 state.inbox.push("Bienvenue. Utilise « Que faire ? » pour être guidé.");
 render()
}
function clubBudget(id){const n=E.squad(id).reduce((s,p)=>s+p.value,0);return Math.max(5e6,Math.round(n*.22))}
function careerCompetition(){const L=ensureLegacy(),c=E.club(state.clubId);return L.careerCompetitionOverrides[state.clubId]||c.competitionFr}
function leagueClubs(){
 const c=E.club(state.clubId),target=careerCompetition();
 let same=target!==c.competitionFr?FOOTBALL_DATA.clubs.filter(x=>x.countryFr===c.countryFr&&x.competitionFr===target&&!String(x.competitionId||"").startsWith("ARCH_")):FOOTBALL_DATA.clubs.filter(x=>x.competitionId&&c.competitionId&&x.competitionId===c.competitionId);
 if(same.length<6)same=FOOTBALL_DATA.clubs.filter(x=>x.countryFr===c.countryFr&&x.competitionFr===target&&!String(x.competitionId||"").startsWith("ARCH_"));
 if(!same.some(x=>x.id===c.id))same=[c,...same];
 const cid=careerCompetitionId(),rounds=OFFICIAL_LEAGUE_ROUNDS[cid],officialCount=rounds?Math.floor(rounds/2)+1:null;
 if(officialCount&&same.length>officialCount){const others=same.filter(x=>x.id!==c.id).sort((a,b)=>E.clubPower(a.id,E.autoXI(a.id,"4-3-3"),"Équilibré")-E.clubPower(b.id,E.autoXI(b.id,"4-3-3"),"Équilibré"));while(others.length>officialCount-1)others.shift();same=[c,...others]}
 return same;
}
function initSeason(){
 const cs=leagueClubs();
 const ids=cs.map(c=>c.id);
 state.calendar=careerCalendar(ids);state.table={};ids.forEach(id=>state.table[id]={p:0,w:0,d:0,l:0,gf:0,ga:0,pts:0});state.week=0;
 state.inbox.push(`Championnat chargé : ${careerCompetition()}, ${ids.length} clubs, ${state.calendar.length} journées.`)
}
function nextMatch(){
 while(state.week<state.calendar.length){
   const round=state.calendar[state.week]||[],g=round.find(x=>x.includes(state.clubId));
   if(g){const opp=g[0]===state.clubId?g[1]:g[0];if(E.squad(opp).length>=11)return{home:g[0]===state.clubId,opponent:opp};
     const us=simCareerFixture(g[0],g[1]);update(g[0],g[1],us[0],us[1]);state.history.push({week:state.week+1,home:g[0],away:g[1],hg:us[0],ag:us[1],auto:true});
     round.filter(x=>x!==g).forEach(([h,a])=>{const s=simCareerFixture(h,a);update(h,a,s[0],s[1])});state.inbox.push(`J${state.week+1} auto-simulée : adversaire sans effectif complet dans la base.`);state.week++;continue
   }
   round.forEach(([h,a])=>{const s=simCareerFixture(h,a);update(h,a,s[0],s[1])});state.week++;
 }
 return null
}
function home(){
 clear();
 if(state.tournament){
  const T=state.tournament,n=tournamentNext();
  if(T.champion){if(T.champion===state.clubId)grantTournamentReward(T);text([`${T.name} terminée.`,`${E.club(T.champion).name} remporte la compétition.${T.champion===state.clubId?" Tu es champion !":""}`]);btn("Palmarès et conséquences",legacyScreen);btn("Tableau / classements",tournamentTableScreen);btn("Retour au menu",()=>{state=fresh(state.legacy);render()});return}
  if(T.eliminated){text([`${T.name} : ton équipe est éliminée.`,`Les résultats des poules/phase de ligue ont été utilisés pour déterminer les qualifiés.`]);btn("Tableau / classements",tournamentTableScreen);btn("Retour au menu",()=>{state=fresh(state.legacy);render()});return}
  text([n?`Prochain match : ${E.club(n[0]).name} - ${E.club(n[1]).name}.`:"Calcul de la phase suivante..."]);
  if(n)btn("Jouer le prochain match",preMatch);btn("Composition",lineup);btn("Effectif",squadMenu);btn("Classement / tableau",tournamentTableScreen);btn("Calendrier",calendar);return
 }
 const n=nextMatch();text([n?`Prochain match : ${E.club(n.opponent).name} — ${n.home?"domicile":"extérieur"}.`:"Saison terminée."]);
 btn("Que faire ?",help);if(n)btn("Jouer le prochain match",preMatch);btn("Composition",lineup);btn("Effectif",squadMenu);btn("Classement",table);btn("Calendrier",calendar);btn("Entraînement",training);btn("Transferts",transfers);btn("Palmarès et conséquences",legacyScreen);if(!n)btn("Saison suivante",nextSeason)
}
function help(){
 const n=nextMatch();clear();
 text(n?[
 `1. Ton prochain adversaire est ${E.club(n.opponent).name}, dans la même division : ${careerCompetition()}.`,
 "2. Ouvre Équipe pour vérifier les titulaires et leurs postes.",
 "3. Ouvre Tactiques pour choisir la formation et le style.",
 "4. Reviens puis choisis Jouer le prochain match.",
 "5. Pendant le match, tu peux attaquer, construire, accélérer, temporiser, changer de tactique ou faire des remplacements."
 ]:["La saison est terminée. Consulte le classement puis passe à la saison suivante."]);
 btn("Retour",home)
}
function squadMenu(){
 clear();const s=E.squad(state.clubId).sort((a,b)=>b.rating-a.rating);
 text([`${E.club(state.clubId).name} — ${s.length} joueurs.`]);
 btn("Onze titulaire",lineup);
 btn("Effectif complet",()=>playersList(s,squadMenu));
 btn("Indisponibles",()=>playersList(s.filter(p=>p.injury||p.suspension),squadMenu));
 btn("Retour",home)
}
function playersList(a,back){
 clear();text([`${a.length} joueur(s).`]);
 a.forEach(p=>btn(`${p.name} — ${p.posFr||E.posFr(p.pos)} — GEN ${p.rating} — ${p.age} ans`,()=>card(p,back)));
 btn("Retour",back)
}
function card(p,back){
 clear();text([p.name,`Club : ${p.club}`,`Poste : ${p.posFr||E.posFr(p.pos)}`,`Âge : ${p.age}`,`Pays : ${p.nation||"Non renseigné"}`,`GEN simulation : ${p.rating} — potentiel ${p.potential}`,`Valeur jeu : ${E.formatMoney(p.value)}`,`Forme ${p.fitness} — moral ${p.morale}`,`${p.apps} matchs — ${p.goals} buts — ${p.assists} passes décisives`]);btn("Retour",back)
}
function lineup(){
 normalizeUserXI();clear();
 const slots=FOOTBALL_DATA.formations[state.formation]||FOOTBALL_DATA.formations["4-3-3"];
 text([`Onze titulaire — ${state.formation}`]);
 state.xi.forEach((id,i)=>{const p=E.player(id);if(p)btn(`${i+1}. ${p.name} — ${E.posFr(slots[i]||p.pos)} — poste naturel : ${p.posFr||E.posFr(p.pos)} — GEN ${p.rating}`,()=>replace(i))});
 btn("Composition automatique cohérente",()=>{state.xi=E.autoXI(state.clubId,state.formation);lineup()});
 btn("Retour",squadMenu)
}
function replace(i){
 clear();const slots=FOOTBALL_DATA.formations[state.formation]||FOOTBALL_DATA.formations["4-3-3"],target=slots[i];
 text([`Remplacer le poste : ${E.posFr(target)}.`]);
 E.squad(state.clubId).filter(p=>!state.xi.includes(p.id)&&!p.injury&&!p.suspension).sort((a,b)=>
  (b.rating+E.positionScore(b,target))-(a.rating+E.positionScore(a,target))).slice(0,40).forEach(p=>
  btn(`${p.name} — ${p.posFr||E.posFr(p.pos)} — GEN ${p.rating}`,()=>{state.xi[i]=p.id;lineup()}));
 btn("Retour",lineup)
}
function tactics(){
 clear();text([`Formation : ${state.formation}. Style : ${state.tactic}.`]);
 Object.keys(FOOTBALL_DATA.formations).forEach(f=>btn(`Formation ${f}`,()=>{state.formation=f;normalizeUserXI();tactics()}));
 ["Équilibré","Attaque","Défense","Pressing"].forEach(t=>btn(`Style ${t}`,()=>{state.tactic=t;home()}));
 btn("Retour",home)
}
function preMatch(){
 normalizeUserXI();
 const tp=state.tournament?tournamentNext():null;
 const n=state.tournament?{home:tp[0]===state.clubId,opponent:tp[0]===state.clubId?tp[1]:tp[0]}:nextMatch();clear();
 const my=E.club(state.clubId),op=E.club(n.opponent),myPower=E.clubPower(my.id,state.xi,state.tactic),opPower=E.clubPower(op.id,E.autoXI(op.id,"4-3-3"),"Équilibré");
 text([`${my.name} contre ${op.name}`,n.home?"À domicile":"À l’extérieur",state.tournament?`Compétition : ${state.tournament.name}`:`Division : ${my.competitionFr}`,`Force estimée : ${my.name} ${myPower.toFixed(1)} — ${op.name} ${opPower.toFixed(1)}`,`Titulaires : ${state.xi.length}/11`]);
 btn("Jouer le match en texte",()=>startMatch(false));
 btn("Simulation rapide",()=>startMatch(true));
 btn("Composition",lineup);btn("Tactiques",tactics);btn("Retour",home)
}
function startMatch(fast){
 const tp=state.tournament?tournamentNext():null;
 const n=state.tournament?{home:tp[0]===state.clubId,opponent:tp[0]===state.clubId?tp[1]:tp[0]}:nextMatch();
 normalizeUserXI();
 if(state.xi.length<11){log("Impossible de lancer le match : moins de 11 joueurs disponibles.");return preMatch()}
 const ox=validSavedXI(n.opponent,E.autoXI(n.opponent,"4-3-3"),"4-3-3"),h=n.home?state.clubId:n.opponent,a=n.home?n.opponent:state.clubId;
 if(ox.length<11){
   const myPower=E.clubPower(state.clubId,state.xi,state.tactic),nominalOpp=68,sc=n.home?E.realisticScore(myPower,nominalOpp,1):E.realisticScore(nominalOpp,myPower,1);
   state.match={home:h,away:a,homeXI:n.home?[...state.xi]:[],awayXI:n.home?[]:[...state.xi],userHome:n.home,minute:90,hg:sc[0],ag:sc[1],events:["90e — Match auto-simulé : l’effectif détaillé de l’adversaire n’est pas présent dans la base."],momentum:0,goals:[],subs:[],injuries:[],autoUnavailableOpponent:true};
   return finish()
 }
 state.match={home:h,away:a,homeXI:n.home?[...state.xi]:[...ox],awayXI:n.home?[...ox]:[...state.xi],userHome:n.home,minute:0,hg:0,ag:0,events:[],momentum:0,goals:[],subs:[],injuries:[]};
 if(fast){simulateWhole();finish()}else matchScreen()
}
function matchScreen(){
 clear();const m=state.match;
 text([`${E.club(m.home).name} ${m.hg}-${m.ag} ${E.club(m.away).name}`,`${m.minute}e minute`,m.events.at(-1)||"Coup d’envoi. Les deux équipes se mettent en place."]);
 if(m.minute<90){
   btn("Construire patiemment",()=>userAction("build"));
   btn("Attaquer rapidement",()=>userAction("attack"));
   btn("Passer par les ailes",()=>userAction("wing"));
   btn("Jouer dans l’axe",()=>userAction("middle"));
   btn("Presser haut",()=>userAction("press"));
   btn("Temporiser",()=>userAction("slow"));
   btn("Jouer 5 minutes automatiquement",()=>{simulateFive();matchScreen()});
   btn("Changer de tactique",matchTactics);
   btn("Faire un remplacement",subs);
   btn("Simuler jusqu’à la fin",()=>{simulateWhole();finish()})
 } else btn("Continuer",finish)
}
function userAction(type){
 const m=state.match,userXI=m.userHome?m.homeXI:m.awayXI,oppXI=m.userHome?m.awayXI:m.homeXI;
 const passer=pickForAction(userXI,type,"passer");
 const prefTarget=type==="wing"?["RW","LW","RB","LB"]:type==="middle"?["AM","CM","ST"]:["ST","RW","LW","AM"];
 if(!passer)return simulateFive(),matchScreen();
 const target=distinctPlayer(userXI,[passer.id],prefTarget)||passer;
 const opp=pickForAction(oppXI,type,"def")||target;
 const descriptions={
  build:`${passer.name} (${passer.posFr||E.posFr(passer.pos)}) conserve le ballon et trouve ${target.name} (${target.posFr||E.posFr(target.pos)}). ${target.name} se retourne face au jeu.`,
  attack:`${passer.name} accélère et cherche immédiatement ${target.name} dans la profondeur. ${opp.name} tente de couper la trajectoire.`,
  wing:`${passer.name} écarte vers ${target.name} sur le côté. ${target.name} prend de la vitesse et prépare un centre.`,
  middle:`${passer.name} combine dans l’axe avec ${target.name}. ${opp.name} sort au duel pour fermer l’espace.`,
  press:`${passer.name} déclenche le pressing. ${target.name} monte avec lui pour enfermer le porteur adverse.`,
  slow:`${passer.name} temporise, remet derrière puis l’équipe fait circuler le ballon pour calmer le rythme.`
 };
 m.minute=Math.min(90,m.minute+3);
 m.events.push(`${m.minute}e — ${descriptions[type]}`);
 const userPower=E.clubPower(state.clubId,userXI,state.tactic)+(type==="attack"?1.2:type==="press"?.8:type==="slow"?.2:.5);
 const oppClub=m.userHome?m.away:m.home,oppPower=E.clubPower(oppClub,oppXI,"Équilibré");
 let chance=E.clamp(.08+(userPower-oppPower)/180,0.03,0.18);
 if(type==="attack"||type==="wing"||type==="middle")chance+=.03;
 if(Math.random()<chance){
   const scorer=E.weightedScorer(userXI),creator=E.weightedCreator(userXI,scorer.id);
   if(m.userHome)m.hg++;else m.ag++;
   scorer.goals++;
   if(creator){creator.assists++;m.goals.push({minute:m.minute,teamId:state.clubId,scorerId:scorer.id,assistId:creator.id});m.events.push(`${m.minute}e — BUT ! ${creator.name} trouve ${scorer.name}, ${scorer.posFr||E.posFr(scorer.pos)}, qui marque pour ${E.club(state.clubId).name}.`)}
   else{m.goals.push({minute:m.minute,teamId:state.clubId,scorerId:scorer.id,assistId:null});m.events.push(`${m.minute}e — BUT ! ${scorer.name} marque pour ${E.club(state.clubId).name}.`)}
 }else if(Math.random()<.28){
   m.events.push(`${m.minute}e — ${target.name} frappe, mais le gardien adverse intervient.`);
 }
 if(Math.random()<.22) opponentSequence();
 matchScreen()
}

function distinctPlayer(xi,excludeIds,preferred){
 const ex=new Set(Array.isArray(excludeIds)?excludeIds:[excludeIds]);
 const ps=xi.map(E.player).filter(p=>p&&!ex.has(p.id));
 const cand=preferred&&preferred.length?ps.filter(p=>preferred.includes(p.pos)):[];
 return E.rand(cand.length?cand:ps);
}
function pickForAction(xi,type,role){
 const ps=xi.map(E.player).filter(Boolean);
 const prefer= role==="passer"?["CM","DM","AM","RB","LB"]:
               role==="target"?(type==="wing"?["RW","LW","RB","LB"]:type==="middle"?["AM","CM","ST"]:["ST","RW","LW","AM"]):
               ["CB","DM","RB","LB"];
 const cand=ps.filter(p=>prefer.includes(p.pos));return E.rand(cand.length?cand:ps)
}
function opponentSequence(){
 const m=state.match,oppXI=m.userHome?m.awayXI:m.homeXI,userXI=m.userHome?m.homeXI:m.awayXI;
 const oppClub=m.userHome?m.away:m.home;
 const p1=pickForAction(oppXI,"attack","passer");if(!p1)return;
 const p2=distinctPlayer(oppXI,[p1.id],["ST","RW","LW","AM"])||p1;
 const def=pickForAction(userXI,"attack","def")||p2;
 m.events.push(`${m.minute}e — ${p1.name} lance ${p2.name}. ${def.name} recule pour défendre.`);
 const op=E.clubPower(oppClub,oppXI,"Équilibré"),us=E.clubPower(state.clubId,userXI,state.tactic);
 if(Math.random()<E.clamp(.07+(op-us)/180,.03,.18)){
   const s=E.weightedScorer(oppXI),c=E.weightedCreator(oppXI,s.id);
   if(m.userHome)m.ag++;else m.hg++;s.goals++;if(c)c.assists++;
   m.goals.push({minute:m.minute,teamId:oppClub,scorerId:s.id,assistId:c?c.id:null});
   m.events.push(`${m.minute}e — BUT adverse : ${c?c.name+" sert ":""}${s.name}, qui marque pour ${E.club(oppClub).name}.`);
 }
}
function simulateFive(){
 const m=state.match;m.minute=Math.min(90,m.minute+5);
 const hp=E.clubPower(m.home,m.homeXI,m.userHome?state.tactic:"Équilibré"),ap=E.clubPower(m.away,m.awayXI,m.userHome?"Équilibré":state.tactic);
 const homePoss=hp/(hp+ap),home=Math.random()<homePoss,xi=home?m.homeXI:m.awayXI,oppXi=home?m.awayXI:m.homeXI;
 const passer=E.weightedCreator(xi,""),target=E.weightedScorer(xi),def=pickForAction(oppXi,"attack","def");
 if(!passer||!target){m.events.push(`${m.minute}e — Temps faible, aucune occasion nette.`);return}
 const safeDef=def||target;
 m.events.push(`${m.minute}e — ${passer.name} trouve ${target.name}. ${safeDef.name} tente d’intervenir.`);
 if(Math.random()<E.clamp(.08+((home?hp:ap)-(home?ap:hp))/170,.03,.19)){
   if(home)m.hg++;else m.ag++;target.goals++;passer.assists++;
   m.goals.push({minute:m.minute,teamId:home?m.home:m.away,scorerId:target.id,assistId:passer.id});
   m.events.push(`${m.minute}e — BUT ! ${passer.name} délivre la passe décisive et ${target.name} marque pour ${E.club(home?m.home:m.away).name}.`);
 }else{
   const endings=[`${target.name} frappe à côté.`,`${safeDef.name} gagne son duel.`,`Le gardien capte la tentative de ${target.name}.`,`Le centre de ${passer.name} est dégagé.`];
   m.events.push(`${m.minute}e — ${E.rand(endings)}`);
 }
 if(Math.random()<.018){const p=E.player(E.rand([...m.homeXI,...m.awayXI]));if(p){p.injury=1+Math.floor(Math.random()*4);m.injuries.push({minute:m.minute,playerId:p.id,weeks:p.injury});m.events.push(`${m.minute}e — Blessure : ${p.name}, ${p.posFr||E.posFr(p.pos)}.`)}}
}
function simulateWhole(){while(state.match.minute<90)simulateFive()}
function matchTactics(){clear();["Équilibré","Attaque","Défense","Pressing"].forEach(t=>btn(t,()=>{state.tactic=t;matchScreen()}));btn("Retour",matchScreen)}
function subs(){
 clear();const m=state.match,xi=m.userHome?m.homeXI:m.awayXI,bench=E.squad(state.clubId).filter(p=>!xi.includes(p.id)&&!p.injury&&!p.suspension).sort((a,b)=>b.rating-a.rating).slice(0,14);
 text(["Choisis le joueur qui entre."]);bench.forEach(p=>btn(`${p.name} — ${p.posFr||E.posFr(p.pos)} — GEN ${p.rating}`,()=>subOut(p)));btn("Retour",matchScreen)
}
function subOut(inp){
 clear();const m=state.match,xi=m.userHome?m.homeXI:m.awayXI;
 xi.forEach((id,i)=>{const p=E.player(id);if(!p)return;btn(`Sortir ${p.name} — ${p.posFr||E.posFr(p.pos)}`,()=>{xi[i]=inp.id;m.subs.push({minute:m.minute,inId:inp.id,outId:p.id,teamId:state.clubId});m.events.push(`${m.minute}e — Changement : ${inp.name} remplace ${p.name}.`);matchScreen()})});btn("Retour",subs)
}

function matchSummary(m){
 const lines=[`Fin : ${E.club(m.home).name} ${m.hg}-${m.ag} ${E.club(m.away).name}.`];
 if(m.goals.length){
  lines.push("Buteurs :");
  m.goals.sort((a,b)=>a.minute-b.minute).forEach(g=>{
   const s=E.player(g.scorerId),a=g.assistId?E.player(g.assistId):null;
   lines.push(`${g.minute}e — ${s?s.name:"Buteur inconnu"} (${E.club(g.teamId).name})${a?` — passe décisive : ${a.name}`:""}.`);
  });
 }else lines.push("Buteurs : aucun.");
 if(m.subs.length){
  lines.push("Remplacements :");
  m.subs.forEach(x=>{
   const inp=E.player(x.inId),out=E.player(x.outId);
   lines.push(`${x.minute}e — ${inp?inp.name:"Entrant"} remplace ${out?out.name:"Sortant"}.`);
  });
 }
 if(m.injuries.length){
  lines.push("Blessures :");
  m.injuries.forEach(x=>{
   const p=E.player(x.playerId);
   lines.push(`${x.minute}e — ${p?p.name:"Joueur"} : indisponible ${x.weeks} semaine(s).`);
  });
 }
 return lines;
}
function finish(){
 const m=state.match;
 if(state.tournament){
  const T=state.tournament;
  if(T.phase==="league"){
   T.history.push({phase:"Phase de ligue",h:m.home,a:m.away,hg:m.hg,ag:m.ag});tUpdate(T.table,m.home,m.away,m.hg,m.ag);simulateTournamentRound(T.calendar[T.round],T.table,state.clubId);T.round++;
  }else if(T.phase==="group"){
   T.history.push({phase:"Phase de groupes",h:m.home,a:m.away,hg:m.hg,ag:m.ag});const gi=T.groups.findIndex(x=>x.includes(state.clubId));tUpdate(T.groupTables[gi],m.home,m.away,m.hg,m.ag);
   for(let k=0;k<T.groups.length;k++)simulateTournamentRound(T.groupCalendars[k][T.groupRound],T.groupTables[k],state.clubId);T.groupRound++;
  }else if(twoLegTournamentRound(T)){
   const base=T.knockout[T.koRound].find(x=>x.includes(state.clubId));
   if(T.koLeg===1){T.userAggregate={pair:base,score:{[m.home]:m.hg,[m.away]:m.ag}};T.history.push({phase:`${T.koNames[T.koRound]} — aller`,h:m.home,a:m.away,hg:m.hg,ag:m.ag});T.koLeg=2}
   else{const z=T.userAggregate||{pair:base,score:{}};z.score[m.home]=(z.score[m.home]||0)+m.hg;z.score[m.away]=(z.score[m.away]||0)+m.ag;let a=z.pair[0],b=z.pair[1],sa=z.score[a]||0,sb=z.score[b]||0;if(sa===sb){if(Math.random()<.5)sa++;else sb++}const winner=sa>sb?a:b;T.history.push({phase:`${T.koNames[T.koRound]} — retour`,h:m.home,a:m.away,hg:m.hg,ag:m.ag,winner,note:`cumul ${sa}-${sb}`});T.koLeg=1;T.userAggregate=null;if(winner!==state.clubId)T.eliminated=true;else{T.pendingUserWinner=state.clubId;advanceKnockoutRound()}}
  }else{
   if(m.hg===m.ag){if(Math.random()<.5)m.hg++;else m.ag++}T.history.push({phase:T.koNames[T.koRound],h:m.home,a:m.away,hg:m.hg,ag:m.ag});const userWon=(m.userHome?m.hg>m.ag:m.ag>m.hg);if(!userWon)T.eliminated=true;else{T.pendingUserWinner=state.clubId;advanceKnockoutRound()}
  }
  state.match=null;clear();text(matchSummary(m));btn("Continuer la coupe",home);return
 }
 if(state.mode==="quick"){clear();text(matchSummary(m));state.match=null;btn("Rejouer contre le même adversaire",()=>quickPlay(m.userHome?m.home:m.away,m.userHome?m.away:m.home));btn("Retour au menu",()=>{state=fresh(state.legacy);render()});return}
 update(m.home,m.away,m.hg,m.ag);
 [...m.homeXI,...m.awayXI].forEach(id=>{const p=E.player(id);if(p){p.apps++;p.fitness=Math.max(45,p.fitness-(5+Math.floor(Math.random()*8)));p.sharpness=Math.min(100,p.sharpness+2)}});
 state.history.push({week:state.week+1,home:m.home,away:m.away,hg:m.hg,ag:m.ag});
 (state.calendar[state.week]||[]).filter(g=>!g.includes(state.clubId)).forEach(([h,a])=>{const hp=E.clubPower(h,E.autoXI(h,"4-3-3"),"Équilibré"),ap=E.clubPower(a,E.autoXI(a,"4-3-3"),"Équilibré"),sc=E.realisticScore(hp,ap,1.0);update(h,a,sc[0],sc[1])});
 state.week++;tick();state.match=null;clear();text(matchSummary(m));btn("Retour au club",home)
}
function update(h,a,hg,ag){const H=state.table[h],A=state.table[a];if(!H||!A)return;H.p++;A.p++;H.gf+=hg;H.ga+=ag;A.gf+=ag;A.ga+=hg;if(hg>ag){H.w++;A.l++;H.pts+=3}else if(hg<ag){A.w++;H.l++;A.pts+=3}else{H.d++;A.d++;H.pts++;A.pts++}}
function tick(){FOOTBALL_DATA.players.forEach(p=>{if(p.injury)p.injury--;if(p.suspension)p.suspension--;p.fitness=Math.min(100,p.fitness+5+Math.floor(Math.random()*5));p.morale=E.clamp(p.morale-1+Math.floor(Math.random()*3),45,100)})}
function table(){clear();const a=Object.entries(state.table).sort((x,y)=>y[1].pts-x[1].pts||((y[1].gf-y[1].ga)-(x[1].gf-x[1].ga)));text(a.map(([id,r],i)=>`${i+1}. ${E.club(id).name} — ${r.pts} pts — ${r.gf} buts pour, ${r.ga} contre`));btn("Retour",home)}
function calendar(){clear();if(state.tournament){const lines=state.tournament.history.slice(-30).map(x=>`${x.phase} : ${E.club(x.h).name} ${x.hg}-${x.ag} ${E.club(x.a).name}`);text(lines.length?lines:["Aucun match joué."]);btn("Retour",home);return}const lines=state.history.slice(-12).map(x=>`J${x.week} : ${E.club(x.home).name} ${x.hg}-${x.ag} ${E.club(x.away).name}`);const n=nextMatch();if(n)lines.push(`À venir : ${E.club(state.clubId).name} contre ${E.club(n.opponent).name}`);text(lines.length?lines:["Aucun match joué."]);btn("Retour",home)}
function training(){clear();["Technique","Physique","Tactique","Repos"].forEach(x=>btn(x,()=>{E.squad(state.clubId).forEach(p=>{if(x==="Repos")p.fitness=Math.min(100,p.fitness+10);else{p.sharpness=Math.min(100,p.sharpness+5);if(p.age<24&&Math.random()<.025&&p.rating<p.potential)p.rating++}});log(`Entraînement ${x}.`);home()}));btn("Retour",home)}
function transfers(){clear();btn("Rechercher un joueur",searchPlayersForTransfer);btn("Retour",home)}
function searchPlayersForTransfer(){clear();text(["Écris un nom de joueur."]);const i=document.createElement("input");i.placeholder="Nom du joueur";$("actions").appendChild(i);btn("Rechercher",()=>{const q=i.value.trim().toLowerCase();clear();const a=FOOTBALL_DATA.players.filter(p=>!p.nationalCopy&&p.clubId!==state.clubId&&p.name.toLowerCase().includes(q)).slice(0,50);text([`${a.length} résultat(s).`]);a.forEach(p=>btn(`${p.name} — ${p.club} — ${p.posFr||E.posFr(p.pos)} — GEN ${p.rating} — ${E.formatMoney(p.value)}`,()=>offer(p)));btn("Retour",transfers)});btn("Retour",transfers)}
function offer(p){clear();text([p.name,`Club : ${p.club}`,`Poste : ${p.posFr||E.posFr(p.pos)}`,`Valeur : ${E.formatMoney(p.value)}`]);btn(`Offrir ${E.formatMoney(p.value)}`,()=>buy(p,p.value));btn(`Offrir +20 %`,()=>buy(p,Math.round(p.value*1.2)));btn("Retour",transfers)}
function buy(p,fee){if(state.budget<fee){log("Budget insuffisant.");return transfers()}if(fee<p.value*(.92+Math.random()*.28)){log("Offre refusée.");return transfers()}p.clubId=state.clubId;p.club=E.club(state.clubId).name;E.reindexPlayers();state.budget-=fee;normalizeUserXI();log(`${p.name} a signé.`,"good");home()}
function searchMenu(back){clear();text(["Recherche mondiale : club ou joueur."]);const i=document.createElement("input");i.placeholder="Nom";$("actions").appendChild(i);btn("Rechercher",()=>{const q=i.value.trim().toLowerCase();clear();const cs=FOOTBALL_DATA.clubs.filter(c=>c.name.toLowerCase().includes(q)).slice(0,20),ps=FOOTBALL_DATA.profiles.filter(p=>p.name.toLowerCase().includes(q)).slice(0,30);text([`${cs.length} clubs, ${ps.length} joueurs/profils affichés.`]);cs.forEach(c=>btn(`Club : ${c.name} — ${c.countryFr} — ${c.competitionFr}`,()=>playersList(E.squad(c.id),()=>searchMenu(back))));ps.forEach(p=>btn(`Joueur : ${p.name} — ${p.club||"sans club"} — ${p.posFr||E.posFr(p.pos)}`,()=>profileCard(p,()=>searchMenu(back))));btn("Retour",back)});btn("Retour",back)}
function profileCard(p,back){clear();text([p.name,`Club source : ${p.club||"non renseigné"}`,`Poste : ${p.posFr||E.posFr(p.pos)}`,`Âge : ${p.age}`,`Pays : ${p.nation||"Non renseigné"}`]);btn("Retour",back)}
function quickOpponent(id){
 restorePlayerBase();state=fresh(state.legacy);state.mode="quick";state.clubId=id;state.xi=E.autoXI(id,"4-3-3");
 clear();text([`Équipe : ${E.club(id).name}. Choisis un adversaire pour ce match unique.`]);
 const sameComp=FOOTBALL_DATA.clubs.filter(c=>c.id!==id&&c.competitionId&&E.club(id).competitionId&&c.competitionId===E.club(id).competitionId&&E.squad(c.id).length>=18);
 sameComp.slice(0,50).forEach(c=>btn(`${c.name} — même division`,()=>quickPlay(id,c.id)));
 btn("Retour",menu)
}
function quickPlay(a,b){restorePlayerBase();state=fresh(state.legacy);state.mode="quick";state.clubId=a;state.xi=E.autoXI(a,"4-3-3");state.match={home:a,away:b,homeXI:[...state.xi],awayXI:[...E.autoXI(b,"4-3-3")],userHome:true,minute:0,hg:0,ag:0,events:[],momentum:0,goals:[],subs:[],injuries:[]};matchScreen()}
function legacyScreen(){ensureLegacy();clear();let L=state.legacy,lines=[`Prestige : ${L.prestige}.`,`Trophées : ${L.trophies.length}.`];L.trophies.slice().reverse().slice(0,20).forEach(x=>lines.push(`${x.season||"Coupe"} — ${x.name} — ${x.club}.`));if(L.consequences.length){lines.push("Conséquences actives / récentes :");L.consequences.slice().reverse().slice(0,15).forEach(x=>lines.push(x))}if(L.qualifications.length){lines.push("Qualifications gagnées :");L.qualifications.slice().reverse().slice(0,10).forEach(x=>lines.push(x))}text(lines);btn("Retour",state.clubId?home:menu)}
function grantTournamentReward(T){if(T.rewarded)return;T.rewarded=true;const L=ensureLegacy(),R={ucl:{prestige:60,budget:25000000,next:"Qualification automatique pour la prochaine Champions League."},uecl:{prestige:35,budget:10000000,next:"Qualification pour la phase de ligue de l’Europa League suivante."},euro:{prestige:50,budget:0,next:"Champion d’Europe en titre."},worldcup:{prestige:80,budget:0,next:"Champion du monde en titre."}}[T.id]||{prestige:20,budget:0,next:"Champion en titre."};L.trophies.push({name:T.name,club:E.club(state.clubId).name,season:"Coupe"});L.prestige+=R.prestige;L.pendingBudget+=R.budget;if(R.next)L.qualifications.push(R.next);L.consequences.push(`${T.name} gagné : +${R.prestige} prestige${R.budget?`, prime de jeu ${E.formatMoney(R.budget)} disponible lors de la prochaine carrière`:""}. ${R.next}`)}
const FOOTBALL_PROMOTION_RULES={
 "Angleterre|Championship":{up:"Premier League",auto:2,playoff:[3,4,5,6]},"Angleterre|League One":{up:"Championship",auto:2,playoff:[3,4,5,6]},"Angleterre|League Two":{up:"League One",auto:3,playoff:[4,5,6,7]},"Angleterre|National League":{up:"League Two",auto:1,playoff:[2,3,4,5,6,7]},
 "France|Ligue 2":{up:"Ligue 1",auto:2,playoff:[3,4,5]},"France|Ligue 3":{up:"Ligue 2",auto:2,playoff:[3]},
 "Espagne|LaLiga2":{up:"Liga",auto:2,playoff:[3,4,5,6]},
 "Allemagne|2. Bundesliga":{up:"Bundesliga",auto:2,playoff:[3]},"Allemagne|3. Liga":{up:"2. Bundesliga",auto:2,playoff:[3]},
 "Italie|Serie B":{up:"Serie A",auto:2,playoff:[3,4,5,6,7,8]},
 "Portugal|Liga Portugal 2":{up:"Liga Portugal",auto:2,playoff:[3]}
};
const FOOTBALL_RELEGATION_RULES={"Angleterre|Premier League":{down:"Championship",bottom:3},"Angleterre|Championship":{down:"League One",bottom:3},"Angleterre|League One":{down:"League Two",bottom:4},"Angleterre|League Two":{down:"National League",bottom:2},"France|Ligue 1":{down:"Ligue 2",bottom:2,playoffFromBottom:3},"France|Ligue 2":{down:"Ligue 3",bottom:2,playoffFromBottom:3},"Espagne|Liga":{down:"LaLiga2",bottom:3},"Allemagne|Bundesliga":{down:"2. Bundesliga",bottom:2,playoffFromBottom:3},"Allemagne|2. Bundesliga":{down:"3. Liga",bottom:2,playoffFromBottom:3},"Italie|Serie A":{down:"Serie B",bottom:3},"Portugal|Liga Portugal":{down:"Liga Portugal 2",bottom:2,playoffFromBottom:3}};
function applyFootballMovement(pos,total){const L=ensureLegacy(),c=E.club(state.clubId),comp=careerCompetition(),key=`${c.countryFr}|${comp}`,up=FOOTBALL_PROMOTION_RULES[key],down=FOOTBALL_RELEGATION_RULES[key];let target=null,msg=null;if(up&&(pos<=up.auto||(up.playoff||[]).includes(pos)&&Math.random()<.5)){target=up.up;msg=`Promotion : ${c.name} monte de ${comp} en ${target}.`}else if(down&&(pos>total-down.bottom||(down.playoffFromBottom&&pos===total-down.playoffFromBottom+1&&Math.random()<.5))){target=down.down;msg=`Relégation : ${c.name} descend de ${comp} en ${target}.`}if(target){L.careerCompetitionOverrides[state.clubId]=target;L.consequences.push(msg);L.qualifications.push(msg)}return{target,msg}}
function closeCareerSeason(){const L=ensureLegacy(),rank=Object.entries(state.table).sort((a,b)=>b[1].pts-a[1].pts||((b[1].gf-b[1].ga)-(a[1].gf-a[1].ga))),pos=Math.max(1,rank.findIndex(x=>x[0]===state.clubId)+1),name=careerCompetition(),club=E.club(state.clubId).name;let bonus=0,prest=0,msg=`Saison ${state.season} terminée : ${pos}e de ${name}.`;if(pos===1){bonus=15000000;prest=25;L.trophies.push({name:`Champion — ${name}`,club,season:`Saison ${state.season}`});msg+=` Titre gagné, +25 prestige et prime de jeu ${E.formatMoney(bonus)}.`}else if(pos<=4){bonus=5000000;prest=10;msg+=` Top 4 : +10 prestige et prime de jeu ${E.formatMoney(bonus)}.`}L.prestige+=prest;state.budget+=bonus;L.seasonArchive.push({season:state.season,competition:name,position:pos,club});const movement=applyFootballMovement(pos,rank.length);L.consequences.push(msg);return{pos,bonus,movement}}
function nextSeason(){const r=closeCareerSeason();state.season++;initSeason();E.squad(state.clubId).forEach(p=>{p.age++;p.morale=Math.min(100,(p.morale||75)+(r.pos===1?10:r.pos<=4?5:0));p.sharpness=Math.min(100,(p.sharpness||70)+(r.pos===1?5:0));if(p.age<25&&p.rating<p.potential&&Math.random()<.35)p.rating++});ensureLegacy().consequences.push(`Saison ${state.season} : ${r.pos===1?"tu débutes comme champion en titre ; moral de l’effectif renforcé et attentes accrues.":r.pos<=4?"la bonne saison précédente améliore la confiance du groupe.":"aucun bonus de champion à défendre."}`);legacyScreen()}
function save(){capturePlayerState();localStorage.setItem("footballCompletCorrige",JSON.stringify(state));log("Sauvegardé.")}
function load(){const r=localStorage.getItem("footballCompletCorrige");if(!r)return log("Aucune sauvegarde.");try{state=JSON.parse(r);normalizeState();render()}catch(e){log("Sauvegarde invalide.")}}
function exportSave(){capturePlayerState();const b=new Blob([JSON.stringify(state,null,2)],{type:"application/json"}),a=document.createElement("a");a.href=URL.createObjectURL(b);a.download="football-textuel-save.json";a.click()}
function importSave(f){const r=new FileReader();r.onload=()=>{try{state=JSON.parse(r.result);normalizeState();render()}catch(e){log("Fichier invalide.")}};r.readAsText(f)}
function newGame(){restorePlayerBase();state=fresh();render()}
window.__FIFA_PROMO_QA={promotionRules:FOOTBALL_PROMOTION_RULES,relegationRules:FOOTBALL_RELEGATION_RULES,careerCompetition};window.__FIFA_CUP_QA={fresh:()=>fresh(),startCareer,startTournament,tournamentNext,tSort,buildLeagueKnockout,buildGroupKnockout,getState:()=>state,setState:s=>state=s,simFootball,advanceKnockoutRound,grantTournamentReward,closeCareerSeason,nextSeason,ensureLegacy,normalizeState,capturePlayerState,applyPlayerState,restorePlayerBase,leagueClubs,careerCalendar,quickPlay,nextMatch,startMatch,finish,simulateWhole,initSeason,careerCompetition,validSavedXI,normalizeUserXI,lineup,preMatch};
$("saveBtn").onclick=save;$("loadBtn").onclick=load;$("exportBtn").onclick=exportSave;$("importBtn").onclick=()=>$("importFile").click();$("importFile").onchange=e=>{if(e.target.files[0])importSave(e.target.files[0])};$("newBtn").onclick=newGame;
render();
})();