/* ─────────────────────────────────────────────────────────────
   Controls — sidebar pieces, pickers, header for the Cycle Plotter
───────────────────────────────────────────────────────────────── */
(function () {
  const { useState, useEffect, useRef } = React;
  const PK = window.PK;
  const COMPOUNDS = window.COMPOUNDS;

  const TYPE_DOT = { trt: '#0fbcad', glp1: '#a78bfa', peptide: '#fbbf24' };

  function doseSummary(p) {
    const c = COMPOUNDS[p.compoundId];
    const wk = PK.mgPerWeek(p);
    const perWk = p.freqDays === 7
      ? `${PK.fmt(p.dose)}${c.unit}/wk`
      : `${PK.fmt(wk)}${c.unit}/wk`;
    return `${PK.fmt(p.dose)}${c.unit} · ${PK.freqLabel(p.freqDays)} · ${perWk}`;
  }

  // ── Metric segmented control ──
  function MetricSegment({ value, onChange }) {
    const opts = [['serum', 'Serum level'], ['release', 'mg / day']];
    return React.createElement('div', { className: 'cp-seg' },
      opts.map(([v, l]) => React.createElement('button', {
        key: v, className: 'cp-seg-btn' + (value === v ? ' on' : ''),
        onClick: () => onChange(v),
      }, l))
    );
  }

  // ── overlay toggle pill ──
  function TogglePill({ on, onClick, children, color }) {
    return React.createElement('button', {
      className: 'cp-pill' + (on ? ' on' : ''),
      onClick,
      style: on && color ? { borderColor: color, color, background: color + '1a' } : undefined,
    },
      React.createElement('span', { className: 'cp-pill-dot' }, on ? '●' : '○'),
      children
    );
  }

  // ── Period picker (custom date range + quick presets) ──
  function PeriodPicker({ from, to, onFrom, onTo, onPreset }) {
    const presets = [['4w', 4], ['8w', 8], ['12w', 12], ['26w', 26]];
    return React.createElement('div', { className: 'cp-period' },
      React.createElement('div', { className: 'cp-period-dates' },
        React.createElement('label', { className: 'cp-date-field' },
          React.createElement('span', { className: 'cp-date-lbl' }, 'From'),
          React.createElement('input', { type: 'date', value: from, max: to, onChange: e => onFrom(e.target.value), className: 'cp-date-input' })
        ),
        React.createElement('span', { className: 'cp-date-arrow' }, '→'),
        React.createElement('label', { className: 'cp-date-field' },
          React.createElement('span', { className: 'cp-date-lbl' }, 'To'),
          React.createElement('input', { type: 'date', value: to, min: from, onChange: e => onTo(e.target.value), className: 'cp-date-input' })
        )
      ),
      React.createElement('div', { className: 'cp-preset-row' },
        presets.map(([l, w]) => React.createElement('button', { key: l, className: 'cp-preset', onClick: () => onPreset(w) }, l))
      )
    );
  }

  // ── Protocol row ──
  // The whole card is the on/off control: click it to show/hide the protocol on
  // the chart. Selected = teal border + glow. The start-date input and the 1·2
  // chart picker stop the click from bubbling so they don't toggle the card.
  function ProtocolRow({ p, onToggle, onChart, onStart }) {
    const stop = e => e.stopPropagation();
    return React.createElement('div', {
      className: 'cp-proto' + (p.enabled ? ' on' : ''),
      role: 'button', tabIndex: 0, 'aria-pressed': p.enabled,
      title: p.enabled ? 'Hide from chart' : 'Show on chart',
      onClick: () => onToggle(p.id),
      onKeyDown: e => { if (e.target === e.currentTarget && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); onToggle(p.id); } },
    },
      // body
      React.createElement('div', { className: 'cp-proto-body' },
        React.createElement('div', { className: 'cp-proto-name' }, p.label),
        React.createElement('div', { className: 'cp-proto-meta' }, doseSummary(p)),
        React.createElement('label', { className: 'cp-proto-date', onClick: stop },
          React.createElement('span', { className: 'cp-proto-date-lbl' }, 'Start'),
          React.createElement('input', {
            type: 'date', className: 'cp-proto-date-input', value: p.start,
            onClick: stop, onChange: e => onStart(p.id, e.target.value),
          })
        )
      ),
      // chart assign
      React.createElement('div', { className: 'cp-chart-pick', onClick: stop, style: { flexShrink: 0 } },
        [1, 2].map(n => React.createElement('button', {
          key: n, className: 'cp-chart-btn' + (p.chart === n ? ' on' : ''),
          onClick: e => { stop(e); onChart(p.id, n); }, title: 'Move to chart ' + n,
        }, n))
      )
    );
  }

  // ── Compound picker modal (→ dashboard to save) ──
  function CompoundPicker({ open, onClose, onPick }) {
    const [q, setQ] = useState('');
    if (!open) return null;
    const groups = PK.compoundGroups();
    const ql = q.trim().toLowerCase();
    return React.createElement('div', { className: 'cp-modal-scrim', onClick: onClose },
      React.createElement('div', { className: 'cp-modal', onClick: e => e.stopPropagation() },
        React.createElement('div', { className: 'cp-modal-head' },
          React.createElement('div', null,
            React.createElement('div', { className: 'cp-modal-title' }, 'Plot a new protocol'),
            React.createElement('div', { className: 'cp-modal-sub' }, 'Pick a compound — we\'ll open your dashboard to set the dose & save it.')
          ),
          React.createElement('button', { className: 'cp-modal-x', onClick: onClose }, '✕')
        ),
        React.createElement('input', {
          className: 'cp-modal-search', placeholder: 'Search compounds…',
          value: q, onChange: e => setQ(e.target.value), autoFocus: true,
        }),
        React.createElement('div', { className: 'cp-modal-list' },
          groups.map(g => {
            const items = g.items.filter(it => !ql || it.name.toLowerCase().includes(ql) || it.short.toLowerCase().includes(ql));
            if (!items.length) return null;
            return React.createElement('div', { key: g.cat, className: 'cp-modal-group' },
              React.createElement('div', { className: 'cp-modal-cat' }, g.cat),
              items.map(it => React.createElement('button', { key: it.id, className: 'cp-cmp', onClick: () => onPick(it) },
                React.createElement('span', { className: 'cp-cmp-dot', style: { background: TYPE_DOT[it.type] } }),
                React.createElement('span', { className: 'cp-cmp-name' }, it.name),
                React.createElement('span', { className: 'cp-cmp-hl' }, 't½ ' + (it.halfLife < 1 ? (it.halfLife * 24).toFixed(0) + 'h' : it.halfLife + 'd')),
                React.createElement('span', { className: 'cp-cmp-go' }, '→')
              ))
            );
          })
        )
      )
    );
  }

  // ── Quick-plot modal (signed-out, single compound) ──
  // Lets a logged-out visitor plot ONE compound without an account: pick the
  // compound, dose, colour and frequency, then Calculate. onPlot receives
  // { compoundId, dose, freqDays, color }. `initial` pre-fills it when editing the
  // already-plotted compound. Stacking multiple compounds + saving needs an account.
  function QuickPlotModal({ open, onClose, onPlot, initial, suggestColor, loggedIn }) {
    const groups = PK.compoundGroups();
    const firstId = (groups[0] && groups[0].items[0] && groups[0].items[0].id) || 'test-e';
    const SW = window.PALETTE || {};
    const BLUE = SW.blue || '#3b9bff', ORANGE = SW.orange || '#ff8a1f';
    const SWATCHES = [BLUE, ORANGE, SW.teal, SW.green, SW.pink, SW.purple, SW.amber, SW.coral].filter(Boolean);
    // signed-in users get every colour; signed-out get blue + orange (rest are login-only).
    const ALLOWED = loggedIn ? SWATCHES : [BLUE, ORANGE];
    // LOCAL date strings (match isoToMs / msToIso in app.jsx, which are local). Using
    // toISOString() (UTC) here put the default start a day off in UTC+ timezones (e.g. NZ).
    const localIso = (ms) => { const x = new Date(ms); return x.getFullYear() + '-' + String(x.getMonth() + 1).padStart(2, '0') + '-' + String(x.getDate()).padStart(2, '0'); };
    const todayIso = localIso(Date.now());
    const plusDays = (iso, d) => localIso(new Date(iso + 'T00:00:00').getTime() + d * 86400000);
    const [cid, setCid] = useState((initial && initial.compoundId) || firstId);
    const [doseStr, setDoseStr] = useState(initial ? String(initial.dose) : '');
    const [color, setColor] = useState((initial && initial.color) || suggestColor || BLUE);
    const [tpw, setTpw] = useState(initial ? (Math.round((7 / initial.freqDays) * 10) / 10) : 2);
    const [start, setStart] = useState((initial && initial.start) || todayIso);
    const [finish, setFinish] = useState((initial && initial.finish) || plusDays((initial && initial.start) || todayIso, 70));
    const [locked, setLocked] = useState(false);
    const [page, setPage] = useState(1);   // 2-step wizard: 1 = compound/dose/freq, 2 = dates/colour
    const lockTimer = useRef(null);
    function showLocked() { setLocked(true); if (lockTimer.current) clearTimeout(lockTimer.current); lockTimer.current = setTimeout(() => setLocked(false), 2000); }
    // Lock the underlying page's scroll while the popup is open; restore on close.
    useEffect(() => {
      if (!open) return;
      const prev = document.body.style.overflow;
      document.body.style.overflow = 'hidden';
      return () => { document.body.style.overflow = prev; };
    }, [open]);
    // Reset the form to the (possibly different) compound each time the popup opens.
    useEffect(() => {
      if (!open) return;
      setCid((initial && initial.compoundId) || firstId);
      setDoseStr(initial ? String(initial.dose) : '');
      setColor((initial && initial.color) || suggestColor || BLUE);
      setTpw(initial ? (Math.round((7 / initial.freqDays) * 10) / 10) : 2);
      const s = (initial && initial.start) || todayIso;
      setStart(s); setFinish((initial && initial.finish) || plusDays(s, 70));
      setLocked(false);
      setPage(1);   // always start on step 1
    }, [open]);
    if (!open) return null;
    const c = COMPOUNDS[cid] || {};
    const FREQ = [['Once a week', 1], ['Twice a week', 2], ['3 times a week', 3], ['Every other day', 3.5], ['Daily', 7]];
    const dose = parseFloat(doseStr);
    const datesOk = !!start && !!finish && finish > start;
    const canPlot = dose > 0 && datesOk;
    const theme = (typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'light') ? 'light' : 'dark';
    const lbl = (t) => React.createElement('div', { style: { fontFamily: 'Inter,sans-serif', fontSize: 11, fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', color: 'var(--cp-text-mut)', margin: '0 0 7px' } }, t);
    // solid background + matching color-scheme so the native dropdown list isn't a pale
    // box on the dark theme.
    // fontSize must be >=16px: iOS Safari auto-zooms the viewport when a focused field
    // is smaller, which looked like the modal "super zooming in" on mobile.
    const inp = { width: '100%', height: 42, padding: '0 12px', borderRadius: 8, background: 'var(--cp-card)', border: '1px solid var(--cp-border)', color: 'var(--cp-text)', fontFamily: 'Inter,sans-serif', fontSize: 16, boxSizing: 'border-box', colorScheme: theme };
    function plot() { if (canPlot) onPlot({ compoundId: cid, dose: dose, freqDays: Math.round((7 / tpw) * 100) / 100, color: color, start: start, finish: finish }); }
    const page1Ok = dose > 0;                 // step 1 (compound + dose) complete → can go Next
    const headBtn = { flexShrink: 0, width: 30, height: 30, borderRadius: 5, border: '1px solid var(--cp-border)', background: 'var(--cp-input)', color: 'var(--cp-text-sec)', fontSize: 15, lineHeight: 1, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' };
    const cta = (label, on, enabled) => React.createElement('button', {
      type: 'button', onClick: on, disabled: !enabled,
      style: { height: 48, marginTop: 4, borderRadius: 8, border: 'none', cursor: enabled ? 'pointer' : 'not-allowed', background: enabled ? 'var(--cp-teal)' : 'var(--cp-input)', color: enabled ? '#06201d' : 'var(--cp-text-mut)', fontFamily: 'Inter,sans-serif', fontSize: 15, fontWeight: 700, letterSpacing: '-0.01em', opacity: enabled ? 1 : 0.6 },
    }, label);
    return React.createElement('div', { className: 'cp-modal-scrim', onClick: onClose },
      React.createElement('div', { className: 'cp-modal', onClick: e => e.stopPropagation(), style: { maxWidth: 360 } },
        // header: close (✕) — and on step 2 a back (←) — both top-LEFT, then the title
        React.createElement('div', { className: 'cp-modal-head', style: { justifyContent: 'flex-start', alignItems: 'center', gap: 10, paddingBottom: 12 } },
          React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8 } },
            page === 2 && React.createElement('button', { style: headBtn, 'aria-label': 'Back', onClick: () => setPage(1) }, '←'),
            React.createElement('button', { style: headBtn, 'aria-label': 'Close', onClick: onClose }, '✕')
          ),
          React.createElement('div', { style: { minWidth: 0 } },
            React.createElement('div', { className: 'cp-modal-title' }, initial ? 'Edit compound' : 'Plot a compound'),
            React.createElement('div', { className: 'cp-modal-sub' }, page === 1 ? 'Step 1 of 2 — compound, dose & frequency' : 'Step 2 of 2 — dates & colour')
          )
        ),
        // ── Step 1: compound, dose, frequency ──
        page === 1 && React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 13, padding: '4px 2px 2px' } },
          React.createElement('div', null, lbl('Compound'),
            React.createElement('select', { value: cid, onChange: e => setCid(e.target.value), style: inp },
              groups.map(g => React.createElement('optgroup', { key: g.cat, label: g.cat },
                g.items.map(it => React.createElement('option', { key: it.id, value: it.id }, it.name))
              ))
            )
          ),
          React.createElement('div', null, lbl('Dose per injection (' + (c.unit || 'mg') + ')'),
            React.createElement('input', { type: 'number', inputMode: 'decimal', min: '0', step: 'any', placeholder: 'e.g. 100', value: doseStr, onChange: e => setDoseStr(e.target.value), style: inp })
          ),
          React.createElement('div', null, lbl('How often?'),
            React.createElement('select', { value: String(tpw), onChange: e => setTpw(parseFloat(e.target.value)), style: inp },
              FREQ.map(([l, v]) => React.createElement('option', { key: v, value: String(v) }, l))
            )
          ),
          cta('Next →', () => setPage(2), page1Ok)
        ),
        // ── Step 2: dates, colour, save ──
        page === 2 && React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 13, padding: '4px 2px 2px' } },
          React.createElement('div', { style: { display: 'flex', gap: 12 } },
            React.createElement('div', { style: { flex: 1 } }, lbl('Start date'),
              React.createElement('input', { type: 'date', value: start, max: finish, onChange: e => setStart(e.target.value), style: inp })
            ),
            React.createElement('div', { style: { flex: 1 } }, lbl('Finish date'),
              React.createElement('input', { type: 'date', value: finish, min: start, onChange: e => setFinish(e.target.value), style: inp })
            )
          ),
          React.createElement('div', { style: { position: 'relative' } }, lbl('Colour'),
            React.createElement('div', { style: { display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' } },
              SWATCHES.map(sw => {
                const ok = ALLOWED.indexOf(sw) !== -1;
                if (ok) return React.createElement('button', {
                  key: sw, type: 'button', 'aria-label': 'Colour', onClick: () => { setColor(sw); setLocked(false); },
                  style: { width: 28, height: 28, borderRadius: '50%', background: sw, cursor: 'pointer', padding: 0, outline: 'none', border: color === sw ? '2px solid var(--cp-text)' : '2px solid transparent', boxShadow: color === sw ? '0 0 0 2px ' + sw : 'none' },
                });
                return React.createElement('button', {
                  key: sw, type: 'button', title: 'Login-only colour — connect your Google account, it’s easy', onClick: showLocked,
                  style: { position: 'relative', width: 28, height: 28, borderRadius: '50%', background: sw, opacity: 0.32, cursor: 'pointer', padding: 0, outline: 'none', border: '2px solid transparent' },
                }, React.createElement('span', { 'aria-hidden': 'true', style: { position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 14, fontWeight: 700, textShadow: '0 1px 2px rgba(0,0,0,0.6)' } }, '✕'));
              })
            ),
            // transient bubble (auto-dismisses after 2s) — colours are a login feature
            locked && React.createElement('div', { role: 'status', style: { position: 'absolute', top: '100%', left: 0, marginTop: 7, zIndex: 5, background: 'var(--cp-card)', color: 'var(--cp-text)', fontFamily: 'Inter,sans-serif', fontSize: 12, lineHeight: 1.4, padding: '7px 11px', borderRadius: 8, border: '1px solid var(--cp-border)', boxShadow: '0 6px 18px rgba(0,0,0,0.45)', maxWidth: 250, pointerEvents: 'none' } },
              'Custom colours are a login feature — connect your Google account, it’s easy.')
          ),
          !datesOk && (start && finish) && React.createElement('div', { style: { fontFamily: 'Inter,sans-serif', fontSize: 12, color: '#ff8a1f' } }, 'Finish date must be after the start date.'),
          cta('Save', plot, canPlot)
        )
      )
    );
  }

  // Theme toggle lives in the shared site nav (nav.js) — no page-level duplicate.

  window.CPControls = { MetricSegment, TogglePill, PeriodPicker, ProtocolRow, CompoundPicker, QuickPlotModal, doseSummary };
})();
