/* Dames New Gen — version hébergement statique (Hostinger) */
/* Pas de build: React, ReactDOM et Tailwind chargés via CDN, JSX transpile via Babel-standalone. */

const { useMemo, useState, useEffect } = React;

// --- Moteur du jeu (identique à la version React, sans import/export) ---
const BOARD_SIZE = 8;
const MAX_TRAPS = 5;
const DARK_SQUARE = (r, c) => (r + c) % 2 === 1;
const DIRS = {
  R: [ [1, -1], [1, 1] ],
  B: [ [-1, -1], [-1, 1] ],
};
const ALL_DIRS = [ [1, -1], [1, 1], [-1, -1], [-1, 1] ];

function cloneBoard(board){
  return board.map(row => row.map(cell => ({
    piece: cell.piece ? { ...cell.piece } : null,
    trap: cell.trap ? { ...cell.trap } : null,
  })));
}

function initBoard(){
  const board = Array.from({length: BOARD_SIZE}, () =>
    Array.from({length: BOARD_SIZE}, () => ({ piece: null, trap: null }))
  );
  for(let r=0; r<3; r++){
    for(let c=0; c<BOARD_SIZE; c++){
      if(DARK_SQUARE(r,c)) board[r][c].piece = { player: 'R', king: false, frozenTurns: 0 };
    }
  }
  for(let r=BOARD_SIZE-3; r<BOARD_SIZE; r++){
    for(let c=0; c<BOARD_SIZE; c++){
      if(DARK_SQUARE(r,c)) board[r][c].piece = { player: 'B', king: false, frozenTurns: 0 };
    }
  }
  return board;
}

function inside(r,c){ return r>=0 && r<BOARD_SIZE && c>=0 && c<BOARD_SIZE; }
function randomChoice(arr){ return arr[Math.floor(Math.random()*arr.length)]; }

function listAllMoves(board, player, forceCaptureOnly=false, fromPos=null){
  const result = new Map();
  let anyCapture = false;
  for(let r=0; r<BOARD_SIZE; r++){
    for(let c=0; c<BOARD_SIZE; c++){
      const cell = board[r][c];
      if(!cell.piece) continue;
      const p = cell.piece;
      if(p.player !== player) continue;
      if(p.frozenTurns && p.frozenTurns>0) continue;
      if(fromPos && (fromPos[0]!==r || fromPos[1]!==c)) continue;
      const dirs = p.king ? ALL_DIRS : DIRS[player];
      const moves = [];
      let hasCapture = false;
      for(const [dr,dc] of dirs){
        const nr = r + dr, nc = c + dc;
        if(inside(nr,nc) && !board[nr][nc].piece && DARK_SQUARE(nr,nc)){
          if(!forceCaptureOnly) moves.push({ to:[nr,nc], capture:null });
        }
        const jr = r + 2*dr, jc = c + 2*dc;
        if(inside(jr,jc) && !board[jr][jc].piece && DARK_SQUARE(jr,jc)){
          const mid = board[nr][nc];
          if(mid?.piece && mid.piece.player !== player){
            moves.push({ to:[jr,jc], capture:{r:nr, c:nc} });
            hasCapture = true;
          }
        }
      }
      if(moves.length){
        result.set(`${r},${c}`, { moves, hasCapture });
        if(hasCapture) anyCapture = true;
      }
    }
  }
  if(anyCapture && forceCaptureOnly){
    for(const [key,val] of result){
      const caps = val.moves.filter(m=>!!m.capture);
      if(caps.length) result.set(key, { moves:caps, hasCapture:true });
      else result.delete(key);
    }
  }
  return { movesByPiece: result, anyCapture };
}

function hasAnyMove(board, player){
  const { movesByPiece } = listAllMoves(board, player, false, null);
  return movesByPiece.size>0;
}

