/* Gift page · the recipient's private page · skeuomorphic mixtape player */

// Color map per song type
const JAM_PALETTES = {
  Roast:     { body: "#D4501A", bodyHighlight: "#FF7A3E", bodyShadow: "#8C2A0A", accent: "#D93616", labelTone: "warm" },
  Heartfelt: { body: "#C8553D", bodyHighlight: "#E87A60", bodyShadow: "#7A2A1C", accent: "#A8412E", labelTone: "warm" },
  Hype:      { body: "#F5C518", bodyHighlight: "#FFE873", bodyShadow: "#A88408", accent: "#D93616", labelTone: "neon" },
  Romantic:  { body: "#D85A8A", bodyHighlight: "#F590B5", bodyShadow: "#8A2E58", accent: "#A8412E", labelTone: "warm" },
};

// Cassette deck transport button
function DeckBtn({ children, onClick, active, primary, label }) {
  return (
    <button onClick={onClick} aria-label={label} style={{
      width: 52, height: 44, border: 0, borderRadius: 6,
      background: active ? "linear-gradient(180deg, #FF7A3E 0%, #D4501A 100%)" : "linear-gradient(180deg, #4a4a52 0%, #2a2a30 50%, #1a1a20 100%)",
      color: active ? "#fff" : "#FAEAC4",
      boxShadow: active
        ? "inset 0 -2px 0 rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.25), 0 0 12px rgba(255,122,62,0.5)"
        : "inset 0 -2px 0 rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12), 0 2px 4px rgba(0,0,0,0.3)",
      cursor: "pointer", display: "grid", placeItems: "center",
      fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.1em",
      transition: "transform 80ms, box-shadow .16s var(--ease-out)",
    }} onMouseDown={e => e.currentTarget.style.transform = "translateY(1px)"} onMouseUp={e => e.currentTarget.style.transform = ""} onMouseLeave={e => e.currentTarget.style.transform = ""}>
      {children}
    </button>
  );
}

// Local silent fallback avoids remote demo-audio failures in the prototype.
const SILENT_SAMPLE_AUDIO = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YQAAAAA=";
const SAMPLE_AUDIO = {
  Roast: SILENT_SAMPLE_AUDIO,
  Heartfelt: SILENT_SAMPLE_AUDIO,
  Hype: SILENT_SAMPLE_AUDIO,
  Romantic: SILENT_SAMPLE_AUDIO,
};

function LyricsCard({ sides, side, onSide, palette }) {
  return (
    <div className="ij-lyrics-card" style={{
      flex: "1 1 520px",
      padding: "22px 24px",
      borderRadius: 16,
      border: "1.5px solid var(--line-strong)",
      background: "var(--paper-2)",
      textAlign: "left",
    }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 14, flexWrap: "wrap" }}>
        <div>
          <span className="eyebrow">Lyric sheet</span>
          <h2 className="display" style={{ fontFamily: "var(--f-italic)", fontStyle: "italic", fontSize: 32, margin: "8px 0 0" }}>Side {side}</h2>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          {["A", "B"].map(s => (
            <button key={s} onClick={() => onSide(s)} className={side === s ? "chip solid" : "chip"} style={{
              cursor: "pointer",
              borderColor: side === s ? palette.accent : "var(--line-strong)",
              background: side === s ? palette.accent : "transparent",
              color: side === s ? "#fff" : "var(--ink)",
            }}>Side {s}</button>
          ))}
        </div>
      </div>
      <pre style={{
        margin: "18px 0 0",
        whiteSpace: "pre-wrap",
        fontFamily: "var(--f-sans)",
        fontSize: 16,
        lineHeight: 1.7,
        color: "var(--ink)",
      }}>{sides[side]}</pre>
    </div>
  );
}

// Copy-to-clipboard with visual feedback hook
function useCopyButton() {
  const [copied, setCopied] = React.useState(false);
  const copy = React.useCallback((text) => {
    const url = text || window.location.href;
    if (navigator.clipboard?.writeText) {
      navigator.clipboard.writeText(url).then(() => {
        setCopied(true);
        setTimeout(() => setCopied(false), 1800);
      }).catch(() => {});
    }
  }, []);
  return [copied, copy];
}

