'use client'

import { useState } from "react";
import { AudioLines, Loader2, RefreshCw } from "lucide-react";
import { Button } from "~/components/ui/button";
import { trpc } from "~/app/_trpc/Client";
import { useUploadThing } from "~/lib/uploadthing";
import { transcodeToAac } from "~/lib/ffmpeg/transcode";
import { toast } from "sonner";
import type { RouterOutputs } from "~/server/routers/_app";
import type { IterableElement } from "type-fest";

export default function ConvertToStreamButton(props: {
	track: IterableElement<RouterOutputs['music']['list']>;
}) {
	const { track } = props;
	const utils = trpc.useUtils();
	const [busy, setBusy] = useState(false);
	const [stage, setStage] = useState("");
	const [progress, setProgress] = useState(0);

	const setStream = trpc.music.setStream.useMutation({
		onSuccess: () => utils.music.list.invalidate(),
	});

	const { startUpload } = useUploadThing("musicUploader");

	async function handleConvert() {
		setBusy(true);
		setProgress(0);
		let currentStage = "Loading ffmpeg";
		const goto = (s: string) => {
			currentStage = s;
			setStage(s);
		};
		try {
			goto("Transcoding");
			const file = await transcodeToAac({
				sourceUrl: track.fileUrl,
				outputName: `${track.title || "track"}.m4a`,
				onProgress: setProgress,
			});

			goto("Uploading");
			const uploaded = await startUpload([file]);
			const res = uploaded?.[0];
			if (!res) throw new Error("Upload returned no file");

			goto("Saving");
			await setStream.mutateAsync({
				id: track.id,
				streamUrl: res.serverData.fileUrl,
				streamKey: res.serverData.fileKey,
				streamName: res.serverData.fileName,
			});
			toast("Streaming version saved");
		} catch (e) {
			console.error("[ConvertToStream] failed during", currentStage, e);
			const detail =
				e instanceof Error
					? e.message
					: typeof e === "string"
						? e
						: (() => {
								try {
									return JSON.stringify(e);
								} catch {
									return String(e);
								}
							})();
			toast(`Conversion failed (${currentStage}): ${detail || "see console for details"}`);
		} finally {
			setBusy(false);
			setStage("");
			setProgress(0);
		}
	}

	return (
		<div className="flex items-center gap-2">
			<Button type="button" variant="outline" size="sm" disabled={busy} onClick={handleConvert}>
				{busy ? (
					<Loader2 className="animate-spin" />
				) : track.streamUrl ? (
					<RefreshCw />
				) : (
					<AudioLines />
				)}
				{busy
					? `${stage}${stage === "Transcoding" && progress ? ` ${Math.round(progress * 100)}%` : "…"}`
					: track.streamUrl
						? "Re-generate stream"
						: "Generate stream (AAC)"}
			</Button>
			{track.streamUrl && !busy && (
				<span className="text-xs text-muted-foreground">Streaming version ready</span>
			)}
		</div>
	);
}
