const AUTOCOMPLETE_API_KEY = "a17b542575f34d8795f90a23d650349f";

const getImage = async (url) => {
	const image = new Image();
	
	const imageLoadPromise = new Promise(
		resolve => {
			image.onload = () => {
				resolve();
			}
			
			image.src = url;
		}
	);
	
	await imageLoadPromise;
	
	return image;
}

const setHighestPossibleFontSize = (
	context,
	text,
	font,
	desiredSize,
	maxWidth
) => {
	let currentSize = desiredSize;
	
	context.font = `${currentSize}px ${font}`;
	
	while (context.measureText(text).width > maxWidth && currentSize > 0) {
		currentSize -= 1;
		context.font = `${currentSize}px ${font}`;
	}
	
	return desiredSize;
}

const createCheck = async (
	context,
	canvas,
	x,
	y
) => {
	const checkImage = await getImage("static/images/check.webp");
	
	const size = canvas.width * 0.0215;
	
	context.drawImage(
		checkImage,
		x, y,
		size, size
	);
}

const fillCanvas = async () => {
	const firstPageCanvas = document.getElementById("page-1-canvas");
	const firstPageContext = firstPageCanvas.getContext("2d");
	
	const secondPageCanvas = document.getElementById("page-2-canvas");
	const secondPageContext = secondPageCanvas.getContext("2d");
	
	const firstPageImage = await getImage("static/images/page1.webp");
	const secondPageImage = await getImage("static/images/page2.webp");
	
	firstPageContext.drawImage(
		firstPageImage,
		0, 0,
		firstPageCanvas.width, firstPageCanvas.height
	);
	
	secondPageContext.drawImage(
		secondPageImage,
		0, 0,
		secondPageImage.width, secondPageImage.height
	);
	
	// BEGIN First page
	
	// Local office name
	const officeName = $("#city").val();
	
	setHighestPossibleFontSize(
		firstPageContext,
		officeName,
		"Open Sans",
		firstPageCanvas.height * 0.015,
		firstPageCanvas.width * 0.76
	);
	
	firstPageContext.fillStyle = "#000";
	firstPageContext.fillText(
		officeName,
		firstPageCanvas.width * 0.12, firstPageCanvas.height * 0.205
	);
	
	// We're always doing the presidential one, so always make this check
	const checkboxSharedY = firstPageCanvas.width * 0.12;
	
	await createCheck(
		firstPageContext,
		firstPageCanvas,
		checkboxSharedY,
		firstPageCanvas.height * 0.3665
	);
	
	const roundCheckSharedY = firstPageCanvas.width * 0.185;
	let electionDate = "";
	
	switch ($("#card-type").val()) {
		case "1. kolo": 
			createCheck(
				firstPageContext,
				firstPageCanvas,
				roundCheckSharedY,
				firstPageCanvas.height * 0.3853
			);
			
			electionDate = "13. ledna 2023 - 14. ledna 2023";
			
			break;
		case "2. kolo":
			createCheck(
				firstPageContext,
				firstPageCanvas,
				roundCheckSharedY,
				firstPageCanvas.height * 0.404
			);
			
			electionDate = "27. ledna 2023 - 28. ledna 2023";
			
			break;
	}
	
	const personalInfoSharedX = firstPageCanvas.width * 0.37;
	
	// Election dates
	
	setHighestPossibleFontSize(
		firstPageContext,
		electionDate,
		"Open Sans",
		firstPageCanvas.height * 0.013,
		firstPageCanvas.width * 0.51
	);
	
	firstPageContext.fillText(
		electionDate,
		personalInfoSharedX, firstPageCanvas.height * 0.505
	);
	
	// Name
	
	const fullName = (
		$("#name").val()
		+ " "
		+ $("#surname").val()
	);
	
	setHighestPossibleFontSize(
		firstPageContext,
		fullName,
		"Open Sans",
		firstPageCanvas.height * 0.013,
		firstPageCanvas.width * 0.51
	);
	
	firstPageContext.fillText(
		fullName,
		personalInfoSharedX, firstPageCanvas.height * 0.535
	);
	
	// Birth date
	
	const birthDate = new Date($("#birth-date").val());
	const formattedBirthDate = (
		birthDate.getDate()
		+ ". "
		+ birthDate.getMonth()
		+ ". "
		+ birthDate.getFullYear()
	);
	
	setHighestPossibleFontSize(
		firstPageContext,
		formattedBirthDate,
		"Open Sans",
		firstPageCanvas.height * 0.013,
		firstPageCanvas.width * 0.51
	);
	
	firstPageContext.fillText(
		formattedBirthDate,
		personalInfoSharedX, firstPageCanvas.height * 0.565
	);
	
	// Street + number
	
	const address = (
		$("#street").val()
		+ ", "
		+ $("#zip").val()
		+ " "
		+ $("#city").val()
	);
	
	setHighestPossibleFontSize(
		firstPageContext,
		address,
		"Open Sans",
		firstPageCanvas.height * 0.013,
		firstPageCanvas.width * 0.51
	);
	
	firstPageContext.fillText(
		address,
		personalInfoSharedX, firstPageCanvas.height * 0.597
	);
	
	// Pick up options
	
	secondPageContext.fillStyle = "#000";
	
	switch ($("#receiving-type").val()) {
		case "Vyzvednout osobně":
			createCheck(
				firstPageContext,
				firstPageCanvas,
				checkboxSharedY,
				firstPageCanvas.height * 0.7195
			);
			
			break;
		case "Předat osobě, která se prokáže plnou mocí":
			createCheck(
				firstPageContext,
				firstPageCanvas,
				checkboxSharedY,
				firstPageCanvas.height * 0.751
			);
			
			break;
		
		// END First page
		// BEGIN Second page
		
		case "Zaslat na adresu trvalého pobytu":
			createCheck(
				secondPageContext,
				secondPageCanvas,
				checkboxSharedY,
				secondPageCanvas.height * 0.08475
			);
			
			break;
		case "Zaslat jinam":
			createCheck(
				secondPageContext,
				secondPageCanvas,
				checkboxSharedY,
				secondPageCanvas.height * 0.1152
			);
			
			const deliveryAddress = $("#other-address-conditional").val();
			
			setHighestPossibleFontSize(
				secondPageContext,
				deliveryAddress,
				"Open Sans",
				secondPageCanvas.height * 0.013,
				secondPageCanvas.width * 0.51
			);
			
			secondPageContext.fillText(
				deliveryAddress,
				secondPageCanvas.width * 0.145, secondPageCanvas.height * 0.155
			);
			
			break;
	}
}

