import CopyOutputButton from "@/components/button/CopyOutputButton";
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
import InputMessage from "@/components/input/InputMessage";
import KeywordInput from "@/components/input/KeywordInput";
import OutputMessage from "@/components/input/OutputMessage";
import PreservationSliders from "@/components/input/PreservationSliders";
import { useDecodeADFGVX, useEncodeADFGVX } from "@/hooks/combination/ADFGVXHooks";
import { TextInput, useToaster } from "mattrixwv-components";
import { useEffect, useState } from "react";
import { useDebouncedCallback } from "use-debounce";


export default function ADFGVXInputs(){
	const [ capitals, setCapitals ] = useState(true);
	const [ symbols, setSymbols ] = useState(true);
	const [ whitespace, setWhitespace ] = useState(true);
	const [ encoding, setEncoding ] = useState(true);
	const [ keyword, setKeyword ] = useState("");
	const [ squareKeyword, setSquareKeyword ] = useState("");
	const [ input, setInput ] = useState("");
	const [ output, setOutput ] = useState("");

	const { addDanger } = useToaster();
	const encodeADFGVXMutation = useEncodeADFGVX();
	const decodeADFGVXMutation = useDecodeADFGVX();


	//Do coding with a delay
	const performCoding = useDebouncedCallback(() => {
		if((input === "") || (keyword.length < 2)){
			setOutput("");
			return;
		}
		if(encoding){
			encodeADFGVXMutation.mutate({
				encoding,
				preserveSymbols: symbols,
				preserveWhitespace: whitespace,
				preserveCapitals: capitals,
				keyword,
				squareKeyword,
				inputString: input
			});
		}
		else{
			decodeADFGVXMutation.mutate({
				encoding,
				preserveSymbols: symbols,
				preserveWhitespace: whitespace,
				preserveCapitals: capitals,
				keyword,
				squareKeyword,
				inputString: input
			});
		}
	}, 1000);


	//Code when input changes
	useEffect(() => {
		performCoding();
	}, [capitals, encoding, keyword, squareKeyword, input, performCoding, symbols, whitespace]);

	//When the mutation is successful set the new output
	useEffect(() => {
		if(decodeADFGVXMutation.isSuccess){
			setOutput(decodeADFGVXMutation.data.outputString ?? "");
			decodeADFGVXMutation.reset();
		}
		if(encodeADFGVXMutation.isSuccess){
			setOutput(encodeADFGVXMutation.data.outputString ?? "");
			encodeADFGVXMutation.reset();
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [ decodeADFGVXMutation.isSuccess, encodeADFGVXMutation.isSuccess, decodeADFGVXMutation.data, encodeADFGVXMutation.data ]);

	//When the mutation has an error, display the message
	useEffect(() => {
		if(decodeADFGVXMutation.isError){
			addDanger(decodeADFGVXMutation.error.message);
			decodeADFGVXMutation.reset();
		}
		if(encodeADFGVXMutation.isError){
			addDanger(encodeADFGVXMutation.error.message);
			encodeADFGVXMutation.reset();
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [ decodeADFGVXMutation.isError, encodeADFGVXMutation.isError ]);


	return (
		<div
			className="flex flex-col items-center justify-center gap-y-4"
		>
			<div
				className="flex flex-row items-center justify-center gap-x-8"
			>
				<PreservationSliders
					capitals={capitals}
					setCapitals={setCapitals}
					symbols={symbols}
					setSymbols={setSymbols}
					whitespace={whitespace}
					setWhitespace={setWhitespace}
				/>
			</div>
			<div
				className="flex flex-col items-center justify-center"
			>
				<EncodingDecodingButton
					encoding={encoding}
					setEncoding={setEncoding}
				/>
			</div>
			<div
				className="flex flex-col items-center justify-center gap-y-8"
			>
				<KeywordInput
					value={keyword}
					onChange={setKeyword}
				/>
				<TextInput
					placeholder="Square Keyword"
					value={squareKeyword}
					onChange={(e) => setSquareKeyword(e.target.value)}
					labelClassName="bg-(--bg-color) text-(--text-color)"
				/>
				<InputMessage
					value={input}
					onChange={setInput}
				/>
				<OutputMessage
					value={output}
					onChange={setOutput}
				/>
				<CopyOutputButton
					value={output}
				/>
			</div>
		</div>
	);
}
