// components.jsx — Mother's Day Trivia for Demetria

// ───────────────────────────── Sleeve (crate item) ─────────────────────────────
function Sleeve({ q, onPick, played, locked }) {
  const isBonus = q.bonus;
  // Played tracks remain replayable for fun; only locked sleeves block clicks.
  const isDisabled = locked;
  // Read real audio duration via metadata preload
  const [dur, setDur] = React.useState(null);
  React.useEffect(() => {
    const a = new Audio();
    a.preload = "metadata";
    const fmt = (d) => {
      if (!isFinite(d) || d <= 0) return null;
      const m = Math.floor(d / 60);
      const s = Math.floor(d % 60).toString().padStart(2, "0");
      return `${m}:${s}`;
    };
    const onLoaded = () => {
      const f = fmt(a.duration);
      if (f) setDur(f);
      else {
        // Fallback for VBR mp3 with no header duration: seek to end to force scan
        try {
          a.currentTime = 1e101;
          a.addEventListener("timeupdate", function once() {
            a.removeEventListener("timeupdate", once);
            const f2 = fmt(a.duration);
            if (f2) setDur(f2);
            try { a.currentTime = 0; } catch (e) {}
          });
        } catch (e) {}
      }
    };
    const onDurChange = () => {
      const f = fmt(a.duration);
      if (f) setDur(f);
    };
    a.addEventListener("loadedmetadata", onLoaded);
    a.addEventListener("durationchange", onDurChange);
    a.src = `assets/audio/track-${q.id}.mp3`;
    return () => {
      a.removeEventListener("loadedmetadata", onLoaded);
      a.removeEventListener("durationchange", onDurChange);
      a.src = "";
    };
  }, [q.id]);
  return (
    <button
      className={`sleeve ${locked ? 'locked' : ''} ${isBonus ? 'bonus' : ''} ${played && !isBonus ? 'played' : ''}`}
      onClick={onPick}
      disabled={isDisabled}
    >
      <div className="art" style={{ background: q.art.bg, color: q.art.fg }}>
        <img
          className="art-img"
          src={`assets/covers/track-${q.id}.jpg`}
          alt=""
          onError={(e) => { e.currentTarget.style.display = 'none'; }}
        />
        {locked && <div className="lock-badge">🔒</div>}
        {played && !isBonus && !locked && (
          <div className="played-badge" aria-label="Already played">
            <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
              <path
                d="M3.5 8.5L6.5 11.5L12.5 5"
                stroke="currentColor" strokeWidth="2"
                fill="none" strokeLinecap="round" strokeLinejoin="round"
              />
            </svg>
          </div>
        )}
      </div>
      <div className="meta">
        <div className="lbl">
          {isBonus ? "Bonus" : `Side ${q.side} · Track ${q.n}`}
        </div>
        <div className="ttl">{q.title}</div>
        {locked && <div className="lock-hint">Get every question right to unlock</div>}
      </div>
      <div className="right">
        {locked
          ? <div className="dur">—</div>
          : played && !isBonus
            ? (
              <div className="check">
                <svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true">
                  <path
                    d="M3.5 8.5L6.5 11.5L12.5 5"
                    stroke="currentColor" strokeWidth="2"
                    fill="none" strokeLinecap="round" strokeLinejoin="round"
                  />
                </svg>
                <span>Played</span>
              </div>
            )
            : <div className="dur">{dur || "—:—"}</div>}
      </div>
    </button>
  );
}

// ───────────────────────────── Turntable ─────────────────────────────
function Turntable({ q, playing }) {
  const accent = q.side === "B" ? "sage" : "";
  const sideLabel = `SIDE ${q.side} · 33⅓`;
  return (
    <div className="turntable">
      <div className="platter">
        <div className={`disc ${playing ? "" : "paused"}`}>
          <div className={`disc-label ${accent}`} data-side={sideLabel} />
        </div>
      </div>
      <Tonearm playing={playing} />
    </div>
  );
}

function Tonearm({ playing }) {
  return (
    <div className={`tonearm ${playing ? "playing" : ""}`}>
      <div className="pivot" />
      <div className="arm"><div className="head" /></div>
    </div>
  );
}

