// recipeos.jsx — RecipeOS workflow animation (matches NutriOS/LabelOS house style)
const { useState, useEffect } = React;

const RDATA = {
  recipe: 'Multigrain Breakfast Biscuit',
  code: 'SKU-BR-118',
  batch: '1,000 units / batch',
  // name, percent (number), per-batch quantity
  formulation: [
    ['Whole Wheat Flour', 54.0, '540 g'],
    ['Refined Palm Oil',  16.0, '160 g'],
    ['Rolled Oats',       14.0, '140 g'],
    ['Cane Sugar',        11.0, '110 g'],
    ['Millet Flour',       3.8, '38 g'],
    ['Iodised Salt',       1.2, '12 g'],
  ],
  note: 'Standardised to 1 kg base; locked supplier specs for palm oil & millet.',
  diff: [
    ['~', 'Refined Palm Oil', '18.0% → 16.0%'],
    ['+', 'Rolled Oats', 'new · 14.0%'],
    ['~', 'Base normalised', '→ 1,000 g'],
  ],
  // tag, message, date  (newest first)
  versions: [
    ['v4', 'Standardised to 1 kg base', 'May 2026'],
    ['v3', 'Added rolled oats & millet', 'Apr 2026'],
    ['v2', 'Reduced palm oil 20 → 16%', 'Mar 2026'],
    ['v1', 'Initial formulation', 'Feb 2026'],
  ],
};

const RSTEPS = [
  { key: 'formulation', label: 'Standardise formulation', win: [0.4, 5.2] },
  { key: 'version',     label: 'Commit new version',      win: [5.5, 8.6] },
  { key: 'record',      label: 'Recipe record · linked workflows', win: [8.9, 13.4] },
];
const RLOOP = 15.5;

const rclamp = (x, a, b) => Math.max(a, Math.min(b, x));
const rprog  = (t, a, b) => rclamp((t - a) / (b - a), 0, 1);
const rtyped = (str, p) => str.slice(0, Math.round(p * str.length));
const rNextStart = (i) => (RSTEPS[i + 1] ? RSTEPS[i + 1].win[0] : RLOOP);
function rActive(t) { for (let i = 0; i < RSTEPS.length; i++) { if (t < rNextStart(i)) return i; } return RSTEPS.length - 1; }

