// tweaks.jsx — Tweaks store + draggable panel for the Complete pitch deck (12.05).
//
// Each slide is rendered into its own React root (see index.html). To share tweak
// state across roots, we keep the canonical state on window.__tweaksStore and
// expose a useTweaks() hook that subscribes to it. Every set() also posts
// {type:'__edit_mode_set_keys'} so the values persist on disk via the
// EDITMODE-BEGIN/END block in index.html.

const __TWEAK_DEFAULTS = (typeof window !== 'undefined' && window.__tweakDefaults) || {
  posture_quoteGap: 40,
  posture_padInner: 36,
  posture_headerGap: 22,
  posture_lineGap: 16,
  posture_quoteSize: 104,
  problem_time: '06:47',
  problem_period: 'AM',
};

window.__tweaksStore = window.__tweaksStore || (() => {
  const listeners = new Set();
  let state = { ...__TWEAK_DEFAULTS };
  return {
    get() { return state; },
    set(patch) {
      state = { ...state, ...patch };
      listeners.forEach(fn => fn(state));
      try {
        window.parent.postMessage({ type: '__edit_mode_set_keys', edits: patch }, '*');
      } catch (e) {}
    },
    subscribe(fn) { listeners.add(fn); return () => listeners.delete(fn); },
  };
})();

function useTweaks() {
  const [s, setS] = React.useState(window.__tweaksStore.get());
  React.useEffect(() => window.__tweaksStore.subscribe(setS), []);
  const setT = React.useCallback((patch) => window.__tweaksStore.set(patch), []);
  return [s, setT];
}

// — UI primitives —

function TwSection({ title, sub, children }) {
  return (
    <div style={{ padding: '14px 16px', borderBottom: '1px solid #1f1f1f' }}>
      <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase', color: '#888', marginBottom: 2 }}>{title}</div>
      {sub ? <div style={{ fontSize: 10, color: '#666', marginBottom: 10 }}>{sub}</div> : <div style={{ height: 8 }} />}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>{children}</div>
    </div>
  );
}

function TwRange({ label, value, min, max, step = 1, onChange, unit = 'px' }) {
  return (
    <label style={{ display: 'block', cursor: 'pointer' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: '#bbb', marginBottom: 4 }}>
        <span>{label}</span>
        <span style={{ color: '#e5e5e5', fontVariantNumeric: 'tabular-nums' }}>{value}{unit}</span>
      </div>
      <input
        type="range"
        min={min} max={max} step={step} value={value}
        onChange={e => onChange(parseFloat(e.target.value))}
        style={{ width: '100%', accentColor: '#e5e5e5' }}
      />
    </label>
  );
}

function TwText({ label, value, onChange, placeholder }) {
  return (
    <label style={{ display: 'block', cursor: 'text' }}>
      <div style={{ fontSize: 11, color: '#bbb', marginBottom: 4 }}>{label}</div>
      <input
        type="text"
        value={value} onChange={e => onChange(e.target.value)}
        placeholder={placeholder}
        style={{
          width: '100%', background: '#1a1a1a', color: '#e5e5e5',
          border: '1px solid #3a3a3a', padding: '6px 8px',
          fontFamily: 'inherit', fontSize: 12, outline: 'none', boxSizing: 'border-box',
        }}
      />
    </label>
  );
}

function TwRadio({ label, value, onChange, options }) {
  return (
    <div>
      {label ? <div style={{ fontSize: 11, color: '#bbb', marginBottom: 4 }}>{label}</div> : null}
      <div style={{ display: 'flex', border: '1px solid #3a3a3a' }}>
        {options.map(([v, txt]) => (
          <button
            key={v} onClick={() => onChange(v)}
            style={{
              flex: 1, padding: '7px 4px',
              background: value === v ? '#e5e5e5' : 'transparent',
              color: value === v ? '#0a0a0a' : '#e5e5e5',
              border: 'none', cursor: 'pointer',
              fontFamily: 'inherit', fontSize: 11, fontWeight: 700,
              letterSpacing: 0.8, textTransform: 'uppercase',
            }}
          >{txt}</button>
        ))}
      </div>
    </div>
  );
}

