/* App shell — manages step state, config, modals (recommender + share), tweaks */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "sizeLayout": "ladder",
  "configLayout": "sticky",
  "personaStyle": "script",
  "summaryVariant": "spec",
  "volumeItem": "mug"
}/*EDITMODE-END*/;

const DEFAULT_CONFIG = {
  size: null,
  airflow: 'updraft',
  gas: 'ng',
  insulation: 'b23',
  door: 'left',
  doorStyle: 'hinged',
  controls: 'right',
  cart: 'frontload',
  upgrades: {
    programmable: true,
    furniture: false,
    hood: false,
    hoodSS: false,
    windApron: false,
    forcedAir: false,
    oxyProbe: false,
  },
  studio: {},
};

function App() {
  const [step, setStep] = useState(0);
  const [config, setConfigRaw] = useState(() => {
    // Hydrate from URL hash if present
    try {
      const h = window.location.hash;
      if (h.startsWith('#cfg=')) {
        const decoded = JSON.parse(atob(decodeURIComponent(h.slice(5))));
        return { ...DEFAULT_CONFIG, ...decoded };
      }
    } catch (e) {}
    return DEFAULT_CONFIG;
  });
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [recOpen, setRecOpen] = useState(false);
  const [shareOpen, setShareOpen] = useState(false);

  const setConfig = (patch) => setConfigRaw((c) => ({ ...c, ...patch }));

  // Sync theme to body data-attr
  useEffect(() => {
    document.documentElement.setAttribute('data-theme', tweaks.theme);
  }, [tweaks.theme]);

  // Step navigation
  const go = (n) => {
    setStep(n);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleSizePicked = (id, mode) => {
    if (mode === 'recommend') {
      setRecOpen(true);
      go(1);
      return;
    }
    if (id && window.LE200.MODELS.find(m => m.id === id)) {
      setConfig({ size: id });
    }
    go(1);
  };

  return (
    <>
      <TopNav step={step} onStep={go} model={window.LE200.MODELS.find(m => m.id === config.size)} />

      {step === 0 && (
        <Landing
          onStart={() => { setConfig({ size: config.size || '12' }); go(1); }}
          onJumpToSize={(id) => handleSizePicked(id, id === 'recommend' ? 'recommend' : null)}
        />
      )}

      {step === 1 && (
        <SizePicker
          config={config}
          setConfig={setConfig}
          onNext={() => go(2)}
          openRecommender={() => setRecOpen(true)}
          layout={tweaks.sizeLayout}
          personaStyle={tweaks.personaStyle}
        />
      )}

      {step === 2 && config.size && (
        <Configurator
          config={config}
          setConfig={setConfig}
          onBack={() => go(1)}
          onNext={() => go(3)}
          layout={tweaks.configLayout}
          volumeItem={tweaks.volumeItem}
        />
      )}

      {step === 3 && config.size && (
        <FitCheck
          config={config}
          setConfig={setConfig}
          onBack={() => go(2)}
          onNext={() => go(4)}
        />
      )}

      {step === 4 && config.size && (
        <Summary
          config={config}
          onBack={() => go(3)}
          onPlace={() => {}}
          variant={tweaks.summaryVariant}
          onShare={() => setShareOpen(true)}
        />
      )}

      {/* Modals */}
      {recOpen && (
        <Recommender
          onClose={() => setRecOpen(false)}
          onPick={(id) => {
            setConfig({ size: id });
            setRecOpen(false);
            if (step < 1) go(1);
          }}
        />
      )}

      {shareOpen && (
        <ShareModal
          config={config}
          onClose={() => setShareOpen(false)}
        />
      )}

      {/* Tweaks panel */}
      <TweaksPanel title="Tweaks">
        <TweakSection title="Field">
          <TweakRadio
            label="Theme"
            options={[
              { value: 'light', label: 'Cream' },
              { value: 'mixed', label: 'Mixed' },
              { value: 'dark', label: 'Teal' },
            ]}
            value={tweaks.theme}
            onChange={(v) => setTweak('theme', v)}
          />
        </TweakSection>
        <TweakSection title="Step 1 · Size picker">
          <TweakRadio
            label="Layout"
            options={[
              { value: 'ladder', label: 'Ladder' },
              { value: 'cards', label: 'Cards' },
              { value: 'compare', label: 'Table' },
            ]}
            value={tweaks.sizeLayout}
            onChange={(v) => setTweak('sizeLayout', v)}
          />
          <TweakRadio
            label="Persona quote"
            options={[
              { value: 'script', label: 'Script' },
              { value: 'clean', label: 'Clean' },
              { value: 'bubble', label: 'Bubble' },
            ]}
            value={tweaks.personaStyle}
            onChange={(v) => setTweak('personaStyle', v)}
          />
        </TweakSection>
        <TweakSection title="Step 2 · Configurator">
          <TweakRadio
            label="Layout"
            options={[
              { value: 'sticky', label: 'Sticky' },
              { value: 'step', label: 'Step' },
              { value: 'single', label: 'Long' },
            ]}
            value={tweaks.configLayout}
            onChange={(v) => setTweak('configLayout', v)}
          />
          <TweakSelect
            label="Volume viz item"
            options={[
              { value: 'mug', label: 'Mugs' },
              { value: 'bowl', label: 'Bowls' },
              { value: 'plate', label: 'Plates' },
              { value: 'teapot', label: 'Teapots' },
            ]}
            value={tweaks.volumeItem}
            onChange={(v) => setTweak('volumeItem', v)}
          />
        </TweakSection>
        <TweakSection title="Step 4 · Summary">
          <TweakRadio
            label="Variant"
            options={[
              { value: 'spec', label: 'Spec' },
              { value: 'receipt', label: 'Receipt' },
              { value: 'hero', label: 'Hero' },
            ]}
            value={tweaks.summaryVariant}
            onChange={(v) => setTweak('summaryVariant', v)}
          />
        </TweakSection>
        <TweakSection title="Jump to step">
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 6 }}>
            {['Land', 'Size', 'Cfg', 'Fit', 'Order'].map((l, i) => (
              <button
                key={i}
                onClick={() => { if (i >= 2 && !config.size) setConfig({ size: '18' }); go(i); }}
                style={{
                  padding: '8px 4px',
                  background: step === i ? 'var(--ink)' : 'transparent',
                  color: step === i ? 'var(--field)' : 'var(--ink)',
                  border: '1px solid var(--ink)',
                  fontSize: 11,
                  cursor: 'pointer',
                  fontFamily: 'var(--font-mono)',
                  letterSpacing: '0.05em',
                  textTransform: 'uppercase',
                }}
              >{l}</button>
            ))}
          </div>
        </TweakSection>
      </TweaksPanel>
    </>
  );
}

