'use client'

import { useEffect, useRef, useState } from "react";
import { useTheme } from "next-themes";
import type WaveSurfer from "wavesurfer.js";
import { Download, Loader2, Pause, Play } from "lucide-react";
import { Button } from "~/components/ui/button";
import { toast } from "sonner";

function formatTime(seconds: number) {
	if (!Number.isFinite(seconds)) return "0:00";
	const m = Math.floor(seconds / 60);
	const s = Math.floor(seconds % 60);
	return `${m}:${s.toString().padStart(2, "0")}`;
}

function cssVar(name: string, fallback: string) {
	if (typeof window === "undefined") return fallback;
	const v = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
	return v || fallback;
}

function waveColors() {
	return {
		waveColor: cssVar("--muted-foreground", "#9ca3af"),
		progressColor: cssVar("--primary", "#e2761b"),
		cursorColor: cssVar("--foreground", "#111827"),
	};
}

export default function AudioPlayer(props: {
	/** Streaming-friendly source the player actually plays. */
	src: string;
	/** Original high-quality file offered via the download button. */
	downloadUrl: string;
	downloadName: string;
}) {
	const containerRef = useRef<HTMLDivElement>(null);
	const wsRef = useRef<WaveSurfer | null>(null);
	const [playing, setPlaying] = useState(false);
	const [current, setCurrent] = useState(0);
	const [duration, setDuration] = useState(0);
	const [ready, setReady] = useState(false);
	const [downloading, setDownloading] = useState(false);
	const { resolvedTheme } = useTheme();

	useEffect(() => {
		let ws: WaveSurfer | null = null;
		let cancelled = false;
		setReady(false);
		setCurrent(0);

		(async () => {
			const WaveSurferClass = (await import("wavesurfer.js")).default;
			if (cancelled || !containerRef.current) return;
			ws = WaveSurferClass.create({
				container: containerRef.current,
				url: props.src,
				height: 44,
				barWidth: 2,
				barGap: 1,
				barRadius: 2,
				normalize: true,
				cursorWidth: 1,
				...waveColors(),
			});
			wsRef.current = ws;
			ws.on("ready", () => {
				setReady(true);
				setDuration(ws?.getDuration() ?? 0);
			});
			ws.on("play", () => setPlaying(true));
			ws.on("pause", () => setPlaying(false));
			ws.on("finish", () => setPlaying(false));
			ws.on("timeupdate", (t) => setCurrent(t));
		})();

		return () => {
			cancelled = true;
			ws?.destroy();
			wsRef.current = null;
		};
	}, [props.src]);

	// Re-tint the waveform when the user toggles light/dark.
	useEffect(() => {
		wsRef.current?.setOptions(waveColors());
	}, [resolvedTheme]);

	function togglePlay() {
		wsRef.current?.playPause();
	}

	async function handleDownload() {
		setDownloading(true);
		try {
			// The download file is cross-origin, so the <a download> attribute is
			// ignored — fetch it as a blob to force a real download.
			const res = await fetch(props.downloadUrl);
			if (!res.ok) throw new Error(`HTTP ${res.status}`);
			const blob = await res.blob();
			const url = URL.createObjectURL(blob);
			const a = document.createElement("a");
			a.href = url;
			a.download = props.downloadName;
			document.body.appendChild(a);
			a.click();
			a.remove();
			URL.revokeObjectURL(url);
		} catch (e) {
			toast(`Download failed: ${e instanceof Error ? e.message : "unknown error"}`);
		} finally {
			setDownloading(false);
		}
	}

	return (
		<div className="flex items-center gap-3 rounded-lg border bg-transparent px-3 py-2">
			<Button
				type="button"
				size="icon"
				variant="ghost"
				aria-label={playing ? "Pause" : "Play"}
				disabled={!ready}
				onClick={togglePlay}
			>
				{playing ? <Pause /> : <Play />}
			</Button>

			<span className="w-10 shrink-0 text-right font-mono text-xs text-muted-foreground tabular-nums">
				{formatTime(current)}
			</span>

			<div className="relative flex-1">
				<div ref={containerRef} className="w-full" />
				{!ready && (
					<div className="absolute inset-0 flex items-center">
						<div className="h-7 w-full animate-pulse rounded bg-muted-foreground/15" />
					</div>
				)}
			</div>

			<span className="w-10 shrink-0 font-mono text-xs text-muted-foreground tabular-nums">
				{formatTime(duration)}
			</span>

			<Button
				type="button"
				size="icon"
				variant="ghost"
				aria-label="Download lossless file"
				title="Download lossless file"
				disabled={downloading}
				onClick={handleDownload}
			>
				{downloading ? <Loader2 className="animate-spin" /> : <Download />}
			</Button>
		</div>
	);
}
