/* global React */
// components.jsx — shared UI bits (v2)

const { useState, useRef, useEffect, useCallback } = React;

function SectionHead({ num, title, hint, right }) {
  return (
    <div className="section-head">
      {num && <span className="num">{num}</span>}
      <span className="title">{title}</span>
      {hint && <span className="hint">{hint}</span>}
      {right}
    </div>
  );
}

// ── Song Structure Block ──────────────────────────────────────────────────
function StructureBlock({ block, selected, onSelect, onDelete, onChange, totalSec }) {
  const sliderRef = useRef(null);
  const [drag, setDrag] = useState(false);

  const maxDur = 60; // seconds max per block

  const onDown = (e) => {
    e.preventDefault();
    setDrag(true);
    updateFromEvent(e);
  };
  const updateFromEvent = (ev) => {
    if (!sliderRef.current) return;
    const r = sliderRef.current.getBoundingClientRect();
    const p = Math.max(0, Math.min(1, (ev.clientX - r.left) / r.width));
    const dur = Math.max(2, Math.round(p * maxDur));
    onChange({ ...block, dur });
  };
  useEffect(() => {
    if (!drag) return;
    const m = (ev) => updateFromEvent(ev);
    const u = () => setDrag(false);
    window.addEventListener('pointermove', m);
    window.addEventListener('pointerup', u);
    return () => { window.removeEventListener('pointermove', m); window.removeEventListener('pointerup', u); };
  }, [drag]);

  const fmt = (s) => {
    const m = Math.floor(s / 60);
    const ss = (s % 60).toString().padStart(2, '0');
    return `${m}:${ss}`;
  };

  return (
    <div className={`block${selected ? ' selected' : ''}`} onClick={onSelect}>
      <div className="block-head">
        <span className="drag-handle" title="Drag to reorder">⋮⋮</span>
        <span className={`block-type ${block.type}`}>{block.type}</span>
        <input className="block-desc-input"
               value={block.desc}
               placeholder={`Describe the sound or add lyrics for this ${block.type}…`}
               onChange={(e) => onChange({ ...block, desc: e.target.value })}
               onClick={(e) => e.stopPropagation()} />
        <button className="block-x" onClick={(e) => { e.stopPropagation(); onDelete(); }} title="Delete">
          <svg width="12" height="12" viewBox="0 0 12 12" stroke="currentColor" strokeWidth="1.2" fill="none">
            <path d="M2 2l8 8M10 2l-8 8"/>
          </svg>
        </button>
      </div>
      <div className="block-time-row">
        <div className="time-pair">
          <svg width="12" height="12" viewBox="0 0 12 12" stroke="currentColor" strokeWidth="1" fill="none" style={{opacity:.5}}>
            <circle cx="6" cy="6" r="5"/><path d="M6 3v3l2 1.5"/>
          </svg>
          <span>{fmt(block.start)}</span>
          <span className="dash">—</span>
          <span>{fmt(block.start + block.dur)}</span>
        </div>
        <div ref={sliderRef} className="duration-slider" onPointerDown={onDown}>
          <div className="fill" style={{ width: `${(block.dur / maxDur) * 100}%` }} />
          <div className="handle" style={{ left: `${(block.dur / maxDur) * 100}%` }} />
        </div>
        <span className="mono" style={{ fontSize: 10, color: 'var(--ink-3)', minWidth: 44, textAlign: 'right' }}>
          {block.dur}s
        </span>
      </div>
    </div>
  );
}

// ── Analysis rows ─────────────────────────────────────────────────────────
function AnalysisRow({ label, value, empty, em }) {
  return (
    <div className="row">
      <div className={`bullet${empty ? ' empty' : ''}`}></div>
      <div className="key">{label}</div>
      <div className={`val${empty ? ' placeholder' : ''}`}>
        {value}
        {em && <span className="em">{em}</span>}
      </div>
    </div>
  );
}

// ── Player waveform ───────────────────────────────────────────────────────
function seeded(seed) {
  let s = seed >>> 0;
  return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 0xFFFFFFFF; };
}
function genWaveform(seed, n = 140) {
  const r = seeded(seed);
  const arr = [];
  for (let i = 0; i < n; i++) {
    const t = i / n;
    const env = Math.sin(t * Math.PI) * 0.6 + 0.25;
    const v = (0.35 + r() * 0.65) * env + r() * 0.1;
    arr.push(Math.max(0.08, Math.min(1, v)));
  }
  return arr;
}
function formatTime(sec) {
  sec = Math.max(0, Math.floor(sec));
  return `${Math.floor(sec/60)}:${(sec%60).toString().padStart(2,'0')}`;
}
function Waveform({ bars, progress, onSeek }) {
  const ref = useRef(null);
  const click = (e) => {
    const r = ref.current.getBoundingClientRect();
    const p = (e.clientX - r.left) / r.width;
    onSeek(Math.max(0, Math.min(1, p)));
  };
  return (
    <div ref={ref} className="player-waveform" onClick={click}>
      {bars.map((h, i) => {
        const p = i / bars.length;
        const nearNow = Math.abs(p - progress) < 0.006;
        const isPast = p < progress;
        return <div key={i} className={`bar ${nearNow ? 'now' : isPast ? 'past' : ''}`} style={{ height: `${h*100}%` }} />;
      })}
    </div>
  );
}

