/* CTO peer-review widgets — interactive controls specific to the engineering track.
   Skill matrix, sortable priorities, code-diff rating, slider scales, tag picker,
   stack tags, "would you ship this" yes/no with explanation, etc. */

const { useState: ctoUseState, useRef: ctoUseRef, useEffect: ctoUseEffect } = React;

// ─── Skill matrix: rate me on 5 axes (slider 1–5) ─────────────────────
function SkillMatrix({ skills, value = {}, onChange }) {
  const labels = ['—', '1', '2', '3', '4', '5'];
  const captions = (n) => n === 0 ? '· · ·' : n === 1 ? 'junior' : n === 2 ? 'developing' : n === 3 ? 'solid' : n === 4 ? 'strong' : 'staff-level';
  return (
    <div className="cto-matrix">
      {skills.map(s => {
        const v = value[s.key] ?? 0;
        return (
          <div key={s.key} className="cto-matrix-row">
            <div className="cto-matrix-label">
              <div className="cto-matrix-name">{s.label}</div>
              <div className="cto-matrix-hint">{s.hint}</div>
            </div>
            <div className="cto-matrix-track" role="group">
              {[1,2,3,4,5].map(n => (
                <button
                  key={n}
                  className="cto-matrix-dot"
                  data-active={v >= n}
                  onClick={() => onChange({ ...value, [s.key]: v === n ? 0 : n })}
                  aria-label={`${s.label} ${n} of 5`}
                />
              ))}
              <div className="cto-matrix-caption">{captions(v)}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─── Sortable priorities ──────────────────────────────────────────────
function SortablePriorities({ items, value, onChange }) {
  const ordered = value && value.length === items.length ? value : items.slice();
  const [drag, setDrag] = ctoUseState(null);

  const move = (from, to) => {
    if (from === to) return;
    const arr = ordered.slice();
    const [m] = arr.splice(from, 1);
    arr.splice(to, 0, m);
    onChange(arr);
  };

  return (
    <div className="cto-sortable">
      <div className="cto-sortable-hint cf-mono">// drag to reorder · top = matters most</div>
      {ordered.map((item, idx) => (
        <div
          key={item}
          className="cto-sortable-row"
          draggable
          data-dragging={drag === idx}
          onDragStart={() => setDrag(idx)}
          onDragEnd={() => setDrag(null)}
          onDragOver={(e) => { e.preventDefault(); }}
          onDrop={() => { if (drag != null) move(drag, idx); setDrag(null); }}
        >
          <div className="cto-sortable-rank">{String(idx + 1).padStart(2, '0')}</div>
          <div className="cto-sortable-handle">⋮⋮</div>
          <div className="cto-sortable-text">{item}</div>
          <div className="cto-sortable-arrows">
            <button onClick={() => move(idx, Math.max(0, idx - 1))} disabled={idx === 0}>↑</button>
            <button onClick={() => move(idx, Math.min(ordered.length - 1, idx + 1))} disabled={idx === ordered.length - 1}>↓</button>
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Slider scale (1–10) with named ends ──────────────────────────────
function SliderScale({ value, onChange, lowLabel, highLabel, leftWord, rightWord }) {
  const v = value ?? 5;
  return (
    <div className="cto-slider">
      <div className="cto-slider-words">
        <span>{leftWord}</span><span>{rightWord}</span>
      </div>
      <div className="cto-slider-track">
        <input type="range" min={1} max={10} value={v} onChange={e => onChange(Number(e.target.value))} />
        <div className="cto-slider-fill" style={{ width: `${((v - 1) / 9) * 100}%` }} />
        <div className="cto-slider-thumb-num" style={{ left: `${((v - 1) / 9) * 100}%` }}>{v}</div>
      </div>
      <div className="cto-slider-ends cf-mono">
        <span>1 — {lowLabel}</span>
        <span>{highLabel} — 10</span>
      </div>
    </div>
  );
}

// ─── Code diff: which version is better? ─────────────────────────────
function CodeDiffPick({ samples, value, onChange, t }) {
  return (
    <div className="cto-diff">
      {samples.map((s, i) => (
        <button
          key={i}
          className="cto-diff-card"
          aria-pressed={value === i}
          onClick={() => onChange(i)}
        >
          <div className="cto-diff-head">
            <span className="cto-diff-tag">{s.tag}</span>
            <span className="cto-diff-name cf-mono">{s.name}</span>
          </div>
          <pre className="cto-diff-code">{s.code}</pre>
          <div className="cto-diff-pick">
            <span className="cto-diff-pick-dot" />
            {value === i ? (t.locale === 'ru' ? 'Это лучше' : t.locale === 'uk' ? 'Це краще' : 'This one') : (t.locale === 'ru' ? 'Выбрать' : t.locale === 'uk' ? 'Обрати' : 'Pick this')}
          </div>
        </button>
      ))}
    </div>
  );
}

// ─── Yes / No with required reason ───────────────────────────────────
function YesNoWithReason({ value = {}, onChange, yesLabel, noLabel, reasonPlaceholder }) {
  return (
    <div className="cto-yesno">
      <div className="cto-yesno-buttons">
        <button className="cto-yesno-btn cto-yesno-yes" aria-pressed={value.choice === 'yes'} onClick={() => onChange({ ...value, choice: 'yes' })}>
          <span className="cto-yesno-glyph">✓</span> {yesLabel}
        </button>
        <button className="cto-yesno-btn cto-yesno-no" aria-pressed={value.choice === 'no'} onClick={() => onChange({ ...value, choice: 'no' })}>
          <span className="cto-yesno-glyph">✗</span> {noLabel}
        </button>
      </div>
      {value.choice && (
        <textarea
          className="cf-open-text"
          rows={3}
          placeholder={reasonPlaceholder}
          value={value.reason || ''}
          onChange={e => onChange({ ...value, reason: e.target.value })}
          style={{ marginTop: 18 }}
        />
      )}
    </div>
  );
}

// ─── Stack tag cloud (multi-select with weight) ─────────────────────
function StackPicker({ tags, value = [], onChange }) {
  const toggle = (tag) => {
    onChange(value.includes(tag) ? value.filter(t => t !== tag) : [...value, tag]);
  };
  return (
    <div className="cto-stack">
      {tags.map(tag => (
        <button key={tag} className="cto-stack-tag" aria-pressed={value.includes(tag)} onClick={() => toggle(tag)}>
          <span className="cto-stack-hash">#</span>{tag}
        </button>
      ))}
    </div>
  );
}

// ─── Distribute 100 points across categories ─────────────────────────
function PointsAllocator({ buckets, value = {}, onChange, total = 100 }) {
  const sum = Object.values(value).reduce((a, b) => a + (Number(b) || 0), 0);
  const remaining = total - sum;
  const set = (k, raw) => {
    const n = Math.max(0, Math.min(total, Number(raw) || 0));
    const others = Object.entries(value).filter(([key]) => key !== k);
    const otherSum = others.reduce((a, [, b]) => a + (Number(b) || 0), 0);
    const cap = Math.max(0, total - otherSum);
    onChange({ ...value, [k]: Math.min(n, cap) });
  };
  return (
    <div className="cto-points">
      <div className="cto-points-status cf-mono" data-warn={remaining < 0}>
        {remaining === 0 ? '✓ allocated' : remaining > 0 ? `${remaining} left to spend` : `over by ${-remaining}`}
      </div>
      {buckets.map(b => {
        const v = value[b.key] || 0;
        return (
          <div key={b.key} className="cto-points-row">
            <div className="cto-points-label">{b.label}</div>
            <div className="cto-points-bar">
              <input type="range" min={0} max={total} value={v} onChange={e => set(b.key, e.target.value)} />
              <div className="cto-points-fill" style={{ width: `${(v / total) * 100}%` }} />
            </div>
            <div className="cto-points-value cf-mono">{v}</div>
          </div>
        );
      })}
    </div>
  );
}

// ─── Time pulse: how was the rhythm of work? ─────────────────────────
function RhythmGraph({ value = [], onChange, weeks = 8 }) {
  const arr = value.length === weeks ? value : Array.from({ length: weeks }, () => 3);
  const set = (idx, val) => {
    const next = arr.slice();
    next[idx] = val;
    onChange(next);
  };
  return (
    <div className="cto-rhythm">
      <div className="cto-rhythm-grid">
        {arr.map((v, i) => (
          <div key={i} className="cto-rhythm-col">
            <div className="cto-rhythm-bar-wrap">
              {[5,4,3,2,1].map(level => (
                <button
                  key={level}
                  className="cto-rhythm-cell"
                  data-on={v >= level}
                  data-level={level}
                  onClick={() => set(i, v === level ? 0 : level)}
                />
              ))}
            </div>
            <div className="cto-rhythm-week cf-mono">w{i + 1}</div>
          </div>
        ))}
      </div>
      <div className="cto-rhythm-legend cf-mono">
        <span>· low energy</span><span>peak ·</span>
      </div>
    </div>
  );
}

Object.assign(window, {
  SkillMatrix, SortablePriorities, SliderScale, CodeDiffPick,
  YesNoWithReason, StackPicker, PointsAllocator, RhythmGraph,
});

// ─── Trust meter: how much would you trust me with X? ──────────────
function TrustMeter({ items, value = {}, onChange }) {
  const levels = [
    { v: 0, label: 'no way' },
    { v: 1, label: 'with hand-holding' },
    { v: 2, label: 'with light review' },
    { v: 3, label: 'fully' },
  ];
  return (
    <div className="cto-trust">
      {items.map(item => {
        const v = value[item.key];
        return (
          <div key={item.key} className="cto-trust-row">
            <div className="cto-trust-label">
              <div className="cto-trust-name">{item.label}</div>
              <div className="cto-trust-hint">{item.hint}</div>
            </div>
            <div className="cto-trust-pills">
              {levels.map(l => (
                <button
                  key={l.v}
                  className="cto-trust-pill"
                  data-level={l.v}
                  aria-pressed={v === l.v}
                  onClick={() => onChange({ ...value, [item.key]: v === l.v ? undefined : l.v })}
                >
                  {item.levels?.[l.v] || l.label}
                </button>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─── Word pair: pick one of two adjectives across N axes ───────────
function WordPair({ pairs, value = {}, onChange }) {
  return (
    <div className="cto-pairs">
      {pairs.map((p, i) => {
        const picked = value[p.key];
        return (
          <div key={p.key} className="cto-pair-row">
            <button
              className="cto-pair-side cto-pair-left"
              aria-pressed={picked === 'a'}
              onClick={() => onChange({ ...value, [p.key]: picked === 'a' ? undefined : 'a' })}
            >
              <span className="cto-pair-glyph">{p.glyphA || '«'}</span>
              <span className="cto-pair-word">{p.a}</span>
            </button>
            <div className="cto-pair-vs cf-mono">vs</div>
            <button
              className="cto-pair-side cto-pair-right"
              aria-pressed={picked === 'b'}
              onClick={() => onChange({ ...value, [p.key]: picked === 'b' ? undefined : 'b' })}
            >
              <span className="cto-pair-word">{p.b}</span>
              <span className="cto-pair-glyph">{p.glyphB || '»'}</span>
            </button>
          </div>
        );
      })}
    </div>
  );
}

// ─── Process flow rating: stages of work, each gets a glyph ────────
const FLOW_GLYPHS = [
  { v: 'broken', icon: '✗', label: 'broken' },
  { v: 'rough',  icon: '~', label: 'rough' },
  { v: 'ok',     icon: '·', label: 'ok' },
  { v: 'good',   icon: '✓', label: 'good' },
  { v: 'great',  icon: '★', label: 'great' },
];
function ProcessFlow({ stages, value = {}, onChange, captions = {} }) {
  return (
    <div className="cto-flow">
      {stages.map((s, i) => {
        const v = value[s.key];
        return (
          <div key={s.key} className="cto-flow-stage">
            <div className="cto-flow-num cf-mono">{String(i + 1).padStart(2, '0')}</div>
            <div className="cto-flow-name">{s.label}</div>
            <div className="cto-flow-hint cf-mono">{s.hint}</div>
            <div className="cto-flow-glyphs">
              {FLOW_GLYPHS.map(g => (
                <button
                  key={g.v}
                  className="cto-flow-glyph"
                  data-tone={g.v}
                  aria-pressed={v === g.v}
                  onClick={() => onChange({ ...value, [s.key]: v === g.v ? undefined : g.v })}
                  title={captions[g.v] || g.label}
                >
                  {g.icon}
                </button>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ─── "What would you steal from my code" — pick & weight tags ──────
function StealPicker({ tags, value = [], onChange, max = 3 }) {
  const toggle = (tag) => {
    if (value.includes(tag)) {
      onChange(value.filter(t => t !== tag));
    } else if (value.length < max) {
      onChange([...value, tag]);
    }
  };
  return (
    <div>
      <div className="cto-steal">
        {tags.map(tag => {
          const idx = value.indexOf(tag);
          return (
            <button
              key={tag}
              className="cto-steal-tag"
              aria-pressed={idx !== -1}
              onClick={() => toggle(tag)}
              disabled={idx === -1 && value.length >= max}
            >
              {idx !== -1 && <span className="cto-steal-rank cf-mono">{idx + 1}</span>}
              <span>{tag}</span>
            </button>
          );
        })}
      </div>
      <div className="cf-mono cto-steal-hint">
        {value.length} / {max} picked
      </div>
    </div>
  );
}

// ─── Risk flag: text + severity slider ─────────────────────────────
function RiskFlag({ value = {}, onChange, placeholder, severityLow, severityHigh }) {
  const sev = value.severity ?? 3;
  return (
    <div className="cto-risk">
      <textarea
        className="cf-open-text"
        rows={3}
        placeholder={placeholder}
        value={value.text || ''}
        onChange={e => onChange({ ...value, text: e.target.value })}
      />
      <div className="cto-risk-sev">
        <div className="cf-mono cto-risk-sev-label">
          <span>· severity</span>
          <span data-sev={sev}>{sev}/5</span>
        </div>
        <div className="cto-risk-sev-track">
          {[1,2,3,4,5].map(n => (
            <button
              key={n}
              className="cto-risk-sev-cell"
              data-on={sev >= n}
              data-level={n}
              onClick={() => onChange({ ...value, severity: n })}
            />
          ))}
        </div>
        <div className="cf-mono cto-risk-sev-ends">
          <span>{severityLow}</span><span>{severityHigh}</span>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  TrustMeter, WordPair, ProcessFlow, StealPicker, RiskFlag, FLOW_GLYPHS,
});
