/* GavelDuel — vista de comparación A/B.
   Sin engine local: cada acción (vote/skip) es POST al backend, que devuelve el siguiente par.
*/
const { useState: gdUseState, useEffect: gdUseEffect, useRef: gdUseRef } = React;

function GavelDuel({ group, onOpenDetail, onBack }) {
  const [loading, setLoading] = gdUseState(true);
  const [prev, setPrev] = gdUseState(null);   // proyecto anterior (puede ser null en la 1ª)
  const [current, setCurrent] = gdUseState(null);
  const [done, setDone] = gdUseState(false);
  const [decision, setDecision] = gdUseState(null); // "left" | "right" | null
  // progress viene del servidor: { seen_unique, total_projects, comparisons_done, recommended_target, phase }
  const [progress, setProgress] = gdUseState(null);
  const [err, setErr] = gdUseState(null);
  const [showFirst, setShowFirst] = gdUseState(false);
  const [firstSecond, setFirstSecond] = gdUseState(null); // 2º proyecto para la 1ª comparación

  gdUseEffect(() => {
    let cancelled = false;
    if (!group?.id) return;
    setLoading(true);
    window.API.getNextPair(group.id)
      .then((d) => {
        if (cancelled) return;
        if (d.progress) setProgress(d.progress);
        if (d.done) { setDone(true); setLoading(false); return; }
        setPrev(d.prev || null);
        setCurrent(d.next || null);
        setLoading(false);
        if (!d.prev && d.next) {
          fetchSecondForFirst(d.next.id);
        }
      })
      .catch((e) => { if (!cancelled) { setErr(e.message); setLoading(false); } });
    return () => { cancelled = true; };
  }, [group?.id]);

  // Pedir un segundo proyecto distinto para arrancar la 1ª comparación.
  // Reusamos getNextPair: si seguimos sin prev, devolverá un proyecto distinto al actual con probabilidad alta.
  // Más fiable: hacemos un POST de skip ficticio? No — más sencillo: volvemos a llamar getNextPair y comparamos.
  function fetchSecondForFirst(currentId) {
    // pequeño retry hasta conseguir uno distinto
    let attempts = 0;
    function tryOnce() {
      attempts++;
      window.API.getNextPair(group.id).then((d) => {
        if (d.done || !d.next) return;
        if (d.next.id !== currentId) {
          setFirstSecond(d.next);
          setShowFirst(true);
        } else if (attempts < 4) {
          tryOnce();
        }
      }).catch(()=>{});
    }
    tryOnce();
  }

  function applyServerNext(d) {
    if (d.progress) setProgress(d.progress);
    if (d.done) {
      setDone(true);
      setPrev(null);
      setCurrent(null);
    } else {
      setPrev(d.prev || null);
      setCurrent(d.next || null);
    }
  }

  async function vote(side) {
    if (!current || decision || !group?.id) return;
    if (showFirst) return; // primera comparación gestionada aparte
    if (!prev) return; // sin prev no hay duel, debería entrar en first-pair

    const winner = side === "left" ? prev : current;
    const loser  = side === "left" ? current : prev;
    setDecision(side);

    try {
      const d = await window.API.vote(group.id, winner.id, loser.id);
      // pequeña pausa para la animación
      setTimeout(() => {
        applyServerNext(d);
        setDecision(null);
      }, 320);
    } catch (e) {
      setErr(e.message);
      setDecision(null);
    }
  }

  async function firstPairChoose(winnerSide) {
    if (!firstSecond || !current || !group?.id) return;
    const a = firstSecond;
    const b = current;
    const winner = winnerSide === "a" ? a : b;
    const loser  = winnerSide === "a" ? b : a;

    setDecision(winnerSide === "a" ? "left" : "right");
    try {
      // Primera vez: el backend espera prev=null. Forzamos a winner como "current" y loser como "prev"
      // re-marcando con upsertJudgeState mediante una llamada manual seguida de vote.
      // Más simple: llamamos directamente vote(winner, loser) — el server lo registrará y
      // moverá `prev` a winner en el state del juez.
      const d = await window.API.vote(group.id, winner.id, loser.id);
      setTimeout(() => {
        setShowFirst(false);
        setFirstSecond(null);
        applyServerNext(d);
        setDecision(null);
      }, 320);
    } catch (e) {
      setErr(e.message);
      setDecision(null);
    }
  }

  async function skip() {
    if (!current || !group?.id) return;
    try {
      const d = await window.API.skip(group.id, current.id);
      if (d.progress) setProgress(d.progress);
      if (d.done) { setDone(true); setPrev(null); setCurrent(null); }
      else { setPrev(d.prev || null); setCurrent(d.next || null); }
    } catch (e) {
      setErr(e.message);
    }
  }

  if (loading) {
    return (
      <>
        <DuelHeader group={group} onBack={onBack}/>
        <div style={{padding:"60px 20px", textAlign:"center", color:"var(--ink-500)"}}>Cargando par…</div>
      </>
    );
  }

  if (err) {
    return (
      <>
        <DuelHeader group={group} onBack={onBack}/>
        <div style={{padding:"32px var(--app-pad)"}}>
          <div className="alert alert-danger">{err}</div>
        </div>
      </>
    );
  }

  if (done) {
    return (
      <>
        <DuelHeader group={group} onBack={onBack}/>
        <ProgressBlock progress={progress}/>
        <main style={{padding:"60px 20px", textAlign:"center"}}>
          <div style={{
            width:80, height:80, borderRadius:999,
            background:"var(--gradient-brand)",
            display:"inline-flex", alignItems:"center", justifyContent:"center",
            color:"white", marginBottom:16
          }}>
            <Icon.Sparkles width="40" height="40"/>
          </div>
          <h2 className="t-h1" style={{marginBottom:8}}>¡Has comparado todos los pares!</h2>
          <p className="t-body" style={{color:"var(--ink-600)", marginBottom:24}}>
            {progress
              ? `Has hecho ${progress.comparisons_done} comparaciones en este grupo. Ya no hay más pares nuevos que ofrecerte.`
              : "Ya no hay más pares nuevos que ofrecerte en este grupo."}
            <br/>¡Gracias! Vuelve a la lista de grupos para seguir evaluando.
          </p>
          <div style={{display:"flex", gap:10, justifyContent:"center", flexWrap:"wrap"}}>
            <button className="btn btn-primary btn-lg" onClick={onBack}>Volver a grupos</button>
          </div>
        </main>
      </>
    );
  }

  // Caso 1ª comparación: dos cards al mismo nivel
  if (showFirst && current && firstSecond) {
    return (
      <>
        <header className="appbar">
          <button className="iconbtn" onClick={onBack}><Icon.ArrowLeft/></button>
          <div style={{flex:1, textAlign:"center"}}>
            <div className="t-eyebrow" style={{color:"var(--brand-magenta)"}}>Primera comparación</div>
            <div className="appbar-title">Elige tu favorito</div>
          </div>
        </header>
        <ProgressBlock progress={progress}/>
        <div style={{padding:"12px var(--app-pad) 0"}}>
          <div className="alert alert-info">
            <Icon.Info width="20" height="20"/>
            <div>
              <b>Bienvenido.</b><br/>
              En tu primera comparación de este grupo no hay un "favorito anterior".
              Elige el que te guste más entre estos dos para empezar.
            </div>
          </div>
        </div>
        <main style={{padding:"16px var(--app-pad) 100px"}}>
          <div className="duel-grid">
            <DuelCard proj={firstSecond} role="actual" voteLabel="Me gusta más"
              onView={() => onOpenDetail(firstSecond.id)} onVote={() => firstPairChoose("a")}
              dim={decision === "right"} winner={decision === "left"}
              groupHint={{category: group?.category, stage: group?.stage}}/>
            <div className="duel-vs"><span>VS</span></div>
            <DuelCard proj={current} role="actual" voteLabel="Me gusta más"
              onView={() => onOpenDetail(current.id)} onVote={() => firstPairChoose("b")}
              dim={decision === "left"} winner={decision === "right"}
              groupHint={{category: group?.category, stage: group?.stage}}/>
          </div>
        </main>
      </>
    );
  }

  // Caso normal: prev (anterior favorito) vs current
  return (
    <>
      <DuelHeader group={group} onBack={onBack}/>

      <ProgressBlock progress={progress}/>

      <main className="duel" style={{padding:"16px var(--app-pad) 100px"}}>
        <div className="duel-grid">
          <DuelCard proj={prev} role="anterior"
            dim={decision === "right"} winner={decision === "left"}
            onView={prev ? () => onOpenDetail(prev.id) : null}
            onVote={() => vote("left")}
            voteLabel={prev ? "Me gusta más" : "—"}
            disabled={!prev}
            groupHint={{category: group?.category, stage: group?.stage}}/>
          <div className="duel-vs" aria-hidden="true"><span>VS</span></div>
          <DuelCard proj={current} role="actual"
            dim={decision === "left"} winner={decision === "right"}
            onView={() => onOpenDetail(current.id)}
            onVote={() => vote("right")}
            voteLabel="Me gusta más"
            groupHint={{category: group?.category, stage: group?.stage}}/>
        </div>

        <div style={{display:"flex", gap:10, marginTop:18, justifyContent:"center"}}>
          <button className="btn btn-ghost btn-sm" onClick={skip}>
            <Icon.Skip width="16" height="16"/> No conozco / saltar
          </button>
        </div>

        <div style={{marginTop:24}}>
          <details style={{borderRadius:"var(--r-md)", border:"1px solid var(--ink-100)", padding:"12px 14px", background:"var(--white)"}}>
            <summary style={{cursor:"pointer", fontSize:"var(--fs-sm)", color:"var(--ink-600)", fontWeight:600, listStyle:"none", display:"flex", alignItems:"center", gap:8}}>
              <Icon.Info width="16" height="16"/> ¿Cómo funciona la evaluación?
            </summary>
            <p className="t-caption" style={{marginTop:10}}>
              No puntúas proyectos, los <b>comparas</b>. En cada pantalla mantienes tu <b>favorito anterior</b> y lo enfrentas a uno nuevo. El sistema (Crowd-BT) usa tus elecciones para construir un ranking robusto entre todos los mentores. Si no conoces uno, sáltalo: te traerá otro.
            </p>
          </details>
        </div>
      </main>
    </>
  );
}