// ─────────────────────────────────────────────────── Recommender modal
function Recommender({ onClose, onPick }) {
  const [answers, setAnswers] = useState({});
  const questions = window.LE200.RECOMMENDER;
  const allAnswered = questions.every(q => answers[q.id] != null);

  // Tally weights
  const scores = {};
  if (allAnswered) {
    questions.forEach(q => {
      const choice = q.options[answers[q.id]];
      if (choice?.weight) {
        Object.entries(choice.weight).forEach(([sizeId, w]) => {
          scores[sizeId] = (scores[sizeId] || 0) + w;
        });
      }
    });
  }
  const sorted = Object.entries(scores).sort((a, b) => b[1] - a[1]);
  const top = sorted[0]?.[0];
  const topModel = top ? window.LE200.MODELS.find(m => m.id === top) : null;

  return (
    <ModalShell onClose={onClose} title="Help me pick" tag="[01.r] · Size recommender">
      <p style={{ color: 'var(--ink-2)', fontSize: 14, lineHeight: 1.55, marginTop: 0 }}>
        Three quick questions about how you work. We'll point you at the size that fits.
      </p>
      {questions.map((q, qi) => (
        <div key={q.id} style={{ marginTop: 28 }}>
          <div className="mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.12em', marginBottom: 4 }}>
            Q{qi + 1} of {questions.length}
          </div>
          <h4 className="display" style={{ margin: '4px 0 14px', fontSize: 22 }}>{q.question}</h4>
          <div style={{ display: 'grid', gap: 8 }}>
            {q.options.map((opt, oi) => (
              <Choice
                key={oi}
                active={answers[q.id] === oi}
                onClick={() => setAnswers({ ...answers, [q.id]: oi })}
                label={opt.label}
              />
            ))}
          </div>
        </div>
      ))}

      {allAnswered && topModel && (
        <div style={{
          marginTop: 32, padding: 24,
          background: 'var(--field-2)',
          border: '1px solid var(--accent-deep)',
          position: 'relative',
        }}>
          <Crosshairs />
          <div className="mono upper" style={{ fontSize: 10, color: 'var(--accent-deep)', letterSpacing: '0.14em' }}>
            Our pick for you
          </div>
          <div style={{ display: 'flex', gap: 20, alignItems: 'center', marginTop: 12 }}>
            <img src={topModel.front} alt={topModel.sku} style={{ width: 100, filter: 'drop-shadow(0 8px 12px rgba(14,53,61,0.18))' }} />
            <div>
              <div className="display" style={{ fontSize: 48, lineHeight: 0.9 }}>{topModel.sku}</div>
              <div className="script" style={{ fontSize: 20, color: 'var(--accent-deep)', marginTop: 4, lineHeight: 1.1 }}>
                "{topModel.persona}"
              </div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--ink-3)', marginTop: 6, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
                {topModel.capacity} cu ft · {fmtUSD(topModel.price)} base
              </div>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 12, marginTop: 20, justifyContent: 'flex-end' }}>
            <button className="btn btn-ghost" onClick={() => setAnswers({})}>Reset answers</button>
            <button className="btn btn-accent btn-arrow" onClick={() => onPick(topModel.id)}>
              Configure the {topModel.sku}
            </button>
          </div>

          {sorted.length > 1 && (
            <div style={{ marginTop: 16, paddingTop: 16, borderTop: '1px dashed color-mix(in oklab, var(--ink), transparent 70%)', fontSize: 12, color: 'var(--ink-3)' }}>
              <span className="mono upper" style={{ fontSize: 10, letterSpacing: '0.12em' }}>Runners-up · </span>
              {sorted.slice(1, 3).map(([id, s]) => (
                <button key={id} onClick={() => onPick(id)} style={{
                  background: 'transparent', border: 'none', color: 'var(--ink-2)', cursor: 'pointer',
                  fontFamily: 'var(--font-mono)', fontSize: 12, marginRight: 12, textDecoration: 'underline', padding: 0,
                }}>
                  LE200-{id}
                </button>
              ))}
            </div>
          )}
        </div>
      )}
    </ModalShell>
  );
}