function crownIfNeeded(piece, r){
  if(piece.king) return piece;
  if(piece.player==='R' && r===BOARD_SIZE-1) return { ...piece, king:true };
  if(piece.player==='B' && r===0) return { ...piece, king:true };
  return piece;
}

function countTraps(board){
  let n=0;
  for(let r=0;r<BOARD_SIZE;r++){
    for(let c=0;c<BOARD_SIZE;c++){
      if(board[r][c].trap) n++;
    }
  }
  return n;
}

function placeRandomTrap(board, settings){
  const empty = [];
  for(let r=0;r<BOARD_SIZE;r++){
    for(let c=0;c<BOARD_SIZE;c++){
      const cell = board[r][c];
      if(DARK_SQUARE(r,c) && !cell.piece && !cell.trap) empty.push([r,c]);
    }
  }
  if(!empty.length) return board;
  const [r,c] = randomChoice(empty);
  const type = randomChoice(settings.enabledTraps);
  const nb = cloneBoard(board);
  nb[r][c].trap = { type, ttl: settings.trapTTL };
  return nb;
}

function decayTraps(board){
  const b = cloneBoard(board);
  for(let r=0;r<BOARD_SIZE;r++){
    for(let c=0;c<BOARD_SIZE;c++){
      const t = b[r][c].trap;
      if(t){ t.ttl -= 1; if(t.ttl<=0) b[r][c].trap = null; }
    }
  }
  return b;
}

function reduceFrozenForPlayer(board, player){
  const b = cloneBoard(board);
  for(let r=0;r<BOARD_SIZE;r++){
    for(let c=0;c<BOARD_SIZE;c++){
      const p = b[r][c].piece;
      if(p && p.player===player && p.frozenTurns>0) p.frozenTurns -= 1;
    }
  }
  return b;
}

function applyTrapOnLanding(board, r, c){
  const b = cloneBoard(board);
  const cell = b[r][c];
  const trap = cell.trap;
  if(!trap) return { board:b, effect:null, pieceSurvived:true, consumed:false };
  const piece = cell.piece;
  if(!piece) return { board:b, effect:null, pieceSurvived:true, consumed:false };
  let effect = null;
  if(trap.type==='bombe'){
    cell.piece = null; effect = '💥 Bombe : la pièce est détruite';
  } else if(trap.type==='glace'){
    cell.piece = { ...piece, frozenTurns: (piece.frozenTurns||0)+1 }; effect = '🧊 Glace : la pièce est gelée 1 tour';
  } else if(trap.type==='teleport'){
    const empty = [];
    for(let rr=0; rr<BOARD_SIZE; rr++){
      for(let cc=0; cc<BOARD_SIZE; cc++){
        if(DARK_SQUARE(rr,cc) && !b[rr][cc].piece && !(rr===r && cc===c)) empty.push([rr,cc]);
      }
    }
    if(empty.length){
      const [tr,tc] = randomChoice(empty);
      b[tr][tc].piece = piece; cell.piece = null; effect = '🌀 Téléporteur : la pièce a été déplacée';
    } else {
      effect = '🌀 Téléporteur : aucune case libre, aucun effet';
    }
  }
  cell.trap = null;
  return { board:b, effect, pieceSurvived: !!b[r][c].piece, consumed:true };
}