/**
 * Barra de progreso del juez en el grupo. Cambia de fase a medida que avanza:
 *   - exploring: aún no ha visto todos los proyectos al menos una vez.
 *   - refining:  ya los vio todos pero no llegó al objetivo recomendado (≈3·N).
 *   - saturated: superó el objetivo, su voto sigue contando pero rinde poco.
 */
function ProgressBlock({ progress }) {
  if (!progress) return null;
  const {
    seen_unique = 0,
    total_projects = 0,
    comparisons_done = 0,
    recommended_target = 0,
    phase = "exploring",
  } = progress;

  let pct, label, headline, subline, accent;
  if (phase === "exploring") {
    pct = total_projects ? Math.min(100, Math.round((seen_unique / total_projects) * 100)) : 0;
    label = `${seen_unique}/${total_projects}`;
    headline = "Conociendo el grupo";
    subline = `Has visto ${seen_unique} de ${total_projects} proyectos.`;
    accent = "var(--ink-600)";
  } else if (phase === "refining") {
    pct = recommended_target ? Math.min(100, Math.round((comparisons_done / recommended_target) * 100)) : 0;
    label = `${comparisons_done}/${recommended_target}`;
    headline = "Afinando el ranking";
    subline = `Ya has visto los ${total_projects} proyectos. Sigue comparando para afinar el ranking.`;
    accent = "var(--brand-magenta)";
  } else { // saturated
    pct = 100;
    label = `${comparisons_done}`;
    headline = "Objetivo alcanzado · ¡gracias!";
    subline = `Has hecho ${comparisons_done} comparaciones. Cada voto extra sigue contando, pero el ranking ya es muy estable.`;
    accent = "var(--success)";
  }

  return (
    <div style={{ padding: "10px var(--app-pad) 0" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 4 }}>
        <span className="t-eyebrow" style={{ color: accent, fontWeight: 700 }}>
          {phase === "saturated" && <Icon.Check width="14" height="14"/>} {headline}
        </span>
        <span className="t-caption" style={{ marginLeft: "auto", fontWeight: 700, color: "var(--ink-700)" }}>
          {label}
        </span>
      </div>
      <div className="progress">
        <span style={{ width: `${pct}%` }}/>
      </div>
      <div className="t-caption" style={{ marginTop: 6, color: "var(--ink-600)" }}>
        {subline}
      </div>
    </div>
  );
}