// ───────────────────────────── Waveform ─────────────────────────────
function Waveform({ active }) {
  const heights = [10, 20, 14, 28, 18, 32, 16, 24, 12, 30, 22, 18, 26, 14, 22, 16, 28, 18];
  return (
    <div className={`waveform ${active ? "" : "idle"}`}>
      {heights.map((h, i) => (
        <span key={i} style={{ "--h": `${h}px`, height: 6, animationDelay: `${i * 0.06}s` }} />
      ))}
    </div>
  );
}

// ───────────────────────────── Question Card ─────────────────────────────
function QuestionCard({ q, onAnswer, picked }) {
  return (
    <div className="qcard">
      <div className="qmeta">
        <span className="eyebrow">Track {q.n} · Side {q.side}</span>
        <span className="voiced">{q.voiced} asks</span>
      </div>
      <div className="q">"{q.q}"</div>
      <div className="answers">
        {q.answers.map((a, i) => {
          let cls = "ans";
          if (picked != null) {
            if (i === q.correct) cls += " correct";
            else if (i === picked) cls += " wrong";
            else cls += " dim";
          }
          const key = ["A","B","C","D"][i];
          return (
            <button key={i} className={cls} onClick={() => onAnswer(i)} disabled={picked != null}>
              <span className="key">{key}</span><span>{a}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ───────────────────────────── Notes Pill (in topbar) ─────────────────────────────
function NotesPill({ notes, bumped, onClick }) {
  const inner = (
    <>
      <span className="glyph">♪</span>
      <span>{notes} note{notes === 1 ? "" : "s"}</span>
    </>
  );
  if (onClick) {
    return (
      <button
        type="button"
        className={`notes-pill notes-pill-btn ${bumped ? "bumped" : ""}`}
        onClick={onClick}
        aria-label={`${notes} note${notes === 1 ? "" : "s"} — open the shop`}
      >
        {inner}
      </button>
    );
  }
  return (
    <div className={`notes-pill ${bumped ? "bumped" : ""}`}>{inner}</div>
  );
}

// ───────────────────────────── Settings cog (in topbar) ─────────────────────────────
function SettingsCog({ onClick }) {
  return (
    <button type="button" className="settings-cog" onClick={onClick} aria-label="Settings">
      <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" focusable="false">
        <path
          fill="currentColor"
          d="M19.43 12.98c.04-.32.07-.64.07-.98 0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98 0 .33.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"
        />
      </svg>
    </button>
  );
}

// ───────────────────────────── Topbar ─────────────────────────────
function TopBar({ left, right }) {
  return (
    <div className="topbar">
      <div>{left}</div>
      <div>{right}</div>
    </div>
  );
}

function Brand({ side = "A", onClick }) {
  const label = `Side ${side} · For Demetria`;
  if (onClick) {
    return (
      <button
        type="button"
        className="brand brand-toggle"
        onClick={onClick}
        aria-label={`Switch to Side ${side === "A" ? "B" : "A"}`}
      >
        <span className="mini-disc" />
        <span>{label}</span>
      </button>
    );
  }
  return (
    <div className="brand">
      <span className="mini-disc" />
      <span>{label}</span>
    </div>
  );
}

function BackBtn({ label = "Back to crate", onClick }) {
  return (
    <button className="back-btn" onClick={onClick}>← {label}</button>
  );
}

// ───────────────────────────── Certificate (shop item) ─────────────────────────────
function Certificate({ item, owned, affordable, onBuy }) {
  const cls = `cert ${owned ? "purchased" : ""} ${(!owned && !affordable) ? "locked" : ""}`;
  return (
    <button className={cls} onClick={onBuy} disabled={owned || !affordable}>
      <div className={`stamp ${item.accent}`}>{item.glyph}</div>
      <div className="body">
        <div className="sm-eyebrow">Certificate · Limited press</div>
        <div className="ttl">{item.title}</div>
        <div className="blurb">{item.blurb}</div>
      </div>
      <div className="price">
        {owned ? (
          <span>Pressed</span>
        ) : (
          <>
            <span className="num">{item.cost}</span>
            <span className="unit">♪ note{item.cost === 1 ? "" : "s"}</span>
          </>
        )}
      </div>
    </button>
  );
}

Object.assign(window, {
  Sleeve, Turntable, Tonearm, Waveform, QuestionCard,
  NotesPill, SettingsCog, TopBar, Brand, BackBtn, Certificate,
});