function TwResetButton({ onReset }) {
  return (
    <button onClick={onReset} style={{
      background: 'transparent', color: '#888', border: '1px solid #3a3a3a',
      padding: '6px 10px', fontFamily: 'inherit', fontSize: 10, fontWeight: 700,
      letterSpacing: 0.8, textTransform: 'uppercase', cursor: 'pointer', width: '100%',
    }}>Reset to defaults</button>
  );
}

// — Panel —

function TweaksPanel() {
  const [t, set] = useTweaks();
  const [visible, setVisible] = React.useState(false);
  const [pos, setPos] = React.useState(() => ({
    x: Math.max(16, (window.innerWidth || 1200) - 360),
    y: 24,
  }));

  React.useEffect(() => {
    const onMsg = (e) => {
      const data = e.data || {};
      if (data.type === '__activate_edit_mode') setVisible(true);
      if (data.type === '__deactivate_edit_mode') setVisible(false);
    };
    window.addEventListener('message', onMsg);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  const dismiss = () => {
    setVisible(false);
    window.parent.postMessage({ type: '__edit_mode_dismissed' }, '*');
  };

  const onMouseDown = (e) => {
    const start = { x: e.clientX - pos.x, y: e.clientY - pos.y };
    const onMove = (ev) => setPos({
      x: Math.max(8, Math.min(window.innerWidth - 200, ev.clientX - start.x)),
      y: Math.max(8, Math.min(window.innerHeight - 80, ev.clientY - start.y)),
    });
    const onUp = () => {
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseup', onUp);
    };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup', onUp);
  };

  const resetPosture = () => set({
    posture_quoteGap: 40,
    posture_padInner: 36,
    posture_headerGap: 22,
    posture_lineGap: 16,
    posture_quoteSize: 88,
  });

  const resetProblem = () => set({
    problem_time: '06:47',
    problem_period: 'AM',
  });

  if (!visible) return null;

  return (
    <div style={{
      position: 'fixed', left: pos.x, top: pos.y, zIndex: 99999,
      width: 320, background: '#0a0a0a', color: '#e5e5e5',
      border: '1px solid #3a3a3a',
      fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
      fontSize: 12, boxShadow: '0 12px 40px rgba(0,0,0,0.5)',
    }}>
      <div
        onMouseDown={onMouseDown}
        style={{
          padding: '10px 14px', borderBottom: '1px solid #3a3a3a',
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          cursor: 'grab', userSelect: 'none',
          fontSize: 11, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase',
        }}
      >
        <span>Tweaks · 12.05</span>
        <button onClick={dismiss} style={{
          background: 'transparent', border: 'none', color: '#888',
          cursor: 'pointer', fontSize: 18, padding: 0, lineHeight: 1,
        }} aria-label="Close tweaks">×</button>
      </div>

      <TwSection title="Slide 2 — Problem / The decision" sub="Anchor the time so it reads as a morning moment">
        <TwText label="Time" value={t.problem_time} onChange={v => set({ problem_time: v })} placeholder="06:47" />
        <TwRadio label="Period" value={t.problem_period} onChange={v => set({ problem_period: v })} options={[['AM','AM'],['PM','PM'],['NONE','None']]} />
        <TwResetButton onReset={resetProblem} />
      </TwSection>

      <TwSection title="Slide 5 — Posture / Bowerman" sub="Fix the gap around the divider line">
        <TwRange label="Quote → columns" value={t.posture_quoteGap} min={16} max={96} step={2} onChange={v => set({ posture_quoteGap: v })} />
        <TwRange label="Inner padding" value={t.posture_padInner} min={0} max={80} step={2} onChange={v => set({ posture_padInner: v })} />
        <TwRange label="Header → lines" value={t.posture_headerGap} min={8} max={48} step={1} onChange={v => set({ posture_headerGap: v })} />
        <TwRange label="Line gap" value={t.posture_lineGap} min={6} max={32} step={1} onChange={v => set({ posture_lineGap: v })} />
        <TwRange label="Quote size" value={t.posture_quoteSize} min={72} max={140} step={2} onChange={v => set({ posture_quoteSize: v })} />
        <TwResetButton onReset={resetPosture} />
      </TwSection>
    </div>
  );
}

Object.assign(window, { useTweaks, TweaksPanel });
