// interleaved.jsx — render circuit sets in client-execution order.
//
// Carryover from the Apr 29 meeting and re-flagged by Mike: when a circuit
// has multiple exercises, the trainer asks the client to do
//   Squat 1 → Step+Punch 1 → Squat 2 → Step+Punch 2 …
// not  Squat 1, 2, 3 then Step+Punch 1, 2, 3.
//
// This file:
//   1. flattens circuit.exercises[].sets[] into an interleaved row list
//      (handles uneven set counts — orphan sets render at the end of the
//      sequence under their own round, never lost)
//   2. renders a single table per circuit with one row per set, plus a
//      top "Exercises in order" legend
//   3. tags each exercise with an A/B/C badge so the upcoming color-cue
//      pass (Task 6) has a clear hook — swap the badge bg/border for
//      real accent colors and the same hooks light up the row stripes.

const EX_LETTERS = ['A', 'B', 'C', 'D', 'E', 'F'];
function exLetter(i) { return EX_LETTERS[i] || String(i + 1); }

// Flatten — round-major, exercise-minor. Skips a slot when an exercise has
// fewer sets than the current round so longer exercises finish alone at
// the end rather than crashing or being dropped.
function buildInterleavedRows(circuit) {
  const maxSets = circuit.exercises.reduce((m, e) => Math.max(m, e.sets.length), 0);
  const rows = [];
  for (let r = 0; r < maxSets; r++) {
    circuit.exercises.forEach((ex, exIdx) => {
      if (r < ex.sets.length) {
        rows.push({ round: r + 1, exIdx, ex, setIdx: r, set: ex.sets[r] });
      }
    });
  }
  return rows;
}