// ─────────────────────────────────────────────────── Share modal
function ShareModal({ config, onClose }) {
  const encoded = btoa(JSON.stringify(config));
  const url = window.location.origin + window.location.pathname + '#cfg=' + encodeURIComponent(encoded);
  const [copied, setCopied] = useState(false);

  const copy = () => {
    navigator.clipboard?.writeText(url);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <ModalShell onClose={onClose} title="Save & share this build" tag="[Share] · Configuration link">
      <p style={{ color: 'var(--ink-2)', fontSize: 14, lineHeight: 1.55, marginTop: 0 }}>
        This link captures your full configuration. Send it to a studio partner, save it for later, or print the spec sheet from your browser.
      </p>
      <div style={{ marginTop: 24 }}>
        <div className="mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.12em', marginBottom: 8 }}>Shareable URL</div>
        <div style={{ display: 'flex', gap: 8 }}>
          <input
            value={url}
            readOnly
            onClick={(e) => e.target.select()}
            style={{
              flex: 1, padding: '12px 14px',
              background: 'var(--field-2)',
              border: '1px solid color-mix(in oklab, var(--ink), transparent 70%)',
              fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--ink)',
            }}
          />
          <button className="btn btn-primary" onClick={copy} style={{ whiteSpace: 'nowrap' }}>
            {copied ? '✓ Copied' : 'Copy link'}
          </button>
        </div>
      </div>
      <div style={{ marginTop: 24, display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
        <button className="btn btn-ghost" onClick={() => window.print()}>⎙ Print PDF</button>
        <button className="btn btn-ghost" onClick={() => { window.location.href = 'mailto:?subject=My LE200 config&body=' + encodeURIComponent(url); }}>✉ Email</button>
        <button className="btn btn-ghost" onClick={() => navigator.share?.({ url })}>↗ Share</button>
      </div>
    </ModalShell>
  );
}

// ─────────────────────────────────────────────────── ModalShell
function ModalShell({ onClose, title, tag, children }) {
  useEffect(() => {
    const k = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', k);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', k);
      document.body.style.overflow = '';
    };
  }, []);
  return (
    <div
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{
        position: 'fixed', inset: 0, zIndex: 100,
        background: 'color-mix(in oklab, var(--ink), transparent 30%)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: 24, overflowY: 'auto',
      }}
    >
      <div style={{
        background: 'var(--field)',
        border: '1px solid var(--ink)',
        width: '100%', maxWidth: 640,
        padding: 32,
        position: 'relative',
      }}>
        <Crosshairs />
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
          <div className="mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.12em' }}>{tag}</div>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', cursor: 'pointer', fontSize: 18, color: 'var(--ink)', padding: 4 }}>×</button>
        </div>
        <h3 className="display" style={{ margin: '4px 0 16px', fontSize: 32 }}>{title}</h3>
        {children}
      </div>
    </div>
  );
}

window.App = App;

// Mount
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
