/* global React, ReactDOM, PortFocusLive, FieldRoute, AndroidStatus, SH_EL, AscendModalM, DeathModalM, CollapseModalM */
// Skyhearth mobile PROTOTYPE — app shell. Mounts the SHARED game brain
// (window.SkyhearthCore.reducer) so the phone runs the EXACT same rules as the
// desktop: training/leak ring, ascension, lifespan clock, Hull, the full care
// & starvation/collapse model, town meta, recruits. The screens are pure views.

const { useState: useSa, useEffect: useEa, useReducer: useRd, useRef: useRa } = React;
const CORE = window.SkyhearthCore;
const PROTO_KEY = 'sh-mobile-proto-v2';   // bumped: unified-state shape

// dominant unlocked vein (for the ascension halo tint)
function topVeinId(state) {
  let id = 'fire', v = -1;
  for (const k in state.elements) { const e = state.elements[k]; if (e.unlocked && (e.mastery || 0) > v) { v = e.mastery || 0; id = k; } }
  return id;
}

// ---------- bottom tabs ----------
const TAB_ICON = {
  raise: <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.4"><circle cx="10" cy="10" r="3.2" /><path d="M10 1v3M10 16v3M1 10h3M16 10h3M3.6 3.6l2 2M14.4 14.4l2 2M16.4 3.6l-2 2M5.6 14.4l-2 2" /></svg>,
  atlas: <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.4"><path d="M2 4.5l5-2 6 2 5-2v13l-5 2-6-2-5 2z" /><path d="M7 2.5v13M13 4.5v13" /></svg>,
  field: <svg width="20" height="20" viewBox="0 0 22 22" fill="none" stroke="currentColor" strokeWidth="1.4"><circle cx="11" cy="4" r="2" /><circle cx="5" cy="12" r="2" /><circle cx="17" cy="12" r="2" /><circle cx="11" cy="19" r="2" /><path d="M9.5 5.5L6.5 10.5M12.5 5.5l3 5M6 14l4 3.5M16 14l-4 3.5" /></svg>,
  codex: <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.4"><path d="M3 3h6a2 2 0 012 2v12a2 2 0 00-2-2H3zM17 3h-6a2 2 0 00-2 2v12a2 2 0 012-2h6z" /></svg>,
};
function ProtoTabs({ active, onTab, locked }) {
  const tabs = [['raise', 'Raise'], ['atlas', 'Atlas'], ['field', 'Field'], ['codex', 'Codex']];
  return (
    <div className="tabbar">
      {tabs.map(([id, label]) => (
        <div key={id} className={'tab' + (id === active ? ' active' : '') + (locked && locked.includes(id) ? ' locked' : '')}
          onPointerDown={() => onTab(id)} style={{ cursor: 'pointer' }}>
          <span className="ti">{TAB_ICON[id]}</span>
          <span>{label}</span>
        </div>
      ))}
    </div>
  );
}

