// edit-log.jsx — "Crunches (edited)".
//
// Adding an exercise deliberately does NOT rename a circuit: the original name
// is what makes it recognisable a month later. But then a printed sheet reading
// "Crunches" hides the squats that were done in there. So the name carries one
// quiet marker, borrowed from chat apps, and the marker is tappable.
//
// CIRCUIT LEVEL ONLY. No edited-reps inside edited-round inside edited-circuit —
// one marker, on the circuit, and the popup carries the detail. That popup is
// the whole bargain: a 3lb→4lb tweak must not make a circuit look rewritten,
// but it still has to be findable.

// Diff two circuit arrays by id — used after a reorder, which rewrites
// everything at once. Returns { circuitId: [text, ...] }.
function srDiffCircuits(before, after) {
  const out = {};
  const push = (id, t) => { if (id && t) (out[id] = out[id] || []).push(t); };
  const index = (list) => {
    const m = {};
    list.forEach((c, i) => { if (c && c.id) m[c.id] = { c, i }; });
    return m;
  };
  const B = index(before), A = index(after);

  Object.keys(A).forEach(id => {
    const a = A[id], b = B[id];
    if (!b) return;
    if (a.i !== b.i) push(id, `Moved circuit ${b.i + 1} → ${a.i + 1}`);

    const bn = b.c.exercises.map(e => e.shortName);
    const an = a.c.exercises.map(e => e.shortName);
    const gone = bn.filter(n => !an.includes(n));
    const came = an.filter(n => !bn.includes(n));
    gone.forEach(n => push(id, `Moved ${n} out`));
    came.forEach(n => push(id, `Moved ${n} in`));
    if (!gone.length && !came.length && bn.join('|') !== an.join('|')) push(id, 'Reordered exercises');

    // A round move rewrites every exercise's set order identically, so one
    // shared exercise is enough to name which rounds swapped.
    const pair = a.c.exercises
      .map(e => ({ a: e, b: b.c.exercises.find(x => x.shortName === e.shortName) }))
      .find(p => p.b && p.b.sets.length === p.a.sets.length);
    if (pair) {
      const sig = (s) => `${s.reps}/${s.weight == null ? '-' : JSON.stringify(s.weight)}/${s.tempo || '-'}`;
      const bs = pair.b.sets.map(sig), as = pair.a.sets.map(sig);
      const same = bs.join('|') === as.join('|');
      const permuted = bs.slice().sort().join('|') === as.slice().sort().join('|');
      if (!same && permuted) {
        const moved = [];
        as.forEach((s, i) => { if (s !== bs[i]) moved.push(i + 1); });
        push(id, moved.length === 2 ? `Reordered rounds ${moved[0]} & ${moved[1]}` : 'Reordered rounds');
      }
    }
  });
  return out;
}

// Weight/reps read back the way the trainer typed them.
function srEditValue(v, unit) {
  if (v == null || v === '') return '—';
  if (Array.isArray(v)) return v.map(x => srEditValue(x, unit)).join(' · ');
  if (typeof v === 'object') return srEditValue(v.value, unit);
  return typeof v === 'number' && unit ? `${v}${unit}` : String(v);
}

// The marker. Quiet secondary text, not an alarm — information, not a warning.
function EditedMark({ theme, onClick, size }) {
  const s = size || 14;
  return (
    <button onClick={onClick} aria-label="See what changed" style={{
      background: 'none', border: 'none', padding: 0, marginLeft: 8, cursor: 'pointer',
      fontFamily: theme.uiFamily, fontSize: s, fontWeight: 600, color: theme.muted,
      letterSpacing: -0.1, lineHeight: 1.1, whiteSpace: 'nowrap',
      textDecoration: 'underline', textDecorationStyle: 'dotted', textUnderlineOffset: 3,
      textDecorationColor: exRgba(theme.text, 0.3), textDecorationThickness: 1,
    }}>(edited)</button>
  );
}

// The bargain: tap the marker, see exactly what changed and nothing more.
function EditsPopup({ theme, title, items, onClose }) {
  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 90, display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: 24, background: 'rgba(26,20,16,0.42)',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        width: '100%', maxWidth: 300, maxHeight: '70%', overflowY: 'auto',
        borderRadius: 18, padding: '16px 16px 14px',
        background: theme.surface, border: `1px solid ${theme.border}`, boxShadow: '0 18px 44px rgba(0,0,0,0.28)',
      }}>
        <div style={{
          fontFamily: theme.monoFamily, fontSize: 9.5, fontWeight: 700, letterSpacing: 1,
          textTransform: 'uppercase', color: theme.muted, marginBottom: 4,
        }}>What changed</div>
        <div style={{ fontSize: 15.5, fontWeight: 800, letterSpacing: -0.3, marginBottom: 12, lineHeight: 1.2 }}>{title}</div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
          {items.map((it, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 9 }}>
              <span style={{ width: 5, height: 5, borderRadius: 9999, background: theme.primary, flexShrink: 0, marginTop: 6 }} />
              <div style={{ flex: 1, fontSize: 13, lineHeight: 1.45, letterSpacing: -0.1 }}>{it.text}</div>
            </div>
          ))}
          {!items.length && (
            <div style={{ fontSize: 13, color: theme.muted }}>Nothing recorded yet.</div>
          )}
        </div>

        <button onClick={onClose} style={{
          width: '100%', marginTop: 16, padding: '11px 8px', borderRadius: 12, cursor: 'pointer',
          border: `1px solid ${theme.border}`, background: 'transparent', color: theme.text,
          fontFamily: theme.uiFamily, fontSize: 13, fontWeight: 600,
        }}>Close</button>
      </div>
    </div>
  );
}

Object.assign(window, { srDiffCircuits, srEditValue, EditedMark, EditsPopup });
