import { useRef, useState, useEffect } from "react";
import { Play, Pause, Check, Volume2, Music2, X, Waves, Settings2 } from "lucide-react";
import { MG_MUSIC, SFX_STYLES } from "../remotion/mg/catalog.mjs";
import { useStore } from "../store";

type Track = { id: string; label: string; file: string; genre: string; mood: string; bpm: number; durationSec: number; blurb: string; gradient: string };
const TRACKS = MG_MUSIC as Track[];
type SfxStyle = { id: string; label: string; icon: string; blurb: string };
const STYLES = SFX_STYLES as SfxStyle[];
// a representative cue to preview each style (so the chip "sounds like" what it does)
const STYLE_DEMO: Record<string, string> = { designed: "swoosh", cinematic: "whoosh", clean: "pop", punchy: "impact", soft: "chime", retro: "glitch", off: "" };

// a deterministic static "waveform" silhouette for a card at rest (no audio analysis needed)
const restBar = (i: number) => 22 + (Math.sin(i * 1.7) * 0.5 + 0.5) * 64 + ((i * 41) % 23);

// The Background-music panel — browse the library, preview any track, pick one (or "No music").
// The chosen track loops softly under the whole video (wired in EditorComposition).
export function MusicLibrary() {
  const music = useStore((s) => s.music);
  const musicVolume = useStore((s) => s.musicVolume);
  const setMusic = useStore((s) => s.setMusic);
  const setMusicVolume = useStore((s) => s.setMusicVolume);
  const musicFadeInMs = useStore((s) => s.musicFadeInMs);
  const musicFadeOutMs = useStore((s) => s.musicFadeOutMs);
  const setMusicFade = useStore((s) => s.setMusicFade);
  const sfxStyle = useStore((s) => s.sfxStyle);
  const setSfxStyle = useStore((s) => s.setSfxStyle);
  const [preview, setPreview] = useState<string | null>(null);
  const audioRef = useRef<HTMLAudioElement | null>(null);
  const sfxRef = useRef<HTMLAudioElement | null>(null);
  const playSfx = (file: string) => { if (!file) return; try { sfxRef.current?.pause(); sfxRef.current = new Audio("/sfx/" + file + ".mp3"); sfxRef.current.volume = 0.85; void sfxRef.current.play(); } catch { /* ignore */ } };

  const stop = () => { audioRef.current?.pause(); audioRef.current = null; setPreview(null); };
  const togglePreview = (m: Track) => {
    if (preview === m.id) { stop(); return; }
    audioRef.current?.pause();
    const a = new Audio("/music/" + m.file);
    a.loop = true; a.volume = 0.9;
    a.play().catch(() => { /* autoplay blocked until a gesture — this IS a gesture, so fine */ });
    a.onended = () => setPreview(null);
    audioRef.current = a; setPreview(m.id);
  };
  useEffect(() => () => { audioRef.current?.pause(); }, []);

  const selected = TRACKS.find((m) => m.id === music) || null;

  return (
    <div className="flex h-full flex-col">
      <style>{`@keyframes elgeq{0%,100%{transform:scaleY(0.28)}50%{transform:scaleY(1)}}.elg-eq{transform-origin:bottom;animation:elgeq .75s ease-in-out infinite}`}</style>

      <div className="px-3 pt-3 pb-2">
        <div className="flex items-center gap-1.5 text-[12px] font-semibold text-fg"><Waves size={13} className="text-primary" /> Sound &amp; Music</div>
        <div className="mt-0.5 text-[10px] text-fg-subtle">Control every scene's sound effects and the background track in one place.</div>
      </div>

      <div className="flex-1 space-y-2 overflow-y-auto px-3 pb-3">
        {/* ── Motion-graphics SOUND STYLE — re-skins every scene's entrance sound at once ── */}
        <div className="rounded-xl border border-border bg-white/[0.02] p-2.5">
          <div className="mb-1 flex items-center gap-1.5 text-[11px] font-semibold text-fg"><Settings2 size={12} className="text-primary" /> Motion sound</div>
          <div className="mb-2 text-[10px] text-fg-subtle">Every scene plays a sound on its entrance. Pick a style to re-skin them all — tap to hear it.</div>
          <div className="grid grid-cols-2 gap-1.5">
            {STYLES.map((s) => {
              const on = (sfxStyle || "designed") === s.id;
              return (
                <button key={s.id} onClick={() => { setSfxStyle(s.id); playSfx(STYLE_DEMO[s.id]); }} title={s.blurb}
                  className={"flex items-center gap-1.5 rounded-lg border px-2 py-1.5 text-left transition " + (on ? "border-primary bg-primary/10" : "border-border hover:border-primary/50")}>
                  <span className="text-[14px] leading-none">{s.icon}</span>
                  <span className="min-w-0">
                    <span className="block truncate text-[11px] font-medium text-fg">{s.label}</span>
                    <span className="block truncate text-[9px] text-fg-subtle">{s.blurb}</span>
                  </span>
                  {on && <Check size={12} className="ml-auto shrink-0 text-primary" />}
                </button>
              );
            })}
          </div>
          <div className="mt-2 text-[9.5px] text-fg-subtle">Fine-tune one scene: select it on the timeline → the inspector's <span className="text-fg-muted">Sound</span> section (or click its 🔊 badge).</div>
        </div>

        {/* ── BACKGROUND MUSIC ── */}
        <div className="flex items-center gap-1.5 pt-1 text-[11px] font-semibold text-fg"><Music2 size={12} className="text-primary" /> Background music <span className="text-[9px] font-normal text-fg-subtle">— loops under the video</span></div>
        {/* No music */}
        <button onClick={() => setMusic("")}
          className={"flex w-full items-center gap-2 rounded-lg border px-3 py-2 text-left transition " + (!music ? "border-primary bg-primary/10" : "border-border hover:border-primary/50")}>
          <X size={14} className="text-fg-muted" /><span className="text-[12px] text-fg">No music</span>
          {!music && <Check size={13} className="ml-auto text-primary" />}
        </button>

        {TRACKS.map((m) => {
          const isSel = music === m.id, isPlaying = preview === m.id;
          return (
            <div key={m.id} onClick={() => setMusic(m.id)} title={`Use “${m.label}” — or drag onto the timeline`}
              draggable onDragStart={(e) => { e.dataTransfer.setData("application/x-elg-music", m.id); e.dataTransfer.effectAllowed = "copy"; }}
              className={"group relative cursor-grab overflow-hidden rounded-xl border transition active:cursor-grabbing " + (isSel ? "border-primary ring-1 ring-primary/50" : "border-border hover:border-primary/60")}>
              <div className="absolute inset-0" style={{ background: m.gradient }} />
              <div className="absolute inset-0 bg-black/40 transition group-hover:bg-black/30" />
              <div className="relative p-3">
                <div className="flex items-start justify-between gap-2">
                  <div className="min-w-0">
                    <div className="flex items-center gap-1.5 truncate text-[13px] font-semibold text-white drop-shadow-sm">
                      {m.label}{isSel && <Check size={13} className="shrink-0 text-white" />}
                    </div>
                    <div className="truncate text-[10px] text-white/85">{m.genre} · {m.mood}</div>
                  </div>
                  <button onClick={(e) => { e.stopPropagation(); togglePreview(m); }} title={isPlaying ? "Stop preview" : "Preview"}
                    className="grid h-8 w-8 shrink-0 place-items-center rounded-full bg-white/95 text-black shadow-lg transition hover:scale-105 hover:bg-white">
                    {isPlaying ? <Pause size={15} /> : <Play size={15} className="ml-0.5" />}
                  </button>
                </div>

                {/* live equalizer / waveform */}
                <div className="mt-2.5 flex h-6 items-end gap-[2.5px]">
                  {Array.from({ length: 32 }).map((_, i) => (
                    <span key={i} className={"flex-1 rounded-sm " + (isPlaying ? "elg-eq bg-white/85" : "bg-white/55")}
                      style={isPlaying ? { height: "100%", animationDelay: `${(i % 9) * 70}ms`, animationDuration: `${0.6 + (i % 5) * 0.1}s` } : { height: `${restBar(i)}%` }} />
                  ))}
                </div>

                <div className="mt-2 flex items-center justify-between gap-2 text-[10px] text-white/85">
                  <span className="truncate">{m.blurb}</span>
                  <span className="shrink-0 tabular-nums">{m.bpm} BPM · {m.durationSec}s</span>
                </div>
              </div>
            </div>
          );
        })}
      </div>

      {/* volume + status footer (only when a track is chosen) */}
      {selected && (
        <div className="border-t border-border px-3 py-2.5">
          <div className="flex items-center gap-2">
            <Volume2 size={14} className="shrink-0 text-fg-muted" />
            <input type="range" min={0} max={1} step={0.05} value={musicVolume} onChange={(e) => setMusicVolume(Number(e.target.value))} className="h-1 flex-1 accent-primary" />
            <span className="w-7 text-right text-[10px] tabular-nums text-fg-muted">{Math.round(musicVolume * 100)}</span>
          </div>
          <div className="mt-2 grid grid-cols-2 gap-x-3 gap-y-1">
            <div className="flex items-center gap-1.5"><span className="w-12 shrink-0 text-[10px] text-fg-subtle">Fade in</span><input type="range" min={0} max={4000} step={100} value={musicFadeInMs} onChange={(e) => setMusicFade(Number(e.target.value), musicFadeOutMs)} className="h-1 flex-1 accent-primary" /><span className="w-7 shrink-0 text-right text-[10px] tabular-nums text-fg-muted">{(musicFadeInMs / 1000).toFixed(1)}s</span></div>
            <div className="flex items-center gap-1.5"><span className="w-12 shrink-0 text-[10px] text-fg-subtle">Fade out</span><input type="range" min={0} max={4000} step={100} value={musicFadeOutMs} onChange={(e) => setMusicFade(musicFadeInMs, Number(e.target.value))} className="h-1 flex-1 accent-primary" /><span className="w-7 shrink-0 text-right text-[10px] tabular-nums text-fg-muted">{(musicFadeOutMs / 1000).toFixed(1)}s</span></div>
          </div>
          <div className="mt-1.5 truncate text-[10px] text-fg-subtle"><span className="text-fg-muted">{selected.label}</span> loops under your video, fading in &amp; out. Pick “No music” to remove.</div>
        </div>
      )}
    </div>
  );
}
