/* =========================================================================
   LIFE OS — panels.jsx
   Right-panel tabs: Team (LCD care), Merge Lab, Emotion-dex, Quests.
   window.LifePanels
   ========================================================================= */
(function () {
  const { useState } = React;
  const D = window.LifeData, EN = window.LifeEngine, Art = window.LifeArt;
  const { CreatureSprite, Meter, Coin, moodFromCare } = Art;
  const fmt = n => n >= 1000 ? (n / 1000).toFixed(n < 10000 ? 2 : 1) + 'k' : Math.floor(n).toString();

  // ----------------------------------------------------------- TEAM / CARE
  function TeamPanel({ state, dispatch }) {
    const act = EN.sel.active(state);
    const baseKeys = ['joy', 'sadness', 'anger', 'fear', 'disgust'];
    const hatchCost = EN.C.hatchCost(state.creatures.length);

    return (
      <div>
        {act && <LcdDevice c={act} dispatch={dispatch} />}

        <div className="section-h" style={{ marginTop: 16 }}>Your Feelings · {state.creatures.length}</div>
        <div className="croster">
          {state.creatures.map(c => {
            const e = D.E[c.key], mood = moodFromCare(c.care, c.shadow), avg = EN.sel.careAvg(c);
            const sel = c.uid === state.activeUid;
            return (
              <div key={c.uid} className={'ccard' + (sel ? ' sel' : '') + (c.shadow ? ' shadow' : '')}
                onClick={() => { dispatch({ type: 'SET_ACTIVE', uid: c.uid }); SFX.play('ui'); }}>
                <CreatureSprite emo={e} mood={mood} size={48} />
                <div className="cmeta">
                  <div className="cname">{e.name}<span className="lvl">L{c.level}</span></div>
                  <div className="ctier">{c.shadow ? 'SHADOW · needs care' : e.raw + ' · T' + e.tier}</div>
                  {!c.shadow && <div className="mini-meters">
                    <div className="mm"><i style={{ width: c.care.fed + '%', background: '#FFB347' }} /></div>
                    <div className="mm"><i style={{ width: c.care.rested + '%', background: '#7FB0F0' }} /></div>
                    <div className="mm"><i style={{ width: c.care.seen + '%', background: '#FF8FB0' }} /></div>
                  </div>}
                </div>
                {c.shadow && <button className="btn sm pink" onClick={(ev) => { ev.stopPropagation(); dispatch({ type: 'HEAL', uid: c.uid }); }}>Heal</button>}
              </div>
            );
          })}
        </div>

        <div className="section-h" style={{ marginTop: 18 }}>The Nursery · hatch a raw feeling</div>
        <div className="hand muted" style={{ marginBottom: 8 }}>Each new egg costs a bit more. Raw feelings are the merge ingredients.</div>
        <div className="pick-grid">
          {baseKeys.map(k => {
            const e = D.E[k], afford = state.res.energy >= hatchCost;
            return (
              <div key={k} className={'pick' + (afford ? '' : ' dis')} title={e.name}
                onClick={() => afford && dispatch({ type: 'HATCH', key: k })}>
                <CreatureSprite emo={e} mood="content" size={42} idle={false} />
                <span className="pl">{e.name.slice(0, 3)}</span>
              </div>
            );
          })}
        </div>
        <div className="row" style={{ justifyContent: 'center', gap: 6, marginTop: 8, fontSize: 12 }}>
          <Coin kind="energy" size={15} /><b>{hatchCost}</b><span className="muted">per hatch</span>
        </div>
      </div>
    );
  }

  // LCD Tamagotchi handheld for the active creature
  function LcdDevice({ c, dispatch }) {
    const e = D.E[c.key], mood = moodFromCare(c.care, c.shadow);
    const bars = v => { const n = Math.round(v / 20); return '█'.repeat(n) + '░'.repeat(5 - n); };
    return (
      <div className="lcd-skin pop-in">
        <div className="lcd-screen">
          <div className="row between" style={{ fontSize: 16, marginBottom: 2 }}>
            <span>{e.name.toUpperCase()}</span><span>Lv{c.level}</span>
          </div>
          <div className="lcd-creature">
            <CreatureSprite emo={e} mood={mood} size={120} />
          </div>
          {c.shadow
            ? <div className="lcd-readout">{'>> '}IN SHADOW{' <<'}<br />care to 70% then HEAL</div>
            : <div className="lcd-stats">
                <div className="row"><span>FED&nbsp;</span><span>{bars(c.care.fed)}</span></div>
                <div className="row"><span>RST&nbsp;</span><span>{bars(c.care.rested)}</span></div>
                <div className="row"><span>SEEN</span><span>{bars(c.care.seen)}</span></div>
              </div>}
        </div>
        <div className="lcd-btns">
          {['snack', 'play', 'nap', 'therapy'].map(k => (
            <button key={k} className="lcd-btn" onClick={() => dispatch({ type: 'CARE', uid: c.uid, kind: k })}
              title={D.CARE[k].label}>{D.CARE[k].icon}<span className="cap">{D.CARE[k].label}</span></button>
          ))}
        </div>
      </div>
    );
  }

  // ----------------------------------------------------------- MERGE LAB
  function MergeLab({ state, dispatch }) {
    const [sel, setSel] = useState([]);
    const a = sel[0] || null, b = sel[1] || null;
    const toggle = (uid) => setSel(s => s.includes(uid) ? s.filter(u => u !== uid) : (s.length < 2 ? [...s, uid] : [s[0], uid]));
    const pool = state.creatures.filter(c => !c.shadow);
    const ca = pool.find(c => c.uid === a), cb = pool.find(c => c.uid === b);
    const resultKey = ca && cb ? D.mergeResult(ca.key, cb.key) : null;
    const known = resultKey && state.dex[resultKey];
    const tier = resultKey ? D.E[resultKey].tier : 0;
    let cost = resultKey ? EN.C.mergeCost(tier) : 0;
    if (state.spark === 'alchemist') cost = Math.ceil(cost * 0.65);
    const canMerge = ca && cb && resultKey && state.res.clarity >= cost;
    // V2 — hunches: poke at a combo with "no reaction"
    const hunchCost = Math.round(D.V2.HUNCH.cost * Math.pow(D.V2.HUNCH.costGrowth, state.stats.hunches || 0));
    const hasCuri = state.creatures.some(c => c.key === 'curiosity');
    const canHunch = ca && cb && !resultKey && hasCuri;
    const affordHunch = (state.res.wonder || 0) >= hunchCost;

    const slot = (c, onClear, label) => (
      <div className={'lab-slot ' + (c ? 'filled' : 'empty')} onClick={c ? onClear : null}
        style={c ? { borderColor: D.E[c.key].c[0] } : {}}>
        {c ? <CreatureSprite emo={D.E[c.key]} mood="content" size={84} /> : <span>{label}</span>}
      </div>
    );

    return (
      <div>
        <div className="lab-stage">
          {slot(ca, () => setSel(s => s.filter(u => u !== a)), 'pick A')}
          <span className="lab-plus">+</span>
          {slot(cb, () => setSel(s => s.filter(u => u !== b)), 'pick B')}
          <span className="lab-eq">→</span>
          <div className="lab-result" style={resultKey && known ? { borderColor: D.E[resultKey].c[0] } : (canHunch ? { borderColor: 'var(--wonder)', borderStyle: 'dashed' } : {})}>
            {resultKey ? (
              known
                ? <CreatureSprite emo={D.E[resultKey]} mood="happy" size={92} />
                : <><span className="discover-tag">??? new</span><span className="qmark">?</span></>
            ) : (canHunch ? <><span className="discover-tag" style={{ background: 'var(--wonder-deep)' }}>HUNCH?</span><span className="qmark" style={{ color: 'var(--wonder-deep)' }}>🎲</span></>
                 : (ca && cb ? <span style={{ fontSize: 34, color: 'var(--ink-faint)' }}>✗</span> : <span className="qmark">?</span>))}
          </div>
        </div>

        {resultKey
          ? <button className="btn pink wide" disabled={!canMerge} onClick={() => { dispatch({ type: 'MERGE', a, b }); setSel([]); }}>
              {known ? 'Merge' : 'Discover!'}<span className="cost">· {cost} ◆</span>
            </button>
          : canHunch
            ? <button className="btn wonder wide" disabled={!affordHunch} onClick={() => { dispatch({ type: 'HUNCH', a, b }); setSel([]); }}>
                Play a hunch<span className="cost">· {hunchCost} ◇</span>
              </button>
            : <button className="btn pink wide" disabled>
                {ca && cb ? (hasCuri ? 'No reaction' : 'No reaction\u2026 yet') : 'Pick two feelings'}
              </button>}
        {ca && cb && resultKey && <div className="hand muted center" style={{ marginTop: 8 }}>
          {known ? `${D.E[ca.key].name} + ${D.E[cb.key].name} harmonize into ${D.E[resultKey].name}.` : 'Gus: \u201cI have a good feeling about this combination. Or a bad one. Hard to tell from in here.\u201d'}
        </div>}
        {canHunch && <div className="hand muted center" style={{ marginTop: 8 }}>
          {affordHunch ? 'Gus: \u201cThe handbook says these don\u2019t mix. The handbook is a coward. Spend a little Wonder \u2014 see what falls out.\u201d' : `Not enough Wonder for a hunch (need ${hunchCost} \u25c7). Let Curiosity roam and refill.`}
        </div>}

        <div className="section-h" style={{ marginTop: 18 }}>Choose two to combine</div>
        <div className="pick-grid">
          {pool.map(c => {
            const dim = c.uid === a || c.uid === b;
            return (
              <div key={c.uid} className={'pick' + (dim ? ' dis' : '')} title={D.E[c.key].name}
                onClick={() => { if (dim) return; toggle(c.uid); SFX.play('ui'); }}>
                <CreatureSprite emo={D.E[c.key]} mood="content" size={44} idle={false} />
                <span className="pl">L{c.level}</span>
              </div>
            );
          })}
          {pool.length < 2 && <div className="empty-note" style={{ gridColumn: '1/-1' }}>
            <span className="big">🥚</span>Hatch at least two feelings in the Team tab to start merging.</div>}
        </div>

        <div className="section-h" style={{ marginTop: 18 }}>Recipe Book · {D.MERGE_LIST.filter(([, , r]) => state.dex[r]).length} found</div>
        <div className="croster">
          {D.MERGE_LIST.filter(([, , r]) => state.dex[r]).map(([x, y, r]) => (
            <div key={r} className="ccard" style={{ cursor: 'default' }}>
              <CreatureSprite emo={D.E[r]} mood="content" size={40} idle={false} />
              <div className="cmeta"><div className="cname" style={{ fontSize: 13 }}>{D.E[r].name}</div>
                <div className="ctier">{D.E[x].name} + {D.E[y].name}</div></div>
            </div>
          ))}
          {!Object.keys(state.dex).some(k => D.E[k].tier >= 1) && <div className="hand muted center">No recipes discovered yet. Experiment! Gus is rooting for you. Quietly.</div>}
        </div>

        {(state.hintsSeen || []).filter(r => !state.dex[r]).length > 0 && <>
          <div className="section-h" style={{ marginTop: 18 }}>Hunch Hints · recipes you\u2019ve glimpsed</div>
          <div className="croster">
            {D.MERGE_LIST.filter(([, , r]) => (state.hintsSeen || []).includes(r) && !state.dex[r]).map(([x, y, r]) => (
              <div key={r} className="ccard hint-ccard" style={{ cursor: 'default' }}>
                <span className="hint-glyph">🗂</span>
                <div className="cmeta"><div className="cname" style={{ fontSize: 13 }}>{D.E[x].name} + {D.E[y].name}</div>
                  <div className="ctier">make something \u2014 try it</div></div>
              </div>
            ))}
          </div>
        </>}
      </div>
    );
  }

  // ----------------------------------------------------------- DEX
  function DexPanel({ state, onOpen }) {
    const total = D.order.length, found = Object.keys(state.dex).length;
    const tiers = [{ t: 0, n: 'Raw Feelings' }, { t: 1, n: 'Tier I · First Merges' }, { t: 2, n: 'Tier II · Complex States' }, { t: 3, n: 'Tier III · Legendary' }, { t: 4, n: 'Mutations · Hunch-only' }, { t: -1, n: 'Shadow Forms' }];
    return (
      <div>
        <div className="between" style={{ marginBottom: 10 }}>
          <div className="section-h" style={{ margin: 0 }}>Emotion-dex</div>
          <div className="tiny muted"><b style={{ color: 'var(--pink-deep)' }}>{found}</b> / {total}</div>
        </div>
        <Meter v={found / total * 100} color="linear-gradient(90deg,var(--pink),var(--lav))" h={7} />
        {tiers.map(({ t, n }) => {
          const list = D.order.filter(k => D.E[k].tier === t);
          return (
            <div key={t}>
              <div className="section-h" style={{ marginTop: 16 }}>{n}</div>
              <div className="dex-grid">
                {list.map((k, i) => {
                  const e = D.E[k], seen = state.dex[k];
                  return (
                    <div key={k} className={'dex-cell' + (seen ? '' : ' locked')} onClick={() => seen && onOpen(k)}>
                      <span className="dex-num">{e.tier < 0 ? 'S' : e.tier}{('0' + (i + 1)).slice(-2)}</span>
                      {seen
                        ? <CreatureSprite emo={e} mood="content" size={46} idle={false} />
                        : <span style={{ width: 46, height: 46, display: 'grid', placeItems: 'center', fontSize: 26, color: 'var(--ink-faint)' }}>?</span>}
                      <div className="dn">{seen ? e.name : '???'}</div>
                    </div>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  // ----------------------------------------------------------- QUESTS / STORY
  function QuestPanel({ state, dispatch }) {
    const A = EN.ACTS[state.act - 1];
    const done = EN.actGoalsDone(state, state.act);
    return (
      <div>
        <div className="section-h">The Story · You, Inc.</div>
        <div className="ccard" style={{ cursor: 'default', alignItems: 'flex-start', flexDirection: 'column', gap: 6, padding: 14 }}>
          <div className="row between" style={{ width: '100%' }}>
            <div className="cname" style={{ fontSize: 16 }}>Act {A.n}</div>
            <span className="lvl" style={{ background: 'var(--lav-deep)' }}>{state.act}/4</span>
          </div>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 18, fontWeight: 700 }}>{A.name}</div>
          <div className="muted tiny">{A.blurb}</div>
        </div>

        <div className="section-h" style={{ marginTop: 16 }}>Objectives</div>
        <div className="croster">
          {A.goals.map((g, i) => {
            const [cur, max] = g.p(state); const pct = cur / max * 100; const ok = cur >= max;
            return (
              <div key={i} className="ccard" style={{ cursor: 'default', flexDirection: 'column', alignItems: 'stretch', gap: 7 }}>
                <div className="row between">
                  <span style={{ fontSize: 13, fontWeight: 600 }}>{ok ? '✅ ' : ''}{g.t}</span>
                  <span className="tiny muted" style={{ fontVariantNumeric: 'tabular-nums' }}>{cur}/{max}</span>
                </div>
                <Meter v={pct} color={ok ? 'var(--good)' : 'var(--pink)'} h={7} />
              </div>
            );
          })}
        </div>

        <button className="btn lav wide" style={{ marginTop: 14 }} disabled={!done || state.actDone[state.act]}
          onClick={() => dispatch({ type: 'ADVANCE_ACT' })}>
          {state.actDone[state.act] ? 'Act complete ✓' : done ? `Complete Act ${state.act} →` : 'Finish the objectives'}
        </button>

        <div className="section-h" style={{ marginTop: 20 }}>Run Stats</div>
        <div className="dex-grid" style={{ gridTemplateColumns: 'repeat(2,1fr)' }}>
          {[['Discovered', state.stats.discovered], ['Merges', state.stats.merges], ['Healed', state.stats.healed],
          ['Breakthroughs', state.btCount], ['Clicks', state.stats.clicks], ['Day', state.day]].map(([k, v]) => (
            <div key={k} className="ccard" style={{ cursor: 'default', justifyContent: 'space-between' }}>
              <span className="tiny muted">{k}</span><b style={{ fontVariantNumeric: 'tabular-nums' }}>{fmt(v)}</b>
            </div>
          ))}
        </div>

        {state.spark && <>
          <div className="section-h" style={{ marginTop: 20 }}>Your Spark</div>
          <div className="ccard" style={{ cursor: 'default' }}>
            <span style={{ fontSize: 30 }}>{D.SPARKS[state.spark].icon}</span>
            <div className="cmeta"><div className="cname" style={{ fontSize: 14 }}>{D.SPARKS[state.spark].name}</div>
              <div className="tiny muted" style={{ lineHeight: 1.4 }}>{D.SPARKS[state.spark].desc}</div></div>
          </div>
        </>}
      </div>
    );
  }

  window.LifePanels = { TeamPanel, MergeLab, DexPanel, QuestPanel, fmt };
})();