// ── Generating overlay ────────────────────────────────────────────────────
function GeneratingOverlay({ step, title = "Composing…", sub = "Lyria 3 Pro is arranging your song." }) {
  const steps = [
    "Reading the lyrics",
    "Applying the style",
    "Laying down the taal",
    "Layering instruments",
    "Rendering vocals",
    "Finishing the mix",
  ];
  return (
    <div className="generating">
      <div className="gen-card">
        <div className="spin" />
        <div className="title">{title}</div>
        <div className="sub">{sub}</div>
        <div className="steps">
          {steps.map((s, i) => (
            <div key={s} className={`step ${i < step ? 'done' : i === step ? 'active' : ''}`}>
              <span className="tick">
                {i < step && (
                  <svg width="8" height="8" viewBox="0 0 8 8" fill="none" stroke="#fff" strokeWidth="1.5">
                    <path d="M1.5 4l1.5 1.5L6.5 2" />
                  </svg>
                )}
              </span>
              {s}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── Analysing mini-overlay (inside Define pane) ──────────────────────────
function AnalysingMini() {
  return (
    <div className="analysing">
      <div style={{ textAlign: 'center' }}>
        <div className="spin" />
        <div style={{ fontFamily: 'var(--f-display)', fontStyle: 'italic', fontSize: 18, marginBottom: 4 }}>Analysing…</div>
        <div style={{ fontFamily: 'var(--f-body)', fontSize: 12, color: 'var(--ink-3)' }}>Listening for genre, voice, taal, tempo and instruments</div>
      </div>
    </div>
  );
}

// ── AlternatesRow: editable input + dropdown of LLM-suggested alternatives ────
// Used by AutoStyleMode and ReferenceTrackAnalyzer to render the per-parameter
// rows on the AI-chosen / Detected Style card. Props:
//   k           label
//   value       current selected value (string)
//   note        optional note shown under the value
//   alternates  array of { value, note? } — the LLM's 2–3 options
//   onChange({ value, note })  — fires on type / pick / clear
function AlternatesRow({ k, value, note, alternates, onChange }) {
  const [open, setOpen] = useState(false);
  const wrapRef = useRef(null);
  const list = Array.isArray(alternates) ? alternates : [];

  useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    };
    window.addEventListener('mousedown', onDown);
    return () => window.removeEventListener('mousedown', onDown);
  }, [open]);

  const pick = (alt) => {
    onChange({ value: alt.value || '', note: alt.note || '' });
    setOpen(false);
  };

  return (
    <div className="analysis-row">
      <div className="k">{k}</div>
      <div className="v" ref={wrapRef} style={{ position: 'relative' }}>
        <div className="alt-input-wrap">
          <input value={value || ''}
                 placeholder="(blank)"
                 onChange={(e) => onChange({ value: e.target.value, note })} />
          {list.length > 0 && (
            <button type="button" className="alt-chevron"
                    aria-label={`Show alternates for ${k}`}
                    onClick={() => setOpen((o) => !o)}>
              <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round">
                <path d="M2 4l3 3 3-3"/>
              </svg>
            </button>
          )}
        </div>
        {note && <span className="note">{note}</span>}
        {open && (
          <div className="alt-popover" role="listbox">
            <div className="alt-popover-head">{list.length} alternates</div>
            {list.map((alt, i) => {
              const sel = (alt.value || '') === (value || '');
              return (
                <button key={i} type="button"
                        className={`alt-opt${sel ? ' on' : ''}`}
                        onClick={() => pick(alt)}>
                  <span className="alt-val">{alt.value || '—'}</span>
                  {alt.note && <span className="alt-note">{alt.note}</span>}
                </button>
              );
            })}
            <button type="button" className="alt-opt blank"
                    onClick={() => pick({ value: '', note: '' })}>
              (leave blank)
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

// ── BpmSliderRow: horizontal slider + readout for the AI-chosen card ─────────
function BpmSliderRow({ value, note, min = 60, max = 160, onChange }) {
  const v = Number.isFinite(value) ? value : (parseInt(value, 10) || 92);
  return (
    <div className="analysis-row">
      <div className="k">BPM</div>
      <div className="v">
        <div className="alt-bpm-wrap">
          <input type="range" min={min} max={max} value={v}
                 onChange={(e) => onChange(parseInt(e.target.value, 10))} />
          <span className="alt-bpm-readout mono">{v}</span>
        </div>
        {note && <span className="note">{note}</span>}
      </div>
    </div>
  );
}

Object.assign(window, {
  SectionHead, StructureBlock, AnalysisRow, Waveform,
  genWaveform, seeded, formatTime, GeneratingOverlay, AnalysingMini,
  AlternatesRow, BpmSliderRow,
});
