import { useMutation } from "@tanstack/react-query";
import { useEffect, useEffectEvent, useRef } from "react";
import { toast } from "sonner";
import type { AudioCodec, VideoCodec } from "@/utils/codec-detection";
import { useTRPC } from "@/utils/trpc";

interface UsePlaybackSessionOptions {
	titleId?: string;
	episodeId?: string;
	supportedCodecs: {
		video: VideoCodec[];
		audio: AudioCodec[];
	};
	selectedTracks?: {
		audio?: number;
		subtitle?: number;
	};
	maxResolution?: "480p" | "720p" | "1080p" | "2160p";
}

export function usePlaybackSession(options: UsePlaybackSessionOptions) {
	const sessionId = useRef<string>(
		sessionStorage.getItem("activePlaybackSessionId"),
	);
	// const hasInitiatedSession = useRef(false);
	const trpc = useTRPC();
	const { mutate, isError, data, error, isPending } = useMutation(
		trpc.playback.createSession.mutationOptions({
			onError: (error) => {
				toast.error(`Failed to create playback session: ${error.message}`);
			},
			onSuccess: (data) => {
				sessionId.current = data.sessionId;
				sessionStorage.setItem("activePlaybackSessionId", data.sessionId);
			},
		}),
	);
	const { mutate: mutateStopSession } = useMutation(
		trpc.playback.stopSession.mutationOptions({}),
	);

	const onCreateSession = useEffectEvent(() => {
		mutate({
			titleId: options.titleId,
			episodeId: options.episodeId,
			supportedVideoCodecs: options.supportedCodecs.video,
			supportedAudioCodecs: options.supportedCodecs.audio,
			subtitleStreamIndex: options.selectedTracks?.subtitle,
			maxResolution: options.maxResolution,
		});
	});

	const onDisposed = useEffectEvent(() => {
		if (!sessionId.current) return;
		mutateStopSession({
			sessionId: sessionId.current,
		});
		sessionStorage.removeItem("activePlaybackSessionId");
	});
	useEffect(() => {
		if (sessionId.current) return;
		onCreateSession();
		return () => {
			onDisposed();
		};
	}, []);

	if (isError) {
		return {
			isLoading: isPending,
			isError: isError,
			error: error,
		};
	}

	return {
		isLoading: isPending,
		isError: isError,
		error: error,
		data: data,
	};
}