// --- Application React ---
function App(){
  const [theme, setTheme] = useState('dark');
  const [board, setBoard] = useState(()=>initBoard());
  const [current, setCurrent] = useState('R');
  const [selected, setSelected] = useState(null);
  const [forcedFrom, setForcedFrom] = useState(null);
  const [mustCapture, setMustCapture] = useState(true);
  const [turnCount, setTurnCount] = useState(1);
  const [log, setLog] = useState(['🎮 Nouvelle partie — Rouge commence']);
  const [settings, setSettings] = useState({ trapTTL:6, trapsPerTurn:1, enabledTraps:['bombe','glace','teleport'] });
  const [trapSpawnLocked, setTrapSpawnLocked] = useState(false);

  const tv = useMemo(()=>{
    switch(theme){
      case 'dark': return {
        containerBg: 'bg-gradient-to-b from-slate-950 via-slate-900 to-slate-900',
        containerText: 'text-slate-100',
        squareLight: 'bg-slate-600',
        squareDark: 'bg-slate-800',
        boardBorder: 'border-slate-700',
        boardBg: 'bg-slate-900',
        panelBg: 'bg-white/5 backdrop-blur-lg',
        panelBorder: 'border border-white/10',
        moveRing: 'ring-cyan-300',
        inputBg: 'bg-slate-800 border border-white/10',
        pieceRed: 'bg-rose-400',
        pieceGreen: 'bg-emerald-400',
        pieceRing: 'ring-white/90',
        footer: 'Mode sombre',
      };
      case 'neon': return {
        containerBg: 'bg-[#050914]',
        containerText: 'text-[#e6f3ff]',
        squareLight: 'bg-[#1a2a4a]',
        squareDark: 'bg-[#0e1b34]',
        boardBorder: 'border-[#243253]',
        boardBg: 'bg-[#0a1228]',
        panelBg: 'bg-white/5 backdrop-blur-lg',
        panelBorder: 'border border-[#223559]/60',
        moveRing: 'ring-[#00e5ff]',
        inputBg: 'bg-[#13223f] border border-[#223559]/60',
        pieceRed: 'bg-[#ff3b6b]',
        pieceGreen: 'bg-[#19d38a]',
        pieceRing: 'ring-white/90',
        footer: 'Mode néon',
      };
      default: return {
        containerBg: 'bg-gradient-to-b from-white to-slate-100',
        containerText: 'text-slate-900',
        squareLight: 'bg-white',
        squareDark: 'bg-slate-600',
        boardBorder: 'border-slate-300',
        boardBg: 'bg-slate-50',
        panelBg: 'bg-white/80 backdrop-blur-md',
        panelBorder: 'border border-slate-300',
        moveRing: 'ring-sky-500',
        inputBg: 'bg-white border border-slate-300',
        pieceRed: 'bg-red-600',
        pieceGreen: 'bg-green-600',
        pieceRing: 'ring-black/20',
        footer: 'Mode clair',
      };
    }
  }, [theme]);

  const baseMoves = useMemo(()=>listAllMoves(board, current, false, forcedFrom), [board, current, forcedFrom]);
  const { movesByPiece, anyCapture } = useMemo(()=>{
    if(!mustCapture || !baseMoves.anyCapture) return baseMoves;
    const filtered = new Map();
    for(const [k,v] of baseMoves.movesByPiece){
      const only = v.moves.filter(m=>!!m.capture);
      if(only.length) filtered.set(k, { moves: only, hasCapture:true });
    }
    return { movesByPiece:filtered, anyCapture:true };
  }, [baseMoves, mustCapture]);

  const gameOver = useMemo(()=>!hasAnyMove(board, current), [board, current]);

  function reset(){
    setBoard(initBoard());
    setCurrent('R');
    setSelected(null);
    setForcedFrom(null);
    setTurnCount(1);
    setLog(['🎮 Nouvelle partie — Rouge commence']);
    setTrapSpawnLocked(false);
  }

  function onSquareClick(r,c){
    if(gameOver) return;
    const cell = board[r][c];
    if(cell.piece && cell.piece.player===current){
      if(cell.piece.frozenTurns && cell.piece.frozenTurns>0) return;
      if(forcedFrom && (forcedFrom[0]!==r || forcedFrom[1]!==c)) return;
      setSelected([r,c]); return;
    }
    if(selected){
      const entry = movesByPiece.get(`${selected[0]},${selected[1]}`);
      if(!entry) return;
      const move = entry.moves.find(m=>m.to[0]===r && m.to[1]===c);
      if(!move) return;
      doMove(selected[0], selected[1], r, c, move.capture);
    }
  }

  function doMove(sr,sc,tr,tc,capture){
    let b = cloneBoard(board);
    const moving = b[sr][sc].piece;
    if(!moving) return;
    b[sr][sc].piece = null;
    if(capture) b[capture.r][capture.c].piece = null;
    b[tr][tc].piece = crownIfNeeded(moving, tr);
    let chain = false;
    if(capture){
      const nm = listAllMoves(b, current, true, [tr,tc]);
      const ent = nm.movesByPiece.get(`${tr},${tc}`);
      chain = nm.anyCapture && !!ent && ent.moves.some(m=>m.capture);
    }
    let trapEffect = null, survived = true, consumedTrap = false;
    if(b[tr][tc].trap){
      const res = applyTrapOnLanding(b, tr, tc);
      b = res.board; trapEffect = res.effect; survived = res.pieceSurvived; consumedTrap = res.consumed;
      chain = chain && survived;
    }
    if(consumedTrap) setTrapSpawnLocked(false);
    if(chain){
      setBoard(b); setSelected([tr,tc]); setForcedFrom([tr,tc]);
      if(trapEffect) setLog(l=>[`⚠️ ${trapEffect}`, ...l]);
      return;
    }
    endTurn(b, trapEffect);
  }

  function endTurn(boardAfterMove, trapEffect){
    let b = boardAfterMove;
    b = decayTraps(b);
    const currentCount = countTraps(b);
    let toAdd = 0;
    if(!trapSpawnLocked){
      const free = Math.max(0, MAX_TRAPS - currentCount);
      toAdd = Math.min(settings.trapsPerTurn, free);
    }
    for(let i=0;i<toAdd;i++) b = placeRandomTrap(b, settings);
    if(countTraps(b) >= MAX_TRAPS){ if(!trapSpawnLocked) setTrapSpawnLocked(true); }
    const next = current==='R' ? 'B' : 'R';
    b = reduceFrozenForPlayer(b, next);
    const msg = trapEffect ? `🧭 Tour ${turnCount} terminé (${current==='R'?'Rouge':'Noir'}) · ${trapEffect}` : `🧭 Tour ${turnCount} terminé (${current==='R'?'Rouge':'Noir'})`;
    setBoard(b); setCurrent(next); setSelected(null); setForcedFrom(null); setTurnCount(t=>t+1); setLog(l=>[msg, ...l]);
  }

  const playableKeys = useMemo(()=>new Set(movesByPiece.keys()), [movesByPiece]);
  const hint = useMemo(()=>{
    if(gameOver) return `Partie terminée — ${(current==='R'?'Rouge':'Noir')} ne peut plus jouer`;
    const nb = countTraps(board);
    const lock = (trapSpawnLocked && nb>=MAX_TRAPS) ? " · limite de pièges atteinte (nouveaux pièges bloqués jusqu'à activation)" : "";
    return `Au tour de ${(current==='R'?'Rouge':'Noir')}${(mustCapture && anyCapture ? ' · prise obligatoire' : '')} · Pièges: ${nb}/${MAX_TRAPS}${lock}`;
  }, [board, current, mustCapture, anyCapture, gameOver, trapSpawnLocked]);

  const squares = useMemo(()=>{
    return Array.from({length:BOARD_SIZE}).flatMap((_,r)=>
      Array.from({length:BOARD_SIZE}).map((_,c)=>{
        const dark = DARK_SQUARE(r,c);
        const cell = board[r][c];
        const key = `${r},${c}`;
        const isSelected = selected && selected[0]===r && selected[1]===c;
        const entry = movesByPiece.get(selected ? `${selected[0]},${selected[1]}` : "");
        const canGo = entry ? entry.moves.some(m=>m.to[0]===r && m.to[1]===c) : false;
        const isPlayablePiece = cell.piece && cell.piece.player===current && playableKeys.has(key) && (!(cell.piece.frozenTurns>0));
        return (
          <button key={key} onClick={()=>onSquareClick(r,c)}
            className={
              `relative w-16 h-16 md:w-20 md:h-20 flex items-center justify-center transition `+
              `${dark ? tv.squareDark : tv.squareLight} `+
              `${canGo ? ('ring-4 ' + tv.moveRing + ' ring-offset-2 ring-offset-transparent') : ''} `+
              `${isSelected ? 'outline outline-4 outline-amber-300' : ''} `+
              `${isPlayablePiece ? 'outline outline-4 outline-amber-300' : ''}`
            }
            aria-label={`case ${r+1},${c+1}`}>
            {cell.trap && (
              <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
                {cell.trap.type==='bombe' && <span className="text-xl">💣</span>}
                {cell.trap.type==='glace' && <span className="text-xl">🧊</span>}
                {cell.trap.type==='teleport' && <span className="text-xl">🌀</span>}
                <span className="absolute bottom-0 right-0 text-[10px] md:text-xs bg-black/60 px-1 rounded">{cell.trap.ttl}</span>
              </div>
            )}
            {cell.piece && (
              <div className={
                `relative rounded-full w-12 h-12 md:w-14 md:h-14 shadow-xl ring-2 ${tv.pieceRing} `+
                `${cell.piece.player==='R' ? tv.pieceRed : tv.pieceGreen} `+
                `${cell.piece.frozenTurns>0 ? 'opacity-60' : ''}`
              }>
                {cell.piece.king && (<span className="absolute inset-0 flex items-center justify-center text-xl md:text-2xl">👑</span>)}
                {cell.piece.frozenTurns>0 && (<span className="absolute -top-2 -right-2 text-sm">❄️</span>)}
              </div>
            )}
          </button>
        );
      })
    );
  }, [board, movesByPiece, playableKeys, selected, tv]);

  useEffect(()=>{
    try{
      const b0 = initBoard();
      let rCount=0, bCount=0;
      for(let r=0;r<BOARD_SIZE;r++){ for(let c=0;c<BOARD_SIZE;c++){ const p=b0[r][c].piece; if(p){ if(p.player==='R') rCount++; else bCount++; } } }
      console.assert(rCount===12 && bCount===12, 'Init: 12 rouges et 12 noirs');
    }catch(e){ console.warn('Tests exception', e); }
  },[]);

  return (
    <div className={`w-full min-h-screen ${tv.containerBg} ${tv.containerText} flex flex-col items-center py-6`}>
      <h1 className="text-3xl md:text-4xl font-extrabold tracking-tight mb-2">Dames New Gen</h1>
      <p className="opacity-90 text-sm md:text-base mb-4">Version 8×8 • Rouge commence • Limite 5 pièges</p>
      <div className="flex flex-col md:flex-row gap-6 w-full max-w-6xl px-4">
        <div className="flex flex-col items-center">
          <div className={`grid grid-cols-8 border-[10px] ${tv.boardBorder} rounded-3xl overflow-hidden shadow-[0_20px_50px_rgba(0,0,0,0.5)] ${tv.boardBg}`}>
            {squares}
          </div>
          <div className="mt-4 text-sm grid grid-cols-2 gap-3 w-full">
            <div className={`${tv.panelBg} ${tv.panelBorder} rounded-3xl p-4`}>
              <div className="font-semibold mb-1">Légende pièges</div>
              <div className="flex gap-3 flex-wrap opacity-90">
                <span>💣 Bombe = détruit</span>
                <span>🧊 Glace = gel 1 tour</span>
                <span>🌀 Téléporteur = déplacement</span>
              </div>
            </div>
            <div className={`${tv.panelBg} ${tv.panelBorder} rounded-3xl p-4`}>
              <div className="font-semibold mb-1">État</div>
              <div className="opacity-90">{hint}</div>
            </div>
          </div>
          <div className="mt-3 flex gap-2">
            <button onClick={reset} className="px-4 py-2 rounded-xl bg-gradient-to-r from-sky-500 to-cyan-400 hover:from-sky-600 hover:to-cyan-500 text-white shadow-lg">Nouvelle partie</button>
          </div>
        </div>
        <div className="flex-1 grid gap-4 content-start">
          <div className={`${tv.panelBg} ${tv.panelBorder} rounded-3xl p-5`}>
            <div className="font-semibold mb-2 flex items-center justify-between">
              <span>Options</span>
              <div className="flex items-center gap-2 text-xs">
                <label className="flex items-center gap-1">
                  Thème
                  <select value={theme} onChange={e=>setTheme(e.target.value)} className={`px-2 py-1 rounded ${tv.inputBg}`}>
                    <option value="light">Clair</option>
                    <option value="dark">Sombre</option>
                    <option value="neon">Néon</option>
                  </select>
                </label>
              </div>
            </div>
            <div className="space-y-3 text-sm">
              <label className="flex items-center gap-2">
                <input type="checkbox" className="accent-sky-400" checked={mustCapture} onChange={e=>setMustCapture(e.target.checked)}/>
                Prise obligatoire
              </label>
              <div className="grid grid-cols-2 gap-3">
                <label className="flex items-center gap-2">TTL des pièges (tours)
                  <input type="number" min={1} max={20} value={settings.trapTTL} onChange={e=>setSettings(s=>({...s, trapTTL: Math.max(1, Math.min(20, Number(e.target.value)||6))}))} className={`${tv.inputBg} rounded px-2 py-1 w-20`} />
                </label>
                <label className="flex items-center gap-2">Pièges / tour
                  <input type="number" min={0} max={3} value={settings.trapsPerTurn} onChange={e=>setSettings(s=>({...s, trapsPerTurn: Math.max(0, Math.min(3, Number(e.target.value)||1))}))} className={`${tv.inputBg} rounded px-2 py-1 w-20`} />
                </label>
              </div>
              <div>
                <div className="mb-1">Types de pièges actifs</div>
                <div className="flex gap-4 flex-wrap">
                  {['bombe','glace','teleport'].map(t => (
                    <label key={t} className="flex items-center gap-2">
                      <input type="checkbox" className="accent-sky-400" checked={settings.enabledTraps.includes(t)} onChange={(e)=>{
                        setSettings(s=>{
                          const set = new Set(s.enabledTraps);
                          if(e.target.checked) set.add(t); else set.delete(t);
                          const arr = Array.from(set);
                          return { ...s, enabledTraps: arr.length?arr:['bombe'] };
                        });
                      }} />
                      {t==='bombe'?'💣 Bombe': t==='glace'?'🧊 Glace':'🌀 Téléport'}
                    </label>
                  ))}
                </div>
              </div>
            </div>
          </div>
          <div className={`${tv.panelBg} ${tv.panelBorder} rounded-3xl p-5`}>
            <div className="font-semibold mb-2">Journal</div>
            <div className="space-y-2 max-h-[360px] overflow-auto pr-1 text-sm">
              {log.map((line, idx) => (<div key={idx} className="opacity-90">{line}</div>))}
            </div>
          </div>
          <div className={`${tv.panelBg} ${tv.panelBorder} rounded-3xl p-5 text-sm opacity-90`}>
            <div className="font-semibold mb-1">Astuce</div>
            <p>Les pièces jouables sont soulignées par un contour ambre. Les cases de destination s'illuminent en bleu. À 5 pièges, le spawn est bloqué jusqu'à ce que quelqu'un tombe dans un piège.</p>
          </div>
        </div>
      </div>
      <footer className="mt-6 opacity-60 text-xs">Prototype frontend — sans IA ni multijoueur. {tv.footer}. Optimisé pour desktop.</footer>
    </div>
  );
}

// Démarrage
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