// ---------- Field gate (Field tab tapped, but no run is live) ----------
function FieldGate({ state, dispatch, onLaunch, tabBar }) {
  const ready = state.rank >= 1;
  return (
    <div className="phone sh-m">
      <AndroidStatus />
      <div className="grow col center aic" style={{ padding: '0 34px', gap: 16 }}>
        <div style={{ width: 70, height: 70, borderRadius: '50%', border: '1.5px dashed var(--ink-faded)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'IM Fell English SC, serif', fontSize: 30, color: 'var(--ink-faded)' }}>⚓</div>
        <span className="fell" style={{ fontSize: 22, textAlign: 'center', lineHeight: 1.1 }}>No vessel is afield</span>
        <span className="mono muted" style={{ fontSize: 11, textAlign: 'center', lineHeight: 1.6 }}>
          {ready
            ? 'The harness is rigged and the strata wait. Launch a run from the Hearth to take the spirit out.'
            : 'A Nascent mote cannot crew a vessel. Raise it to a Lesser form first — train a vein to its threshold, and the Hearth will let it launch.'}
        </span>
        {ready
          ? <button className="btn-primary" style={{ fontSize: 15, padding: '11px 22px' }} onPointerDown={onLaunch}>Launch Expedition ▸</button>
          : <span className="stamp stamp-amber">Locked · Rank ≥ Lesser</span>}
      </div>
      {tabBar}
    </div>
  );
}

// ---------- generic stub (Atlas / Codex placeholders until Phases 2–3) ----------
function StubScreen({ which, tabBar }) {
  const copy = which === 'atlas'
    ? { ic: '◈', t: 'The Hearth Atlas', d: 'The rescued plots and the keyed archipelago. Coming next — Phase 2.' }
    : { ic: '❦', t: 'The Codex', d: 'The bestiary of veins, by rank. Coming next — Phase 3.' };
  return (
    <div className="phone sh-m">
      <AndroidStatus />
      <div className="grow col center aic" style={{ padding: '0 30px', gap: 14 }}>
        <div style={{ width: 64, height: 64, borderRadius: '50%', border: '1.5px dashed var(--ink-faded)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'IM Fell English SC, serif', fontSize: 30, color: 'var(--ink-faded)' }}>{copy.ic}</div>
        <span className="fell" style={{ fontSize: 22, textAlign: 'center' }}>{copy.t}</span>
        <span className="mono muted" style={{ fontSize: 11, textAlign: 'center', lineHeight: 1.6 }}>{copy.d}</span>
        <span className="stamp" style={{ marginTop: 4 }}>In progress</span>
      </div>
      {tabBar}
    </div>
  );
}

function ProtoApp() {
  const [boot] = useSa(() => {
    try { const s = JSON.parse(localStorage.getItem(PROTO_KEY)); if (s && s.game && s.game.elements && s.ui) return s; } catch (e) {}
    return { ui: { screen: 'raise' }, game: CORE.INITIAL_STATE };
  });
  const [state, dispatch] = useRd(CORE.reducer, boot.game);
  const [screen, setScreen] = useSa(boot.ui.screen || 'raise');
  const [scale, setScale] = useSa(1);

  // dev/debug hooks (mirror the desktop)
  useEa(() => { window.SH_dispatch = dispatch; window.SH_state = state; });
  // persist unified state + which screen
  useEa(() => { try { localStorage.setItem(PROTO_KEY, JSON.stringify({ ui: { screen }, game: state })); } catch (e) {} }, [screen, state]);

  // keep the visible screen in step with the game phase (LAUNCH → field, RETURN → raise)
  useEa(() => {
    if (state.phase === 'expedition' && screen !== 'field') setScreen('field');
    else if (state.phase === 'port' && screen === 'field') setScreen('raise');
  }, [state.phase]);

  // ascension fanfare — watch a rank increase, hold the moment until dismissed
  const prevRank = useRa(state.rank);
  const [ascendInfo, setAscendInfo] = useSa(null);
  useEa(() => {
    if (state.rank > prevRank.current) {
      const vein = topVeinId(state);
      setAscendInfo({ formName: state.formName, toRank: state.rank, veinId: vein });
    }
    prevRank.current = state.rank;
  }, [state.rank]);
  // auto-clear the brief shake flag the reducer sets
  useEa(() => { if (!state.ascending) return; const t = setTimeout(() => dispatch({ type: 'CLEAR_ASCENDING' }), 900); return () => clearTimeout(t); }, [state.ascending]);

  // auto-scale the device to the viewport
  const DEV_W = 384, DEV_H = 832;
  useEa(() => {
    function fit() {
      const s = Math.min((window.innerWidth - 40) / DEV_W, (window.innerHeight - 40) / DEV_H);
      setScale(Math.min(1.35, Math.max(0.4, s)));
    }
    fit(); window.addEventListener('resize', fit);
    return () => window.removeEventListener('resize', fit);
  }, []);

  function launch() { dispatch({ type: 'LAUNCH' }); }
  function resetAll() { try { localStorage.removeItem(PROTO_KEY); } catch (e) {} dispatch({ type: 'LOAD_STATE', state: CORE.INITIAL_STATE }); setScreen('raise'); setAscendInfo(null); }

  const popupOpen = !!ascendInfo || state.collapsed || state.dying;
  const tabBar = <ProtoTabs active={screen} onTab={setScreen} locked={state.rank < 1 ? ['field'] : []} />;

  let body;
  if (screen === 'raise') body = <PortFocusLive state={state} dispatch={dispatch} onLaunch={launch} popupOpen={popupOpen} tabBar={tabBar} />;
  else if (screen === 'field') body = (state.phase === 'expedition')
    ? <FieldRoute state={state} dispatch={dispatch} onReturnScreen={() => setScreen('raise')} tabBar={tabBar} />
    : <FieldGate state={state} dispatch={dispatch} onLaunch={launch} tabBar={tabBar} />;
  else body = <StubScreen which={screen} tabBar={tabBar} />;

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'radial-gradient(ellipse at center, #2a221a 0%, #0e0a08 100%)', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
      <button onPointerDown={resetAll} title="Reset prototype state"
        style={{ position: 'absolute', top: 14, right: 16, zIndex: 10, background: 'rgba(244,236,214,0.08)', border: '1px solid rgba(244,236,214,0.25)', color: 'rgba(244,236,214,0.6)', fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: '0.1em', padding: '5px 9px', borderRadius: 3, cursor: 'pointer' }}>↺ RESET</button>

      <div style={{ transform: `scale(${scale})`, transformOrigin: 'center center' }}>
        <div style={{ width: DEV_W + 18, height: DEV_H + 18, background: 'linear-gradient(160deg, #1c1713, #0d0a08)', borderRadius: 42, padding: 9, boxShadow: '0 40px 90px rgba(0,0,0,0.6), inset 0 0 0 1px rgba(244,236,214,0.06)' }}>
          <div style={{ width: DEV_W, height: DEV_H, borderRadius: 33, overflow: 'hidden', position: 'relative', boxShadow: 'inset 0 0 0 2px #000' }}>
            {body}
            {/* condition modals — overlaid inside the bezel */}
            {ascendInfo && <AscendModalM info={ascendInfo} onClose={() => setAscendInfo(null)} />}
            {state.collapsed && !state.dying && <CollapseModalM state={state} onClose={() => dispatch({ type: 'CLEAR_COLLAPSE' })} />}
            {state.dying && <DeathModalM state={state} onReset={() => dispatch({ type: 'RESET_TO_MOTE' })} />}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ProtoApp, ProtoTabs });