// ─── Main block — legend + interleaved table ─────────────────────────────
function InterleavedBlock({ theme, circuit, mode, onUpdateSet, onOpenFeedback, onOpenDetail, exerciseNotes, onEditNote, columnPrefs }) {
  const rawCols = smartColumns(circuit);
  const focusCols = circuitFocusCols(circuit);
  // rawCols = data presence only. Mask through user prefs + view mode +
  // per-circuit focus override (any exercise's focusColumns promotes the
  // column for the whole interleaved table).
  const cols = effectiveColumns(rawCols, columnPrefs, mode, focusCols);
  const weightUnit = (columnPrefs && columnPrefs.weightUnit) || 'lb';
  const rows = buildInterleavedRows(circuit);

  // Column model — Equipment is OUT of the main row entirely (it lives in
  // the per-set expanded breakdown). Tempo still grows vertically when it
  // has multiple numbers; weight collapses to a comma list horizontally.
  const parts = ['1fr', '1.4fr'];                      // Reps | Wt
  if (cols.tempo) parts.push('38px');                  // Tempo digit
  if (cols.rpe)   parts.push('32px');                  // RPE
  parts.push('24px');                                  // Done
  parts.push('22px');                                  // Expand chevron
  const grid = parts.join(' ');

  return (
    <div style={{ padding: '12px 14px' }}>
      {/* Exercise legend at top */}
      <ExerciseLegend theme={theme} circuit={circuit} mode={mode}
        exerciseNotes={exerciseNotes}
        onEditNote={onEditNote}
        onOpenFeedback={onOpenFeedback}
        onOpenDetail={onOpenDetail}/>

      {/* Execution hint */}
      <div style={{
        margin: '10px 0 8px',
        fontFamily: theme.uiFamily, fontSize: 10, color: theme.muted,
        display: 'flex', alignItems: 'center', gap: 6,
      }}>
        <Icon name="chevron" size={9} color={theme.muted} strokeWidth={2.5}/>
        <span>Execution order — top to bottom</span>
      </div>

      {/* Interleaved table */}
      <div style={{ borderRadius: 8, overflow: 'hidden', border: `1px solid ${theme.border}`, position: 'relative' }}>
        {/* Header */}
        <div style={{
          display: 'grid', gridTemplateColumns: grid, gap: 6,
          padding: '6px 8px 6px 12px',
          background: theme.isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.025)',
          fontFamily: theme.uiFamily, fontSize: 9, fontWeight: 600,
          color: theme.muted, textTransform: 'uppercase', letterSpacing: 0.4,
          borderBottom: `0.5px solid ${theme.border}`,
        }}>
          <div>Reps</div>
          <div>Wt</div>
          {cols.tempo && <div>Tempo</div>}
          {cols.rpe   && <div>RPE</div>}
          <div>✓</div>
          <div/>
        </div>

        {/* Sub-header: unit cue under Wt (the unit itself never repeats on a cell) */}
        <div style={{
          display: 'grid', gridTemplateColumns: grid, gap: 6,
          padding: '0 8px 4px 12px',
          fontFamily: theme.monoFamily, fontSize: 8, color: theme.muted, opacity: 0.7,
          borderBottom: `0.5px solid ${theme.border}`,
        }}>
          <div/>
          <div>{weightUnit}</div>
          {cols.tempo && <div/>}
          {cols.rpe   && <div/>}
          <div/>
          <div/>
        </div>

        {/* Rows */}
        {rows.map((row, i) => {
          const prev = i > 0 ? rows[i - 1] : null;
          const newRound = !prev || row.round !== prev.round;
          const totalRounds = rows.length > 0 ? rows[rows.length - 1].round : 0;
          const accent = exerciseColor(theme, row.exIdx);
          return (
            <React.Fragment key={`${row.exIdx}-${row.setIdx}`}>
              {newRound && (
                <div style={{
                  display: 'flex', alignItems: 'baseline', gap: 10,
                  padding: '12px 12px 10px',
                  background: theme.isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.045)',
                  borderTop: i === 0 ? 'none' : `1px solid ${theme.border}`,
                  borderBottom: `1px solid ${theme.border}`,
                }}>
                  <span style={{
                    fontFamily: theme.displayFamily, fontSize: 18, fontWeight: 700,
                    color: theme.text, lineHeight: 1, letterSpacing: -0.2,
                  }}>
                    Round {row.round}
                  </span>
                  <span style={{
                    fontFamily: theme.uiFamily, fontSize: 10, fontWeight: 700,
                    color: theme.muted, textTransform: 'uppercase', letterSpacing: 0.6,
                  }}>of {totalRounds}</span>
                  <div style={{ flex: 1, height: 1, background: theme.border, opacity: 0.6, alignSelf: 'center' }}/>
                </div>
              )}
              <InterleavedSetGroup theme={theme} accent={accent} grid={grid} cols={cols}
                ex={row.ex} set={row.set} setIdx={row.setIdx} exIdx={row.exIdx}
                isFirstAfterRound={newRound}
                detailed={mode === 'detailed'}
                onUpdateSet={onUpdateSet}/>
            </React.Fragment>
          );
        })}
      </div>
    </div>
  );
}