function GiftPage({ song = {}, onMakeYourOwn, onWaitlist }) {
  const {
    recipient = "Maya",
    title = "The Ballad of May-May",
    occasion = "30th birthday",
    senderName = "Jess",
    senderMessage = "Happy 30th, weirdo. You deserve to be sung about.",
    songType = "Roast",
    genre = "Pop anthem",
    duration = 54,
    lyrics: lyricsRaw,
    audioUrl,
  } = song;

  const lyrics = lyricsRaw || `[Verse 1]
She rolls in twenty minutes late...
(no lyrics provided)`;

  const palette = JAM_PALETTES[songType] || JAM_PALETTES.Roast;
  const [playing, setPlaying] = React.useState(false);
  const [t, setT] = React.useState(0);
  const [side, setSide] = React.useState("A");
  const [scrubbing, setScrubbing] = React.useState(false);
  const audioRef = React.useRef(null);
  const audioSrc = audioUrl || SAMPLE_AUDIO[songType] || SAMPLE_AUDIO.Roast;
  const simulateAudio = /^data:audio\//.test(audioSrc || "");
  const [copied, copy] = useCopyButton();

  // Wire <audio> to play/pause + scrub state
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a || simulateAudio) return;
    if (playing) a.play().catch(() => setPlaying(false));
    else a.pause();
  }, [playing, simulateAudio]);

  React.useEffect(() => {
    if (!playing || !simulateAudio) return undefined;
    const timer = setInterval(() => {
      setT((current) => {
        const next = Math.min(duration, current + 0.25);
        if (next >= duration) {
          setPlaying(false);
          return 0;
        }
        return next;
      });
    }, 250);
    return () => clearInterval(timer);
  }, [duration, playing, simulateAudio]);

  // Sync t with the audio's currentTime; clamp to song duration so the visual
  // progress bar lines up with the displayed track length even if the sample
  // file is longer.
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a || simulateAudio) return;
    const onTime = () => {
      const cur = Math.min(a.currentTime, duration);
      setT(cur);
      if (a.currentTime >= duration) {
        a.pause();
        setPlaying(false);
      }
    };
    const onEnd = () => { setPlaying(false); setT(0); };
    a.addEventListener("timeupdate", onTime);
    a.addEventListener("ended", onEnd);
    return () => {
      a.removeEventListener("timeupdate", onTime);
      a.removeEventListener("ended", onEnd);
    };
  }, [duration, simulateAudio]);

  const seek = React.useCallback((newT) => {
    const clamped = Math.max(0, Math.min(duration, newT));
    setT(clamped);
    if (audioRef.current) audioRef.current.currentTime = clamped;
  }, [duration]);
  const scrubToPointer = React.useCallback((e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const next = ((e.clientX - r.left) / r.width) * duration;
    seek(next);
    setSide(next / duration >= 0.52 ? "B" : "A");
  }, [duration, seek]);

  const fmt = (s) => `${Math.floor(s / 60)}:${String(Math.floor(s % 60)).padStart(2, "0")}`;
  const progress = t / duration;

  // Split lyrics into sides — A=verses up to bridge, B=bridge+chorus
  const sides = React.useMemo(() => {
    const lines = lyrics.split("\n");
    const bridgeIdx = lines.findIndex(l => /\[Bridge\]/i.test(l));
    if (bridgeIdx < 0) return { A: lyrics, B: "(B-side coming soon...)" };
    return {
      A: lines.slice(0, bridgeIdx).join("\n").trim(),
      B: lines.slice(bridgeIdx).join("\n").trim(),
    };
  }, [lyrics]);

  const cassetteTraits = createPrototypeCassetteTraits({
    seed: song.giftSlug || `${recipient}-${occasion}-${title}`,
    recipient,
    occasion,
    title,
    songType,
    genre,
    tier: song.tier || "quick",
    durationSeconds: duration,
  });
  const cassetteMeta = cassetteTraits.label.meta;
  const cassetteTitle = cassetteTraits.label.title;

  return (
    <div style={{ minHeight: "100vh", background: "var(--paper)", color: "var(--ink)" }}>
      <audio ref={audioRef} src={audioSrc} preload="metadata" crossOrigin="anonymous"/>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "20px 40px", borderBottom: "1px solid var(--line)" }}>
        <Logo/>
        <div style={{ fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.08em", opacity: 0.6 }}>
          PRIVATE GIFT PAGE · /jam/{recipient.toLowerCase()}-{occasion.replace(/\s+/g, '-').toLowerCase().slice(0, 12)}
        </div>
      </div>

      {/* Hero · the mixtape player */}
      <section style={{ padding: "50px 40px 30px" }}>
        <div style={{ maxWidth: 1100, margin: "0 auto", textAlign: "center" }}>
          <span className="tape" style={{ fontSize: 11 }}>A SONG FROM {senderName.toUpperCase()} · FOR {recipient.toUpperCase()}</span>
          <h1 className="display" style={{ fontSize: "clamp(40px, 5vw, 72px)", margin: "16px 0 4px", textWrap: "balance", fontFamily: "var(--f-italic)", fontStyle: "italic", color: palette.accent }}>
            "{title}"
          </h1>
          <p style={{ fontSize: 13, opacity: 0.7, fontFamily: "var(--f-mono)", letterSpacing: "0.08em" }}>
            {cassetteMeta}
          </p>
        </div>

        {/* The deck · giant cassette + transport */}
        <div className={playing ? "ij-gift-deck is-playing" : "ij-gift-deck"} style={{
          maxWidth: 920, margin: "40px auto 0",
          padding: "32px 36px 28px",
          borderRadius: 22,
          background: "linear-gradient(180deg, #2a2a32 0%, #15151a 50%, #2a2a32 100%)",
          boxShadow: "0 1px 0 rgba(255,255,255,0.08) inset, 0 30px 60px -28px rgba(0,0,0,0.55), 0 12px 24px -12px rgba(0,0,0,0.35)",
          position: "relative",
        }}>
          {/* Brushed-metal ridge highlights */}
          <div style={{ position: "absolute", left: 16, top: 16, fontFamily: "var(--f-mono)", fontSize: 10, letterSpacing: "0.16em", color: "#FAEAC4", opacity: 0.5 }}>INSIDEJAMS · STEREO DECK</div>

          {/* Cassette in the deck "bay" */}
          <GiftPlayer3D
            traits={cassetteTraits}
            playing={playing}
            progress={progress}
            duration={duration}
            scrubbing={scrubbing}
          />

          {/* Transport row */}
          <div style={{ marginTop: 20, display: "flex", alignItems: "center", gap: 14 }}>
            {/* Buttons */}
            <div style={{ display: "flex", gap: 6 }}>
              <DeckBtn label="Rewind" onClick={() => seek(t - 10)}>◀◀</DeckBtn>
              <DeckBtn label="Play" onClick={() => setPlaying(!playing)} active={playing} primary>
                {playing ? "❚❚" : "▶"}
              </DeckBtn>
              <DeckBtn label="Stop" onClick={() => { setPlaying(false); seek(0); }}>■</DeckBtn>
              <DeckBtn label="Fast forward" onClick={() => seek(t + 10)}>▶▶</DeckBtn>
            </div>

            {/* Scrubber */}
            <div style={{ flex: 1, padding: "10px 16px", background: "linear-gradient(180deg, #08080c 0%, #1a1a20 100%)", borderRadius: 8, boxShadow: "inset 0 2px 6px rgba(0,0,0,0.6)" }}>
              <div style={{ display: "flex", justifyContent: "space-between", fontFamily: "var(--f-mono)", fontSize: 10, color: "#FAEAC4", letterSpacing: "0.1em", marginBottom: 6 }}>
                <span>{fmt(t)}</span>
                <span style={{ opacity: 0.6 }}>{fmt(duration)}</span>
              </div>
              <div
                className={scrubbing ? "ij-tape-scrubber is-scrubbing" : "ij-tape-scrubber"}
                style={{ height: 6, background: "rgba(255,255,255,0.08)", borderRadius: 3, position: "relative", cursor: "grab", touchAction: "none" }}
                onPointerDown={(e) => {
                  e.currentTarget.setPointerCapture?.(e.pointerId);
                  setScrubbing(true);
                  scrubToPointer(e);
                }}
                onPointerMove={(e) => {
                  if (scrubbing) scrubToPointer(e);
                }}
                onPointerUp={() => setScrubbing(false)}
                onPointerCancel={() => setScrubbing(false)}>
                <div style={{ position: "absolute", inset: 0, width: `${progress * 100}%`, background: `linear-gradient(90deg, ${palette.accent} 0%, ${palette.bodyHighlight} 100%)`, borderRadius: 3, boxShadow: `0 0 8px ${palette.accent}` }}/>
                <div style={{ position: "absolute", left: `${progress * 100}%`, top: -4, width: 14, height: 14, borderRadius: "50%", background: "#FAEAC4", transform: "translateX(-50%)", boxShadow: "0 2px 4px rgba(0,0,0,0.5)" }}/>
              </div>
            </div>

          </div>
        </div>

        {/* Sender note · polaroid */}
        <div style={{ maxWidth: 920, margin: "32px auto 0", display: "flex", gap: 24, alignItems: "flex-start", justifyContent: "space-between", flexWrap: "wrap" }}>
          <div style={{
            background: "#fff",
            padding: "16px 18px 22px",
            transform: "rotate(-1.5deg)",
            boxShadow: "0 12px 30px -10px rgba(0,0,0,0.25)",
            border: "1px solid rgba(0,0,0,0.08)",
            maxWidth: 460,
            color: "#1A1A24",
          }}>
            <span style={{ fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase", color: palette.accent, opacity: 0.85 }}>A note from {senderName}</span>
            <p className="display" style={{ fontFamily: "var(--f-italic)", fontSize: 22, fontStyle: "italic", lineHeight: 1.35, marginTop: 10, color: "#1A1A24" }}>
              "{senderMessage}"
            </p>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            <button className="btn primary" style={{ background: palette.accent, borderColor: palette.accent }}>
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 1.5 L7 9.5 M3.5 6 L7 9.5 L10.5 6 M2 12 L12 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>
              Download MP3
            </button>
            <button className="btn ghost" onClick={() => copy()}>{copied ? "✓ Copied" : "Copy private link"}</button>
            <button className="btn ghost" onClick={() => {
              if (navigator.share) {
                navigator.share({ title: `A song for ${recipient}`, text: `${senderName} made you a song: "${title}"`, url: window.location.href }).catch(() => {});
              } else {
                copy();
              }
            }}>Share</button>
          </div>
        </div>

        <div style={{ maxWidth: 920, margin: "34px auto 0", display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 10 }}>
          {[
            ["Made for", recipient],
            ["From", senderName],
            ["Occasion", occasion],
            ["Page", "Private link"],
          ].map(([label, value]) => (
            <div key={label} style={{
              padding: "12px 14px",
              border: "1.5px solid var(--line)",
              borderRadius: 12,
              background: "var(--paper-2)",
              textAlign: "left",
            }}>
              <div style={{ fontFamily: "var(--f-mono)", fontSize: 9, letterSpacing: "0.12em", textTransform: "uppercase", opacity: 0.55 }}>{label}</div>
              <div style={{ marginTop: 4, fontWeight: 700, overflowWrap: "anywhere" }}>{value}</div>
            </div>
          ))}
        </div>
      </section>

      <section style={{ padding: "20px 40px 30px" }}>
        <div style={{ maxWidth: 920, margin: "0 auto", display: "flex", gap: 24, alignItems: "stretch", flexWrap: "wrap" }}>
          <div className={scrubbing ? "ij-lyrics-sync is-scrubbing" : "ij-lyrics-sync"} style={{ flex: "1 1 520px", display: "flex" }}>
            <LyricsCard sides={sides} side={side} onSide={setSide} palette={palette}/>
          </div>
          <div style={{
            flex: "0 1 280px",
            padding: "22px",
            borderRadius: 16,
            background: "#15151a",
            color: "#FAEAC4",
            boxShadow: "0 1px 0 rgba(255,255,255,0.08) inset, 0 18px 40px -24px rgba(0,0,0,0.55)",
          }}>
            <span style={{ fontFamily: "var(--f-mono)", fontSize: 10, letterSpacing: "0.14em", textTransform: "uppercase", opacity: 0.65 }}>Keepsake notes</span>
            <p style={{ margin: "14px 0 0", fontSize: 14, lineHeight: 1.6, opacity: 0.82 }}>
              This page is unlisted and made for sharing by link. Save the MP3, copy the page, or send it straight to the group chat when the moment is right.
            </p>
            <div style={{ marginTop: 18, display: "flex", flexWrap: "wrap", gap: 8 }}>
              {["UNLISTED", "MP3", "LYRICS", "NO ACCOUNT"].map(t => (
                <span key={t} style={{ fontFamily: "var(--f-mono)", fontSize: 9, letterSpacing: "0.08em", padding: "5px 8px", borderRadius: 999, border: "1px solid rgba(250,234,196,0.25)" }}>{t}</span>
              ))}
            </div>
          </div>
        </div>
      </section>

      {/* Subtle CTA */}
      <section style={{ padding: "80px 40px", textAlign: "center" }}>
        <div style={{ maxWidth: 720, margin: "0 auto" }}>
          <div className="display" style={{ fontSize: 36, fontFamily: "var(--f-italic)", fontStyle: "italic" }}>
            Got someone <em>else</em> in mind?
          </div>
          <p style={{ fontSize: 16, opacity: 0.7, marginTop: 10 }}>Make your own InsideJam. Starts at $29 with a private gift page.</p>
          <div style={{ display: "flex", gap: 12, justifyContent: "center", marginTop: 24 }}>
            <button className="btn primary" onClick={onMakeYourOwn}>Start their jam →</button>
            <button className="btn ghost" onClick={onWaitlist}>Card waitlist →</button>
          </div>
        </div>
      </section>

      <footer style={{ padding: "30px 40px", textAlign: "center", fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.08em", opacity: 0.55, borderTop: "1px solid var(--line)" }}>
        UNLISTED · NOT INDEXED · INSIDEJAMS © 2026
      </footer>
    </div>
  );
}

Object.assign(window, { GiftPage });
