import { findBy } from "@nontara/language-codes";
import { useQuery } from "@tanstack/react-query";
import { FileVideo, Languages, Volume2 } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { Card } from "@/components/ui/card";
import {
	Select,
	SelectContent,
	SelectItem,
	SelectTrigger,
	SelectValue,
} from "@/components/ui/select";
import { useTRPC } from "@/utils/trpc";

type MediaTracksSelectorProps = {
	titleId: string;
	onTracksChange?: (tracks: {
		video?: number;
		audio?: number;
		subtitle?: number;
	}) => void;
};

export default function MediaTracksSelector({
	titleId,
	onTracksChange,
}: MediaTracksSelectorProps) {
	const trpc = useTRPC();

	const { data, isLoading, error } = useQuery(
		trpc.media.getTracks.queryOptions({ titleId }),
	);

	const [selectedVideo, setSelectedVideo] = useState<string>("");
	const [selectedAudio, setSelectedAudio] = useState<string>("");
	const [selectedSubtitle, setSelectedSubtitle] = useState<string>("");

	// Set default selections when data loads
	useEffect(() => {
		if (!data || data.length === 0) return;

		const mediaItem = data[0];

		// Set default video track (first one)
		if (mediaItem.tracks.video.length > 0 && !selectedVideo) {
			setSelectedVideo(mediaItem.tracks.video[0].streamIndex.toString());
		}

		// Set default audio track (default or first one)
		if (mediaItem.tracks.audio.length > 0 && !selectedAudio) {
			const defaultAudio = mediaItem.tracks.audio.find((t) => t.isDefault);
			const audioToSelect = defaultAudio || mediaItem.tracks.audio[0];
			setSelectedAudio(audioToSelect.streamIndex.toString());
		}

		// Set default subtitle track if there's a default one
		if (mediaItem.tracks.subtitle.length > 0 && !selectedSubtitle) {
			const defaultSubtitle = mediaItem.tracks.subtitle.find(
				(t) => t.isDefault,
			);
			if (defaultSubtitle) {
				setSelectedSubtitle(defaultSubtitle.streamIndex.toString());
			}
		}
	}, [data, selectedVideo, selectedAudio, selectedSubtitle]);

	// Notify parent of track changes
	useEffect(() => {
		if (onTracksChange) {
			onTracksChange({
				video: selectedVideo ? Number.parseInt(selectedVideo, 10) : undefined,
				audio: selectedAudio ? Number.parseInt(selectedAudio, 10) : undefined,
				subtitle:
					selectedSubtitle && selectedSubtitle !== "none"
						? Number.parseInt(selectedSubtitle, 10)
						: undefined,
			});
		}
	}, [selectedVideo, selectedAudio, selectedSubtitle, onTracksChange]);

	// Memoized language name lookup to avoid unnecessary re-renders
	const languageNames = useMemo(() => {
		const cache = new Map<string, string>();

		const getLanguageName = (code: string | null): string | null => {
			if (!code) return null;

			// Check cache first
			const cached = cache.get(code);
			if (cached) {
				return cached;
			}

			const lowerCode = code.toLowerCase().trim();

			// Try to find language by code length
			let language: ReturnType<typeof findBy> | undefined;
			if (lowerCode.length === 3) {
				// Try ISO 639-3 first, then ISO 639-2
				language = findBy("3", lowerCode) || findBy("2", lowerCode);
			} else if (lowerCode.length === 2) {
				// Try ISO 639-1 first, then ISO 639-2
				language = findBy("1", lowerCode) || findBy("2", lowerCode);
			}

			// Get name or fallback to uppercase code
			const name = language?.name || code.toUpperCase();
			cache.set(code, name);
			return name;
		};

		return getLanguageName;
	}, []);

	// If loading or error, don't render anything
	if (isLoading || error || !data || data.length === 0) {
		return null;
	}

	// Get the first media item (usually there's only one)
	const mediaItem = data[0];

	const formatVideoTrack = (
		track: (typeof mediaItem.tracks.video)[number],
	): string => {
		const parts = [];
		if (track.width && track.height) {
			parts.push(`${track.width}x${track.height}`);
		}
		if (track.codecName) {
			parts.push(track.codecName.toUpperCase());
		}
		return parts.length > 0 ? parts.join(" • ") : `Stream ${track.streamIndex}`;
	};

	const formatAudioTrack = (
		track: (typeof mediaItem.tracks.audio)[number],
	): string => {
		const parts = [];
		if (track.language) {
			const langName = languageNames(track.language);
			if (langName) {
				parts.push(langName);
			}
		}
		if (track.title) {
			parts.push(track.title);
		}
		if (track.channels) {
			parts.push(`${track.channels}ch`);
		}
		if (track.codecName) {
			parts.push(track.codecName.toUpperCase());
		}
		if (track.isDefault) {
			parts.push("(Default)");
		}
		return parts.length > 0 ? parts.join(" • ") : `Stream ${track.streamIndex}`;
	};

	const formatSubtitleTrack = (
		track: (typeof mediaItem.tracks.subtitle)[number],
	): string => {
		const parts = [];
		if (track.language) {
			const langName = languageNames(track.language);
			if (langName) {
				parts.push(langName);
			}
		}
		if (track.title) {
			parts.push(track.title);
		}
		if (track.isForced) {
			parts.push("(Forced)");
		}
		if (track.isDefault) {
			parts.push("(Default)");
		}
		return parts.length > 0 ? parts.join(" • ") : `Stream ${track.streamIndex}`;
	};

	return (
		<div className="space-y-3 sm:space-y-4">
			<h2 className="font-semibold text-lg sm:text-xl">Media Tracks</h2>

			<Card className="border-border/50 bg-card/50 p-4 backdrop-blur-sm sm:p-6">
				<div className="flex flex-col gap-4">
					{/* Video Tracks */}
					{mediaItem.tracks.video.length > 0 && (
						<div className="space-y-2">
							<div className="flex items-center gap-2 font-medium text-muted-foreground text-sm">
								<FileVideo className="h-4 w-4" />
								Video Track
							</div>
							<Select value={selectedVideo} onValueChange={setSelectedVideo}>
								<SelectTrigger className="w-full">
									<SelectValue placeholder="Select video track" />
								</SelectTrigger>
								<SelectContent>
									{mediaItem.tracks.video.map((track) => (
										<SelectItem
											key={track.streamIndex}
											value={track.streamIndex.toString()}
										>
											{formatVideoTrack(track)}
										</SelectItem>
									))}
								</SelectContent>
							</Select>
						</div>
					)}

					{/* Audio Tracks */}
					{mediaItem.tracks.audio.length > 0 && (
						<div className="space-y-2">
							<div className="flex items-center gap-2 font-medium text-muted-foreground text-sm">
								<Volume2 className="h-4 w-4" />
								Audio Track
							</div>
							<Select value={selectedAudio} onValueChange={setSelectedAudio}>
								<SelectTrigger className="w-full">
									<SelectValue placeholder="Select audio track" />
								</SelectTrigger>
								<SelectContent>
									{mediaItem.tracks.audio.map((track) => (
										<SelectItem
											key={track.streamIndex}
											value={track.streamIndex.toString()}
										>
											{formatAudioTrack(track)}
										</SelectItem>
									))}
								</SelectContent>
							</Select>
						</div>
					)}

					{/* Subtitle Tracks */}
					{mediaItem.tracks.subtitle.length > 0 && (
						<div className="space-y-2">
							<div className="flex items-center gap-2 font-medium text-muted-foreground text-sm">
								<Languages className="h-4 w-4" />
								Subtitle Track
							</div>
							<Select
								value={selectedSubtitle}
								onValueChange={setSelectedSubtitle}
							>
								<SelectTrigger className="w-full">
									<SelectValue placeholder="No subtitle" />
								</SelectTrigger>
								<SelectContent>
									<SelectItem value="none">No subtitle</SelectItem>
									{mediaItem.tracks.subtitle.map((track) => (
										<SelectItem
											key={track.streamIndex}
											value={track.streamIndex.toString()}
										>
											{formatSubtitleTrack(track)}
										</SelectItem>
									))}
								</SelectContent>
							</Select>
						</div>
					)}
				</div>
			</Card>
		</div>
	);
}