// One set's worth of rows in the interleaved table. The colored accent bar
// runs full height; a thin label on top names the exercise so the eye can
// jump from the legend down to a specific row without losing context.
function InterleavedSetGroup({ theme, accent, grid, cols, ex, set, setIdx, exIdx, isFirstAfterRound, detailed, onUpdateSet }) {
  const { tempoParts, weights, equips, rowSpan } = expandSet(set);
  const hasBreakdown = weights.length > 1 || equips.length > 0 || weights.some(w => w.label);
  const [open, setOpen] = React.useState(false);
  const groupBg = set.done
    ? (theme.isDark ? 'rgba(52,211,153,0.10)' : 'rgba(46,125,50,0.07)')
    : exerciseSetTint(theme, exIdx, setIdx);
  const weightRow = weightRowText(weights);
  return (
    <div style={{
      borderLeft: `5px solid ${accent}`,
      background: groupBg,
      borderTop: isFirstAfterRound ? 'none' : `0.5px solid ${theme.border}`,
    }}>
      {/* Exercise label — the accent bar handles identity, this text seals it */}
      <div style={{
        padding: '5px 10px 0',
        fontFamily: theme.uiFamily, fontSize: 11, fontWeight: 600,
        color: accent, lineHeight: 1.25,
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
      }} title={ex.fullName}>
        {detailed ? ex.fullName : ex.shortName}
      </div>
      {Array.from({ length: rowSpan }).map((_, rowIdx) => {
        const primary = rowIdx === 0;
        return (
          <div key={rowIdx} style={{
            display: 'grid', gridTemplateColumns: grid, gap: 6,
            padding: '6px 8px 6px 10px', alignItems: 'center',
            borderTop: rowIdx === 0 ? 'none' : `0.5px dotted ${theme.border}`,
          }}>
            <Cell theme={theme}
              value={primary ? (set.reps ?? '') : null}
              editable={primary}
              onChange={v => onUpdateSet(ex.id, setIdx, { reps: v })}/>
            {primary ? (
              weights.length > 1 ? (
                <WeightListCell theme={theme} text={weightRow}/>
              ) : (
                <Cell theme={theme}
                  value={weights.length === 1 ? weights[0].value : null}
                  editable={weights.length === 1}
                  onChange={v => onUpdateSet(ex.id, setIdx, { weight: listWithSlot(set.weight, 0, v) })}/>
              )
            ) : <Dash theme={theme}/>}
            {cols.tempo && (
              <Cell theme={theme}
                value={tempoParts[rowIdx] != null ? tempoParts[rowIdx] : null}
                editable={tempoParts[rowIdx] != null}
                onChange={v => onUpdateSet(ex.id, setIdx, { tempo: tempoWithPart(set, rowIdx, v) })}/>
            )}
            {cols.rpe && (
              <Cell theme={theme}
                value={primary ? (set.rpe ?? '') : null}
                editable={primary}
                onChange={v => onUpdateSet(ex.id, setIdx, { rpe: v })}/>
            )}
            <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
              {primary
                ? <DoneCheck theme={theme} done={set.done} onClick={() => onUpdateSet(ex.id, setIdx, { done: !set.done })}/>
                : <Dash theme={theme}/>}
            </div>
            <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
              {primary && hasBreakdown ? (
                <ExpandChevron theme={theme} open={open} accent={accent}
                  onClick={() => setOpen(v => !v)}/>
              ) : <span/>}
            </div>
          </div>
        );
      })}
      {hasBreakdown && open && (
        <ExpandedBreakdown theme={theme} accent={accent}
          weights={weights} equips={equips}
          onChangeWeight={(idx, v) => onUpdateSet(ex.id, setIdx, { weight: replaceLabeled(set.weight, idx, v, 'kind') })}
          onChangeEquip={(idx, v)  => onUpdateSet(ex.id, setIdx, { equip:  replaceLabeled(set.equip,  idx, v, 'name') })}
        />
      )}
    </div>
  );
}

