import * as gql from "railbird-gql";
import { useCallback, useState } from "react";
// @ts-ignore
import { useCameraPermission } from "react-native-vision-camera";
import { showAlert } from "../../lib/alert-messages";

// TODO: #122 should decide on what values/labels go here.
enum GameType {
	FreePlay = "freePlay",
	StraightPool = "straightPool",
	NineBall = "nineBall",
}
// TODO: #122 should be int -- inch value of table size.
enum TableSize {
	NineFoot = "nineFoot",
	EightFoot = "eightFoot",
	SevenFoot = "sevenFoot",
}

interface VideoUserInputMeta {
	sessionName: string;
	gameType: GameType | null;
	tableSize: TableSize | null;
}

interface VideoFlowInputParams extends VideoUserInputMeta {
	videoId?: number;
}

function useDropdown<T>(
	initialValue: T | null,
	options: Array<{ label: string; value: T }>,
	closeOthers: () => void,
) {
	const [isOpen, setIsOpen] = useState(false);
	const [value, setValue] = useState<T | null>(initialValue);
	const [optionsList, setOptionsList] = useState(options);

	const toggleOpen = useCallback(() => {
		if (!isOpen) {
			closeOthers();
		}
		setIsOpen(!isOpen);
	}, [isOpen, closeOthers]);

	return {
		isOpen,
		toggleOpen,
		value,
		setValue,
		optionsList,
		setOptionsList,
		setIsOpen,
	};
}

export const useVideoDetails = ({
	params: {
		mode,
		videoId,
		sessionName: initialSessionName,
		gameType: initialGameType,
		tableSize: initialTableSize,
	},
	navigation,
}) => {
	const initialState = {
		sessionName: initialSessionName || "",
		gameType: initialGameType || null,
		tableSize: initialTableSize || null,
	};
	const { hasPermission, requestPermission } = useCameraPermission();

	const [sessionName, setSessionName] = useState<string>(
		initialState.sessionName || "",
	);

	const closeAllDropdowns = useCallback(() => {
		gameType.setIsOpen(false);
		tableSize.setIsOpen(false);
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);

	const gameType = useDropdown<GameType | null>(
		initialState.gameType,
		[
			{ label: "Free Play", value: GameType.FreePlay },
			{ label: "Straight Pool", value: GameType.StraightPool },
			{ label: "Nine Ball", value: GameType.NineBall },
		],
		closeAllDropdowns,
	);

	const tableSize = useDropdown<TableSize | null>(
		initialState.tableSize,
		[
			{ label: `9'`, value: TableSize.NineFoot },
			{ label: `8'`, value: TableSize.EightFoot },
			{ label: `7'`, value: TableSize.SevenFoot },
		],
		closeAllDropdowns,
	);

	const [TerminateUploadStream, { loading, error }] =
		gql.useTerminateUploadStreamMutation();

	const handleSubmit = async () => {
		if (mode === "start-video" && !hasPermission) {
			requestPermission();
			return showAlert("camera");
		}

		if (mode === "start-video") {
			const params: VideoFlowInputParams = {
				sessionName,
				gameType: gameType.value,
				tableSize: tableSize.value,
			};
			navigation.push("Camera", params);
		} else {
			try {
				await TerminateUploadStream({
					variables: {
						videoId,
						videoName: sessionName,
						tableSize: tableSize.value,
						gameType: gameType.value,
					},
				});
				navigation.push("Tabs");
			} catch (err) {
				showAlert("terminateUpload");
			}
		}
	};

	return {
		sessionName,
		setSessionName,
		gameType,
		tableSize,
		handleSubmit,
		loading,
		error,
	};
};