$(window).ready(
	() => {
		const { jsPDF } = window.jspdf;
		
		const currentDate = new Date();
		$("#current-date").val(
			currentDate.getDate()
			+ ". "
			+ currentDate.getMonth()
			+ ". "
			+ currentDate.getFullYear()
		);
		
		const autocompleteWidget = new autocomplete.GeocoderAutocomplete(
			document.getElementById("address-autocomplete"), 
			AUTOCOMPLETE_API_KEY,
			{
				"lang": "cs",
				"filter": {
					"countrycode": ["cz"]
				},
				"placeholder": "🔎  Vyhledat adresu..."
			}
		);

		autocompleteWidget.on(
			"select",
			(location) => {
				const properties = location.properties;
				
				const street = (
					(properties.street !== undefined) ?
					properties.street : ""
				);
				const houseNumber = (
					(properties.housenumber !== undefined) ?
					properties.housenumber : ""
				);
				
				document.getElementById("street").value = (
					street
					+ (
						(street !== "") ?
						" " : ""
					)
					+ houseNumber
				);
				
				if (properties.city !== undefined) document.getElementById("city").value = properties.city;
				if (properties.postcode !== undefined) document.getElementById("zip").value = properties.postcode;
			}
		);
		
		$("#receiving-type").on(
			"change",
			(event) => {
				if (event.target.value === "Zaslat jinam") {
					$("#other-address-conditional").css("display", "block");
				} else {
					$("#other-address-conditional").css("display", "none");
				}
			}
		);
		
		$("#create-filled-form").on(
			"click",
			async (event) => {
				$("#form-wrapper input,#form-wrapper select").attr("disabled", true);
				// We already know this, don't waste time looking it up.
				// Repeating ourselves once is fine here.
				$(event.target).attr("disabled", true);
				
				await fillCanvas();
				
				await new Promise(
					resolve => { $("#step1").fadeOut(200, resolve); }
				);
				$("#step1").css("display", "none");
				
				await new Promise(
					resolve => { $("#step2").fadeIn(200, resolve); }
				);
				
				$("#signature").jSignature();
			}
		);
		
		$("#signature-undo").on(
			"click",
			(event) => {
				$("#signature").jSignature("reset");
			}
		);
		
		$("#show-document").on(
			"click",
			async (event) => {
				await new Promise(
					resolve => { $("#step2").fadeOut(200, resolve); }
				);
				$("#step2").css("display", "none");
				
				await new Promise(
					resolve => { $("#canvas-wrapper").fadeIn(200, resolve); }
				);
			}
		);
		
		$("#back-to-step2").on(
			"click",
			async (event) => {
				await new Promise(
					resolve => { $("#canvas-wrapper").fadeOut(200, resolve); }
				);
				$("#canvas-wrapper").css("display", "none");
				
				await new Promise(
					resolve => { $("#step2").fadeIn(200, resolve); }
				);
			}
		);
		
		$("#finish").on(
			"click",
			async (event) => {
				// Canvas
				
				const secondPageCanvas = document.getElementById("page-2-canvas");
				const secondPageContext = secondPageCanvas.getContext("2d");
				
				// Date
				
				const desiredCurrentDate = $("#current-date").val()
				
				setHighestPossibleFontSize(
					secondPageContext,
					desiredCurrentDate,
					"Open Sans",
					secondPageCanvas.height * 0.013,
					secondPageCanvas.width * 0.32
				);
				
				secondPageContext.fillText(
					desiredCurrentDate,
					secondPageCanvas.width * 0.56, secondPageCanvas.height * 0.232
				);
				
				// Location
				
				const location = $("#signature-location").val();
				
				setHighestPossibleFontSize(
					secondPageContext,
					location,
					"Open Sans",
					secondPageCanvas.height * 0.013,
					secondPageCanvas.width * 0.31
				);
				
				secondPageContext.fillText(
					location,
					secondPageCanvas.width * 0.155, secondPageCanvas.height * 0.232
				);
				
				// Signature
				
				const signature = await getImage($("#signature").jSignature("getData"));
				
				const signatureWidth = secondPageCanvas.width * 0.315;
				const signatureHeight = (
					signature.height
					* (signatureWidth / signature.width)
				);
				
				console.log(signatureHeight, signatureWidth, signature);
				
				secondPageContext.drawImage(
					signature,
					secondPageCanvas.width * 0.57, secondPageCanvas.height * 0.31 - signatureHeight,
					signatureWidth, signatureHeight
				);
				
				// UI
				
				await new Promise(
					resolve => { $("#step2").fadeOut(200, resolve); }
				);
				$("#step2").css("display", "none");
				
				const city = $("#city").val();
				
				if (city in OFFICES) {
					const office = OFFICES[city];
					
					$("#office-address-direction").html(
						office["address"]["street"]
						+ ", "
						+ office["address"]["zip"]
						+ " "
						+ office["address"]["city"]
					);
					
					$("#office-ds-id-direction").html(office["ds_id"]);
					
					$("#found-office").css("display", "block");
				} else {
					$("#not-found-office").css("display", "block");
				}
				
				await new Promise(
					resolve => { $("#step3").fadeIn(200, resolve); }
				);
			}
		);
		
		$("#download-pdf").on(
			"click",
			() => {
				const pdfDocument = new jsPDF({
					orientation: "portrait",
					unit: "pt",
					format: "a4"
				});
				
				pdfDocument.addImage(
					document.getElementById("page-1-canvas"),
					"JPEG",
					0, 0,
					595.28, 841.89
				);
				
				pdfDocument.addPage();
				
				pdfDocument.addImage(
					document.getElementById("page-2-canvas"),
					"JPEG",
					0, 0,
					595.28, 841.89
				);
				
				pdfDocument.save("Přihláška k volebnímu průkazu.pdf");
			}
		);
	}
);