// ─── Exercise legend (top of the interleaved block) ──────────────────────
function ExerciseLegend({ theme, circuit, mode, exerciseNotes, onEditNote, onOpenFeedback, onOpenDetail }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', gap: 8,
      padding: '10px 12px', borderRadius: 8,
      background: theme.isDark ? 'rgba(255,255,255,0.025)' : 'rgba(0,0,0,0.02)',
      border: `1px solid ${theme.border}`,
    }}>
      <div style={{
        fontFamily: theme.uiFamily, fontSize: 9, fontWeight: 700,
        color: theme.muted, textTransform: 'uppercase', letterSpacing: 0.5,
      }}>Exercises in this circuit</div>
      {circuit.exercises.map((ex, exIdx) => {
        const note = exerciseNotes[ex.id];
        const focusList = (ex.focusColumns || []).filter(k => ['equip','tempo','rpe'].includes(k));
        return (
          <div key={ex.id} style={{
            display: 'flex', alignItems: 'flex-start', gap: 9,
            paddingLeft: 8,
            borderLeft: `3px solid ${exerciseColor(theme, exIdx)}`,
          }}>
            <ExBadge theme={theme} exIdx={exIdx}/>
            <div onClick={() => onOpenDetail(ex)} style={{ flex: 1, minWidth: 0, cursor: 'pointer' }}>
              <div style={{
                display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap',
              }}>
                <span style={{
                  fontFamily: theme.uiFamily, fontSize: 13, fontWeight: 600, color: theme.text,
                  lineHeight: 1.3,
                }}>{mode === 'detailed' ? ex.fullName : ex.shortName}</span>
                {focusList.length > 0 && (
                  <span
                    title={`Focus: ${focusList.map(k => ({equip:'Equip',tempo:'Tempo',rpe:'RPE'}[k])).join(' · ')} — column promoted into Basic`}
                    style={{
                      display: 'inline-flex', alignItems: 'center', gap: 4,
                      padding: '1px 7px 2px 5px', borderRadius: 9999,
                      background: exerciseColor(theme, exIdx),
                      color: exerciseChipInk(theme, exIdx),
                      fontFamily: theme.uiFamily, fontSize: 8, fontWeight: 700,
                      textTransform: 'uppercase', letterSpacing: 0.5,
                    }}>
                    <span style={{ fontSize: 9, lineHeight: 1 }}>★</span>
                    {focusList.map(k => ({equip:'Equip',tempo:'Tempo',rpe:'RPE'}[k])).join(' · ')}
                  </span>
                )}
              </div>
              {mode === 'detailed' && (
                <div style={{
                  fontFamily: theme.monoFamily, fontSize: 9, color: theme.muted,
                  marginTop: 2, opacity: 0.7,
                }}>{ex.systemName}</div>
              )}
              {note && (
                <div style={{
                  marginTop: 4, padding: '5px 9px',
                  background: theme.isDark ? 'rgba(255,182,39,0.08)' : 'rgba(255,182,39,0.10)',
                  borderLeft: `2px solid ${theme.primary}`,
                  borderRadius: '0 5px 5px 0',
                  fontFamily: theme.uiFamily, fontSize: 11, color: theme.text, lineHeight: 1.4,
                }}>{note}</div>
              )}
            </div>
            <button onClick={(e) => { e.stopPropagation(); onEditNote('exercise', ex.id, ex.shortName); }}
              title="Add note" style={legendBtnStyle(theme, !!note)}>
              <Icon name="notes" size={11} color={note ? theme.primaryInk : theme.muted} strokeWidth={2}/>
            </button>
            <button onClick={(e) => { e.stopPropagation(); onOpenFeedback({ exerciseId: ex.id, exerciseName: ex.shortName }); }}
              title="Pain or feedback" style={legendBtnStyle(theme, false)}>
              <Icon name="flag" size={11} color={theme.muted} strokeWidth={2}/>
            </button>
          </div>
        );
      })}
    </div>
  );
}

function legendBtnStyle(theme, filled) {
  return {
    width: 26, height: 26, borderRadius: 9999, padding: 0,
    background: filled ? theme.primary : 'transparent',
    border: `1px solid ${filled ? theme.primary : theme.border}`,
    color: filled ? theme.primaryInk : theme.muted,
    cursor: 'pointer', flexShrink: 0,
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
  };
}

// ─── A/B/C exercise badge ────────────────────────────────────────────────
// Filled swatch in the exercise's accent color — same color is echoed by
// the row's left accent bar and tonal row background.
function ExBadge({ theme, exIdx }) {
  const color = exerciseColor(theme, exIdx);
  return (
    <div style={{
      width: 20, height: 20, borderRadius: 5, margin: '0 auto',
      background: color, color: exerciseChipInk(theme, exIdx),
      fontFamily: theme.monoFamily, fontSize: 10, fontWeight: 700,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      boxShadow: theme.isDark ? '0 0 0 1px rgba(0,0,0,0.25) inset' : 'none',
    }}>{exLetter(exIdx)}</div>
  );
}

Object.assign(window, {
  buildInterleavedRows, InterleavedBlock, ExerciseLegend, ExBadge, exLetter,
});