function useReLoop(duration) {
  const [t, setT] = useState(0);
  useEffect(() => {
    let raf, start = performance.now();
    const tick = (now) => {
      if (window.__forceT != null) setT(window.__forceT);
      else setT(((now - start) / 1000) % duration);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [duration]);
  return t;
}

function RCaret({ on }) { return on ? <span className="caret">|</span> : null; }

const MAXPCT = 54.0;

/* ---- final output: recipe record card with version history + linked workflows ---- */
function RecipeRecord({ t }) {
  const building = t < 9.7;
  const done = t >= 12.6;
  const totalShown = RDATA.formulation.filter((_, i) => t >= 9.7 + i * 0.18).length;
  const sum = RDATA.formulation
    .filter((_, i) => t >= 9.7 + i * 0.18)
    .reduce((a, r) => a + r[1], 0);
  const linkP = rprog(t, 11.9, 12.6);
  return (
    <div className={'rp' + (done ? ' rp-done' : '')}>
      <div className="rp-head">
        <div>
          <div className="rp-name">{RDATA.recipe}</div>
          <div className="rp-code mono">{RDATA.code} · {RDATA.batch}</div>
        </div>
        <div className="rp-badge mono">v4 · current</div>
      </div>
      <div className="rp-rule"></div>

      {building
        ? <div className="rp-calc"><span className="np-spin"></span>Compiling immutable recipe record…</div>
        : <div className="rp-grid">
            <div className="rp-form">
              <div className="rp-colhead mono"><span>Formulation</span><span>{sum.toFixed(1).replace('.0','')}%</span></div>
              {RDATA.formulation.map((r, i) => {
                const show = t >= 9.7 + i * 0.18;
                const bp = show ? rprog(t, 9.7 + i * 0.18, 9.7 + i * 0.18 + 0.5) : 0;
                return (
                  <div className={'rp-frow' + (show ? ' in' : '')} key={i}>
                    <span className="rp-fname">{r[0]}</span>
                    <span className="rp-bar"><i style={{ width: (r[1] / MAXPCT) * 100 * bp + '%' }}></i></span>
                    <b className="mono">{r[1].toFixed(1)}%</b>
                    <b className="mono rp-g">{r[2]}</b>
                  </div>
                );
              })}
            </div>

            <div className="rp-ver">
              <div className="rp-colhead mono"><span>Version history</span></div>
              <div className="rp-timeline">
                {RDATA.versions.map((v, i) => {
                  const show = t >= 10.0 + i * 0.28;
                  const cur = i === 0;
                  return (
                    <div className={'rp-vrow' + (show ? ' in' : '') + (cur ? ' cur' : '')} key={v[0]}>
                      <span className="rp-vnode"></span>
                      <div className="rp-vmeta">
                        <div className="rp-vtop"><b className="mono">{v[0]}</b><span className="rp-vdate mono">{v[2]}</span></div>
                        <div className="rp-vmsg">{v[1]}</div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>}

      <div className="rp-foot">
        <span className="rp-flbl mono">CONNECTED WORKFLOWS</span>
        <span className={'rp-link' + (linkP > 0.2 ? ' on' : '')}>→ NutriOS <i>{linkP > 0.2 ? '✓' : ''}</i></span>
        <span className={'rp-link' + (linkP > 0.7 ? ' on' : '')}>→ LabelOS <i>{linkP > 0.7 ? '✓' : ''}</i></span>
      </div>
    </div>
  );
}

/* ---- step input panels ---- */
function ReStepInputs({ stepKey, t }) {
  if (stepKey === 'formulation') {
    const totalP = rprog(t, 0.5, 3.8);
    const sum = RDATA.formulation
      .filter((_, i) => t >= 0.5 + i * 0.55)
      .reduce((a, r) => a + r[1], 0);
    return (
      <div className="si">
        <div className="si-tablehead"><span>Ingredient</span><span>% · per batch</span></div>
        {RDATA.formulation.map((r, i) => {
          const show = t >= 0.5 + i * 0.55;
          return (
            <div className={'si-trow' + (show ? ' in' : '')} key={i}>
              <span>{r[0]}</span>
              <b className="mono">{r[1].toFixed(1)}% · {r[2]}</b>
            </div>
          );
        })}
        <div className="si-total mono"><span>Total</span><b>{sum.toFixed(1)}%</b></div>
      </div>
    );
  }
  // version commit
  const p = rprog(t, 5.6, 7.2);
  const committing = t >= 7.4 && t < 8.2;
  const committed = t >= 8.2;
  return (
    <div className="si">
      <label>Version note · v3 → v4</label>
      <div className="si-note">{rtyped(RDATA.note, p)}<RCaret on={p > 0 && p < 1} /></div>
      <div className="rc-difflist">
        {RDATA.diff.map((d, i) => {
          const show = t >= 6.4 + i * 0.32;
          return (
            <div className={'rc-diff' + (show ? ' in' : '') + (d[0] === '+' ? ' add' : '')} key={i}>
              <span className="rc-dsign mono">{d[0]}</span>
              <span className="rc-dname">{d[1]}</span>
              <span className="rc-dval mono">{d[2]}</span>
            </div>
          );
        })}
      </div>
      <div className="rc-commit mono">
        {committed
          ? <span className="rc-ok"><span className="rc-check">✓</span>Version v4 committed · immutable · full diff retained</span>
          : committing
            ? <span><span className="np-spin"></span>Creating version v4…</span>
            : <span className="rc-hint">Each commit is locked &amp; auditable · history never overwritten</span>}
      </div>
    </div>
  );
}

function RecipeSplit() {
  const t = useReLoop(RLOOP);
  const ai = rActive(t);
  const isLast = ai === RSTEPS.length - 1;
  const pct = ((ai + rprog(t, RSTEPS[ai].win[0], rNextStart(ai))) / RSTEPS.length) * 100;
  const summaries = { formulation: '6 ingredients · 100%', version: 'v4 committed', record: 'linked' };
  return (
    <div className={'vA' + (isLast ? ' vA-labelmode' : '')}>
      <div className="vA-form">
        <div className="vA-brand"><span className="dot"></span>Recipe<i>OS</i><span className="vA-badge mono">new recipe</span></div>
        <div className="vA-list">
          {RSTEPS.map((s, i) => {
            const state = i < ai ? 'done' : i === ai ? 'active' : 'todo';
            return (
              <div className={'vA-item ' + state} key={s.key}>
                <div className="vA-irow">
                  <span className="vA-ix mono">{state === 'done' ? '✓' : String(i + 1).padStart(2, '0')}</span>
                  <span className="vA-ilabel">{s.label}</span>
                  {state === 'done' && <span className="vA-isum">{summaries[s.key]}</span>}
                </div>
                {state === 'active' && <div className="vA-ibody">{s.key === 'record'
                  ? <div className="vA-finalwrap"><RecipeRecord t={t} /></div>
                  : <ReStepInputs stepKey={s.key} t={t} />}</div>}
              </div>
            );
          })}
        </div>
        <div className="vA-prog"><i style={{ width: pct + '%' }}></i></div>
      </div>
    </div>
  );
}

Object.assign(window, { RDATA, RSTEPS, RLOOP, useReLoop, RecipeRecord, RecipeSplit });
