/* ============================================================
   Level-Up Wizard — modal overlay for the character sheet
   Props: { char, patch, onClose }
   ============================================================ */

function LevelUpWizard({ char, patch, onClose }){
  const mcs = char.multiclasses || [];
  const isMulticlass = mcs.length > 0;

  /* ---- state ---- */
  const [targetClassKey, setTargetClassKey] = React.useState(isMulticlass ? null : char.classKey);
  const [step, setStep]             = React.useState(isMulticlass ? 0 : 1);
  const [hpGained, setHpGained]     = React.useState(null);
  const [rolledDie, setRolledDie]   = React.useState(null);
  const [subchosen, setSubchosen]     = React.useState(null);
  const [subChoices, setSubChoices]   = React.useState({});
  const [bmNewManeuvers, setBmNewManeuvers] = React.useState([]);
  const [levelChoice, setLevelChoice] = React.useState(null);

  /* ---- derived from target class ---- */
  const targetCls   = targetClassKey ? DND.klass(targetClassKey) : null;
  const isPrimary   = targetClassKey === char.classKey;
  const curClassLv  = isPrimary
    ? (char.level || 1)
    : ((mcs.find(m => m.classKey === targetClassKey) || {}).level || 0);
  const newClassLv  = curClassLv + 1;
  const newTotalLv  = DND.totalLevel(char) + 1;

  const curSubclass = isPrimary
    ? char.subclass
    : (mcs.find(m => m.classKey === targetClassKey) || {}).subclass;

  const needsSubclass = newClassLv >= DND.SUBCLASS_LEVEL && !curSubclass;
  const isAsiLevel    = targetClassKey ? DND.asiLevelsFor(targetClassKey).includes(newClassLv) : false;
  // Battle Master gains maneuvers at specific level thresholds
  const needsBMManeuvers = !needsSubclass && curSubclass === "battlemaster" && [7, 10, 15].includes(newClassLv);

  const sc      = DND.finalScores(char);
  const conMod  = DND.mod(sc.con);
  const hd      = targetCls ? targetCls.hd : 8;
  const avgGain = Math.max(1, Math.floor(hd / 2) + 1 + conMod);

  /* ---- steps ---- */
  const steps = React.useMemo(() => {
    if (isMulticlass && !targetClassKey) return ["class"];
    const s = isMulticlass ? ["class"] : [];
    s.push("features", "hp");
    if (needsSubclass)    s.push("subclass");
    if (needsBMManeuvers) s.push("bm_maneuvers");
    if (isAsiLevel)       s.push("asi");
    s.push("done");
    return s;
  }, [targetClassKey, needsSubclass, isAsiLevel, needsBMManeuvers]);

  const curStepId = steps[step];
  const isLast    = step === steps.length - 1;

  /* ---- helpers ---- */
  const selectClass = (key) => { setTargetClassKey(key); setStep(1); };
  const goNext      = ()    => setStep(s => Math.min(steps.length - 1, s + 1));
  const goPrev      = ()    => setStep(s => Math.max(0, s - 1));

  const doRoll = () => {
    const r = Math.ceil(Math.random() * hd);
    setRolledDie(r);
    setHpGained(Math.max(1, r + conMod));
  };

  const subclassNeedsChoices = (clsKey, subKey) => {
    if (clsKey==="fighter"   && subKey==="battlemaster") return (subChoices.maneuvers||[]).length >= DND.battleMasterManeuverCount(newClassLv);
    if (clsKey==="barbarian" && subKey==="wildheart")    return !!subChoices.aspect;
    if (clsKey==="barbarian" && subKey==="zealot")       return !!subChoices.furyType;
    if (clsKey==="ranger"    && subKey==="hunter")       return !!subChoices.prey;
    if (clsKey==="druid"     && subKey==="land")         return !!subChoices.terrain;
    if (clsKey==="sorcerer"  && subKey==="draconic")     return !!subChoices.ancestry;
    return true; // no required choices for other subclasses
  };

  const canNext = () => {
    if (curStepId === "class")       return !!targetClassKey;
    if (curStepId === "hp")          return hpGained != null;
    if (curStepId === "subclass")    return !!subchosen && subclassNeedsChoices(targetCls?.key, subchosen);
    if (curStepId === "bm_maneuvers") {
      const existing = (char.battleMasterManeuvers||[]).length;
      const target   = DND.battleMasterManeuverCount(newClassLv);
      return bmNewManeuvers.length >= (target - existing);
    }
    return true;
  };

  const confirm = () => {
    const changes = {};

    // Increment class level
    if (isPrimary) {
      changes.level = (char.level || 1) + 1;
      if (subchosen) {
        changes.subclass = subchosen;
        // Apply initial subclass choices
        const clsKey = targetCls?.key;
        if (clsKey==="fighter"   && subchosen==="battlemaster" && subChoices.maneuvers?.length) changes.battleMasterManeuvers = subChoices.maneuvers;
        if (clsKey==="barbarian" && subchosen==="wildheart"    && subChoices.aspect)            changes.wildHeartAspect = subChoices.aspect;
        if (clsKey==="barbarian" && subchosen==="zealot"       && subChoices.furyType)          changes.zealotFuryType = subChoices.furyType;
        if (clsKey==="ranger"    && subchosen==="hunter"       && subChoices.prey)              changes.hunterPrey = subChoices.prey;
        if (clsKey==="druid"     && subchosen==="land"         && subChoices.terrain)           changes.landCircleTerrain = subChoices.terrain;
        if (clsKey==="sorcerer"  && subchosen==="draconic"     && subChoices.ancestry)          changes.draconicAncestry = subChoices.ancestry;
      }
    } else {
      const idx = mcs.findIndex(m => m.classKey === targetClassKey);
      if (idx >= 0) {
        changes.multiclasses = mcs.map((m, i) => i === idx
          ? { ...m, level: (m.level || 1) + 1, ...(subchosen ? { subclass: subchosen } : {}) }
          : m
        );
      }
    }

    // HP: increase current HP by amount gained; if at full health, stay at full
    const oldMax     = DND.maxHp(char);
    const oldCurrent = char.hpCurrent ?? oldMax;
    const gain       = hpGained ?? avgGain;
    const newChar    = { ...char, ...changes };
    const newMax     = DND.maxHp(newChar);
    changes.hpCurrent = oldCurrent >= oldMax
      ? newMax                  // was at full — keep full
      : Math.min(oldCurrent + gain, newMax); // damaged — add gain, cap at new max

    // ASI / Feat / Epic Boon
    if (levelChoice) {
      changes.levelChoices = { ...(char.levelChoices || {}), [newTotalLv]: levelChoice };
    }

    // Battle Master extra maneuvers at Lv 7/10/15
    if (needsBMManeuvers && bmNewManeuvers.length > 0) {
      changes.battleMasterManeuvers = [...(char.battleMasterManeuvers || []), ...bmNewManeuvers];
    }

    patch(changes);
    onClose();
  };

  /* ---- new features at this level ---- */
  const newFeatures = targetCls
    ? [
        ...(newClassLv === 1 ? targetCls.features.map(f => ({ name: f.name, text: f.text })) : []),
        ...DND.classFeatures(targetCls.key).filter(f => f.l === newClassLv).map(f => ({ name: f.name, text: f.t })),
      ]
    : [];

  /* ============================================================ */
  return (
    <div style={{
      position:"fixed", inset:0, background:"rgba(0,0,0,.55)", zIndex:200,
      display:"flex", alignItems:"center", justifyContent:"center", padding:20,
    }} onClick={e => e.target === e.currentTarget && onClose()}>
      <div style={{
        background:"var(--bg)", borderRadius:16, width:"100%", maxWidth:560,
        maxHeight:"90vh", overflow:"auto", boxShadow:"0 24px 64px rgba(0,0,0,.25)",
      }}>

        {/* ── Header ── */}
        <div style={{
          padding:"20px 24px 14px", borderBottom:"1px solid var(--line)",
          display:"flex", alignItems:"flex-start", justifyContent:"space-between", gap:12,
        }}>
          <div>
            <div style={{ fontSize:11, fontWeight:700, letterSpacing:1.2, textTransform:"uppercase", color:"var(--faint)", marginBottom:4 }}>
              Level Up
            </div>
            <div style={{ fontSize:20, fontWeight:700, fontFamily:"var(--serif)", lineHeight:1.2 }}>
              {targetCls
                ? `${targetCls.name} → Level ${newClassLv}`
                : "Choose a class to level up"}
            </div>
            {targetCls && (
              <div style={{ fontSize:13, color:"var(--ink-2)", marginTop:3 }}>
                Total level {DND.totalLevel(char)} → {newTotalLv} · Prof {DND.fmt(DND.profBonus(newTotalLv))}
              </div>
            )}
          </div>
          <button onClick={onClose} style={{
            background:"none", border:"none", cursor:"pointer", color:"var(--faint)",
            fontSize:22, lineHeight:1, padding:4, flexShrink:0,
          }}>×</button>
        </div>

        {/* ── Step progress bar ── */}
        <div style={{ display:"flex", gap:4, padding:"10px 24px 0" }}>
          {steps.map((s, i) => (
            <div key={s} style={{
              height:3, flex:1, borderRadius:2,
              background: i <= step ? "var(--accent)" : "var(--line-2)",
              transition:"background .2s",
            }}/>
          ))}
        </div>

        {/* ── Step content ── */}
        <div style={{ padding:"22px 24px" }}>

          {/* CLASS SELECTION */}
          {curStepId === "class" && (
            <div>
              <div style={{ fontWeight:600, marginBottom:12 }}>Which class gains a level?</div>
              <div style={{ display:"grid", gap:8 }}>
                {[{ classKey:char.classKey, level:char.level||1 }, ...mcs].map(entry => {
                  const ec = DND.klass(entry.classKey); if (!ec) return null;
                  return (
                    <button key={entry.classKey} className={"opt"+(targetClassKey===entry.classKey?" sel":"")}
                      style={{ textAlign:"left" }} onClick={() => selectClass(entry.classKey)}>
                      <span className="o-check"><Ic.check/></span>
                      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center" }}>
                        <span className="o-name">{ec.name}</span>
                        <span className="tag mono" style={{ flexShrink:0 }}>Lv {entry.level} → {entry.level + 1}</span>
                      </div>
                      <div className="o-blurb">{DND.prereqText(entry.classKey) ? `Prereq: ${DND.prereqText(entry.classKey)}` : ec.blurb}</div>
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          {/* FEATURES */}
          {curStepId === "features" && (
            <div>
              <div style={{ fontWeight:600, marginBottom:12 }}>
                What you gain at {targetCls?.name} {newClassLv}
              </div>
              {newFeatures.length === 0 ? (
                <div style={{ color:"var(--faint)", fontSize:14, fontStyle:"italic" }}>
                  No new class features at this level — your core power continues to grow.
                </div>
              ) : newFeatures.map((f, i) => (
                <div className="trait" key={i}>
                  <div className="tn">{f.name} <span className="lvtag">Lv {newClassLv}</span></div>
                  <div className="tt">{f.text}</div>
                </div>
              ))}
            </div>
          )}

          {/* HIT POINTS */}
          {curStepId === "hp" && (
            <div>
              <div style={{ fontWeight:600, marginBottom:4 }}>Hit Points</div>
              <div style={{ color:"var(--ink-2)", fontSize:13, marginBottom:18 }}>
                Hit Die d{hd} · CON modifier {DND.fmt(conMod)} · Average: +{avgGain}
              </div>
              <div style={{ display:"flex", gap:10, flexWrap:"wrap" }}>
                <button
                  className={"btn"+(hpGained===avgGain && rolledDie==null?" primary":"")}
                  onClick={() => { setHpGained(avgGain); setRolledDie(null); }}>
                  Take average (+{avgGain})
                </button>
                <button className={"btn"+(rolledDie!=null?" primary":"")} onClick={doRoll}>
                  <Ic.dice/> Roll d{hd}{rolledDie!=null ? ` — rolled ${rolledDie}` : ""}
                </button>
              </div>
              {hpGained != null && (
                <div style={{
                  marginTop:16, padding:"11px 14px",
                  background:"var(--accent-soft)", borderRadius:8,
                  color:"var(--accent-ink)", fontWeight:600, fontSize:14,
                }}>
                  +{hpGained} HP on confirm
                </div>
              )}
            </div>
          )}

          {/* SUBCLASS */}
          {curStepId === "subclass" && targetCls && (
            <div>
              <div style={{ fontWeight:600, marginBottom:4 }}>
                Choose your {DND.SUBCLASS_LABEL[targetCls.key]}
              </div>
              <div style={{ color:"var(--ink-2)", fontSize:13, marginBottom:14 }}>
                Level 3 is when your specialisation becomes clear.
              </div>
              <div className="opt-grid cols-2">
                {DND.subclasses(targetCls.key).map(s => (
                  <button key={s.key} className={"opt"+(subchosen===s.key?" sel":"")}
                    onClick={() => { setSubchosen(subchosen===s.key ? null : s.key); setSubChoices({}); }}>
                    <span className="o-check"><Ic.check/></span>
                    <div className="o-name" style={{ fontSize:15 }}>{s.name}</div>
                    <div className="o-blurb">{s.blurb}</div>
                  </button>
                ))}
              </div>
              {/* Inline subclass-specific choices */}
              {subchosen && (()=>{
                const clsKey = targetCls.key;
                if (clsKey==="fighter" && subchosen==="battlemaster") {
                  const count = DND.battleMasterManeuverCount(newClassLv);
                  const chosen = subChoices.maneuvers || [];
                  const toggle = (n) => chosen.includes(n)
                    ? setSubChoices({...subChoices, maneuvers: chosen.filter(x=>x!==n)})
                    : chosen.length < count && setSubChoices({...subChoices, maneuvers: [...chosen, n]});
                  return (<div style={{marginTop:20}}>
                    <div style={{fontWeight:600, marginBottom:4}}>Battle Master Maneuvers — choose {count} <span style={{float:"right",fontWeight:400,color:chosen.length===count?"var(--accent)":"var(--faint)"}}>{chosen.length}/{count}</span></div>
                    <div className="feat-pick">
                      {DND.BATTLE_MASTER_MANEUVERS.map(m=>{const on=chosen.includes(m.name);const full=!on&&chosen.length>=count;return(<button key={m.name} className={"feat-opt"+(on?" sel":"")} disabled={full} onClick={()=>toggle(m.name)}><div className="fo-top"><span className="fo-name">{m.name}</span>{on&&<span className="fo-check"><Ic.check/></span>}</div><div className="fo-text">{m.text}</div></button>);})}
                    </div>
                  </div>);
                }
                if (clsKey==="barbarian" && subchosen==="wildheart") {
                  return (<div style={{marginTop:20}}>
                    <div style={{fontWeight:600, marginBottom:8}}>Rage of the Wilds — choose an aspect</div>
                    <div className="opt-grid cols-3">
                      {DND.WILD_HEART_ASPECTS.map(a=>(<button key={a.key} className={"opt"+(subChoices.aspect===a.key?" sel":"")} onClick={()=>setSubChoices({...subChoices,aspect:subChoices.aspect===a.key?null:a.key})}><span className="o-check"><Ic.check/></span><div className="o-name" style={{fontSize:15}}>{a.name}</div><div className="o-blurb">{a.text}</div></button>))}
                    </div>
                  </div>);
                }
                if (clsKey==="barbarian" && subchosen==="zealot") {
                  return (<div style={{marginTop:20}}>
                    <div style={{fontWeight:600, marginBottom:8}}>Divine Fury — choose damage type</div>
                    <div className="opt-grid cols-2">
                      {[{key:"radiant",name:"Radiant",text:"Divine Fury deals Radiant damage."},{key:"necrotic",name:"Necrotic",text:"Divine Fury deals Necrotic damage."}].map(o=>(<button key={o.key} className={"opt"+(subChoices.furyType===o.key?" sel":"")} onClick={()=>setSubChoices({...subChoices,furyType:subChoices.furyType===o.key?null:o.key})}><span className="o-check"><Ic.check/></span><div className="o-name" style={{fontSize:15}}>{o.name}</div><div className="o-blurb">{o.text}</div></button>))}
                    </div>
                  </div>);
                }
                if (clsKey==="ranger" && subchosen==="hunter") {
                  return (<div style={{marginTop:20}}>
                    <div style={{fontWeight:600, marginBottom:8}}>Hunter's Prey — choose one</div>
                    <div className="opt-grid cols-3">
                      {DND.HUNTER_PREY_OPTIONS.map(o=>(<button key={o.key} className={"opt"+(subChoices.prey===o.key?" sel":"")} onClick={()=>setSubChoices({...subChoices,prey:subChoices.prey===o.key?null:o.key})}><span className="o-check"><Ic.check/></span><div className="o-name" style={{fontSize:15}}>{o.name}</div><div className="o-blurb">{o.text}</div></button>))}
                    </div>
                  </div>);
                }
                if (clsKey==="druid" && subchosen==="land") {
                  return (<div style={{marginTop:20}}>
                    <div style={{fontWeight:600, marginBottom:8}}>Land's Circle — choose a terrain</div>
                    <div className="opt-grid cols-2">
                      {DND.LAND_CIRCLE_TERRAINS.map(t=>(<button key={t.key} className={"opt"+(subChoices.terrain===t.key?" sel":"")} onClick={()=>setSubChoices({...subChoices,terrain:subChoices.terrain===t.key?null:t.key})}><span className="o-check"><Ic.check/></span><div className="o-name" style={{fontSize:15}}>{t.name}</div><div className="o-blurb">{t.text}</div></button>))}
                    </div>
                  </div>);
                }
                if (clsKey==="sorcerer" && subchosen==="draconic") {
                  return (<div style={{marginTop:20}}>
                    <div style={{fontWeight:600, marginBottom:8}}>Draconic Ancestry — choose a dragon type</div>
                    <div className="opt-grid cols-2">
                      {DND.DRACONIC_ANCESTORS.map(a=>(<button key={a.key} className={"opt"+(subChoices.ancestry===a.key?" sel":"")} onClick={()=>setSubChoices({...subChoices,ancestry:subChoices.ancestry===a.key?null:a.key})}><span className="o-check"><Ic.check/></span><div className="o-name" style={{fontSize:15}}>{a.name}</div><div className="o-blurb">{a.damage} damage</div></button>))}
                    </div>
                  </div>);
                }
                return null;
              })()}
            </div>
          )}

          {/* BATTLE MASTER EXTRA MANEUVERS */}
          {curStepId === "bm_maneuvers" && (()=>{
            const existing = char.battleMasterManeuvers || [];
            const targetCount = DND.battleMasterManeuverCount(newClassLv);
            const needed = targetCount - existing.length;
            const toggle = (n) => bmNewManeuvers.includes(n)
              ? setBmNewManeuvers(bmNewManeuvers.filter(x=>x!==n))
              : bmNewManeuvers.length < needed && setBmNewManeuvers([...bmNewManeuvers, n]);
            return (
              <div>
                <div style={{fontWeight:600, marginBottom:4}}>New Battle Master Maneuvers</div>
                <div style={{color:"var(--ink-2)", fontSize:13, marginBottom:14}}>
                  Choose {needed} new maneuver{needed!==1?"s":""} at level {newClassLv} ({bmNewManeuvers.length}/{needed})
                </div>
                <div className="feat-pick">
                  {DND.BATTLE_MASTER_MANEUVERS.filter(m=>!existing.includes(m.name)).map(m=>{
                    const on=bmNewManeuvers.includes(m.name);
                    const full=!on&&bmNewManeuvers.length>=needed;
                    return(<button key={m.name} className={"feat-opt"+(on?" sel":"")} disabled={full} onClick={()=>toggle(m.name)}><div className="fo-top"><span className="fo-name">{m.name}</span>{on&&<span className="fo-check"><Ic.check/></span>}</div><div className="fo-text">{m.text}</div></button>);
                  })}
                </div>
              </div>
            );
          })()}

          {/* ASI / FEAT / EPIC BOON */}
          {curStepId === "asi" && (
            <div>
              <MilestoneCard lvl={newClassLv} char={char} choice={levelChoice} onChange={setLevelChoice} />
            </div>
          )}

          {/* DONE — summary */}
          {curStepId === "done" && (
            <div>
              <div style={{ fontWeight:600, marginBottom:14 }}>Summary</div>
              <div style={{ display:"grid", gap:6 }}>
                <div className="kv"><span className="k">Class levelled</span>
                  <span className="v">{targetCls?.name} {curClassLv} → {newClassLv}</span></div>
                <div className="kv"><span className="k">Total level</span>
                  <span className="v">{DND.totalLevel(char)} → {newTotalLv}</span></div>
                <div className="kv"><span className="k">Proficiency bonus</span>
                  <span className="v mono">{DND.fmt(DND.profBonus(DND.totalLevel(char)))} → {DND.fmt(DND.profBonus(newTotalLv))}</span></div>
                <div className="kv"><span className="k">HP gained</span>
                  <span className="v">+{hpGained ?? avgGain}</span></div>
                {subchosen && (
                  <div className="kv"><span className="k">Subclass</span>
                    <span className="v">{(DND.subclass(targetCls?.key, subchosen)||{}).name || subchosen}</span></div>
                )}
                {levelChoice?.type === "asi" && levelChoice.mode === "two" && levelChoice.a && (
                  <div className="kv"><span className="k">ASI</span>
                    <span className="v">+2 {abilName(levelChoice.a)}</span></div>
                )}
                {levelChoice?.type === "asi" && levelChoice.mode === "split" && (levelChoice.a || levelChoice.b) && (
                  <div className="kv"><span className="k">ASI</span>
                    <span className="v">+1 {levelChoice.a?abilName(levelChoice.a):"—"} / +1 {levelChoice.b?abilName(levelChoice.b):"—"}</span></div>
                )}
                {levelChoice?.type === "feat" && levelChoice.feat && (
                  <div className="kv"><span className="k">Feat</span>
                    <span className="v">{levelChoice.feat}</span></div>
                )}
                {levelChoice?.type === "boon" && levelChoice.boon && (
                  <div className="kv"><span className="k">Epic Boon</span>
                    <span className="v">{levelChoice.boon}</span></div>
                )}
              </div>
            </div>
          )}
        </div>

        {/* ── Footer ── */}
        <div style={{
          padding:"14px 24px", borderTop:"1px solid var(--line)",
          display:"flex", gap:10, alignItems:"center",
        }}>
          {step > 0 && curStepId !== "class" && (
            <button className="btn" onClick={goPrev}>← Back</button>
          )}
          <span style={{ flex:1 }}/>
          {!isLast && curStepId !== "class" && (
            <button className="btn primary" onClick={goNext} disabled={!canNext()}>
              Next →
            </button>
          )}
          {isLast && (
            <button className="btn primary" onClick={confirm}>
              Level up ✓
            </button>
          )}
        </div>

      </div>
    </div>
  );
}

Object.assign(window, { LevelUpWizard });