function DuelHeader({ group, onBack }) {
  const cat = group ? window.MENTORES_DATA.CATEGORIES[group.category] : null;
  const stg = group ? window.MENTORES_DATA.STAGES[group.stage] : null;
  return (
    <header className="appbar">
      <button className="iconbtn" onClick={onBack} aria-label="Volver"><Icon.ArrowLeft/></button>
      <div style={{flex:1, textAlign:"center"}}>
        <div className="t-eyebrow" style={{color:"var(--ink-500)"}}>
          {cat ? cat.label : ""}{cat && stg ? " · " : ""}{stg ? stg.label : ""}
        </div>
        <div className="appbar-title">¿Cuál te gusta más?</div>
      </div>
      {/* Espaciador para mantener el título centrado (antes era el icono Trofeo→Ranking, ahora oculto). */}
      <div style={{width:40, height:40}} aria-hidden="true"/>
    </header>
  );
}

function DuelCard({ proj, role, onView, onVote, voteLabel, disabled, dim, winner, groupHint }) {
  if (!proj) {
    return (
      <div className="duel-card duel-card-empty">
        <div className="t-caption" style={{textAlign:"center", padding:"40px 20px"}}>
          {role === "anterior" ? "Aún no hay anterior favorito" : "—"}
        </div>
      </div>
    );
  }
  const cat = window.MENTORES_DATA.CATEGORIES[groupHint?.category];
  return (
    <article className={`duel-card ${dim ? "is-dim" : ""} ${winner ? "is-winner" : ""}`}>
      <ProjectPoster project={proj} categoryHint={groupHint?.category} stageHint={groupHint?.stage}/>
      <div className="duel-body">
        <h3 className="duel-title">{proj.name}</h3>
        {proj.equipo && <p className="t-caption" style={{marginBottom:6}}>{proj.equipo}{proj.location ? ` · ${proj.location}` : ""}</p>}
        {proj.description && <p className="duel-pitch">{proj.description}</p>}
        <div className="proj-actions">
          {proj.project_url && (
            <a className="proj-action" href={proj.project_url} target="_blank" rel="noreferrer"
               aria-label="Ver proyecto en itch.io" title="Ver proyecto en itch.io"
               onClick={(e)=>e.stopPropagation()}
               style={{fontSize:18, lineHeight:1, textDecoration:"none"}}>🔎</a>
          )}
          {proj.video_url && (
            <a className="proj-action" href={proj.video_url} target="_blank" rel="noreferrer"
               aria-label="Ver vídeo" title="Ver vídeo"
               onClick={(e)=>e.stopPropagation()}
               style={{fontSize:18, lineHeight:1, textDecoration:"none"}}>📸</a>
          )}
        </div>
      </div>
      <button className="duel-vote" onClick={onVote} disabled={disabled} style={cat ? {background: cat.color} : null}>
        <Icon.Check width="18" height="18"/> {voteLabel}
      </button>
    </article>
  );
}

window.GavelDuel = GavelDuel;
