var resourceName;

// main elements jquery selectors
var main = {}

// tablet element jquery selectors
var tablet = {}

var currentVehicle = {
	fleetId: -1,
	municipality: '',
}

var departmentData = [];
var isMedia = false;
var rewardsModels = [];

// TABLET VARS
var checkedOutRecords = [];
var oosRecords = [];
var checkedOutDataTable;
var oosDataTable;
var mpAssignmentsDataTable;
var mpAssignmentsDataTabletTable;
var tabletDepartment;
var tabletSupervisor;
var playerName;
var tabletTime;
var timeDisplayHandle;
var userName = "ERROR: UKN.";
const easterEggProbability = 0.005;

const directions = {
	N: 'NORTH',
	E: 'EAST',
	S: 'SOUTH',
	W: 'WEST',
	NE: 'NORTH EAST',
	NW: 'NORTH WEST',
	SE: 'SOUTH EAST',
	SW: 'SOUTH WEST',
	'---': '-----',
};


$(document).ready(function () {
	// set jquery selectors to table
	main = {
		municipalitySelectorMain: 		$('#municipality-selector-main'),
		municipalitySelectorContainer:	$('#municipality-selector-container'),
		vehicleSelectorMain: 			$('#vehicle-selector-main'),
		vehicleTypeMarked:				$('#vehicle-type-marked'),
		vehicleCustomizeMain: 			$('#vehicle-customize-main'),
		vehicleCustomizeCancel:			$('#vehicle-customize-cancel'),
		vehicleCustomizeCheckout:		$('#vehicle-customize-checkout'),
		myVehicleMain:					$('#my-vehicle-main'),
		myVehicleReturn:				$('.return-my-vehicle'),
		myVehicleInfoStatus:			$('#my-vehicle-info-status'),
		dialogContainer: 				$('#dialog-container'),
		loadingDialogContainer: 		$('#loading-dialog-container'),
		mpAssignmentsButton:			$('#mp-assignments-button'),
		mpAssignmentsContainer:			$('#mp-assignments-container'),
		trackingOverlayContainer: 		$('#tracking-overlay-container'),
		trackingOverlayMunicipality:	$('#tracking-overlay-municipality'),
		trackingOverlayModel:			$('#tracking-overlay-model'),
		trackingOverlayDirection:		$('#tracking-overlay-direction'),
		trackingOverlaySpeed:			$('#tracking-overlay-speed'),
		trackingOverlayLapse:			$('#tracking-overlay-lapse'),
		trackingOverlayLocation:		$('#tracking-overlay-location'),
	}

	tablet = {
		tablet: 						$('#tablet'),
		mpAssignmentsContainer: 		$('#mp-assignments-tablet-container'),
		mpAssignmentTable:				$('#mp-assignments-table'),
		checkedOutContainer:			$('#checkedout-container'),
		checkedOutTable:				$('#checkedout-table'),
		oosContainer: 					$('#oos-container'),
		oosTable:						$('#oos-table'),
		manageVehicleContainer:			$('#manage-vehicle-container'),
		dateTimeLoading:				$('#date-time-loading'),
		oosFormContainer: 				$('#oos-form-container'),
		oosForm: 						$('#oos-form'),
		tabletLoadingContainer: 		$('#tablet-loading-container'),
	}


	// Datatable Custom Filters
	jQuery.fn.dataTable.ext.order['direction-speed'] = function(settings, col) {
		return this.api().column(col, {order: 'index'}).nodes().map(function(td, i) {
			const directionRemoved = td.innerHTML.replace(/\b(?:N|S|E|W|NW|NE|SE|SW)\b\s*/, '');
			return directionRemoved;
		});
	};	

	// main
	main.municipalitySelectorMain.hide();
	main.vehicleSelectorMain.hide();
	main.myVehicleMain.hide();
	main.vehicleCustomizeMain.hide();
	main.dialogContainer.hide();
	main.loadingDialogContainer.hide();
	main.trackingOverlayContainer.hide();
	
	//	tablet
    tablet.tablet.hide();
	tablet.oosContainer.hide();
	tablet.mpAssignmentsContainer.hide();
	tablet.manageVehicleContainer.hide();
	tablet.oosFormContainer.hide();
	tablet.tabletLoadingContainer.hide();
	
	// CLICK HANDLERS
	$('#vehicle-selector-return').click( function() { 
		sendDataToLua('SetUpdateRequests', false);
		main.vehicleSelectorMain.hide();
		main.municipalitySelectorMain.show();
		main.vehicleCustomizeMain.hide();
		main.dialogContainer.hide();
		main.loadingDialogContainer.hide();
	});
	
	$('#municipality-selector-exit').click( function() { 
		sendDataToLua('Close', undefined)
	});
		
	main.vehicleCustomizeCancel.click( function() { 
		main.vehicleCustomizeMain.hide();
	});
	
	main.vehicleCustomizeCheckout.click( function() { 
		if ($(this).text() === "Checkout"){
			sendDataToLua('ValidateCheckout', { fleetId: currentVehicle.fleetId, municipality: currentVehicle.municipality })
		} else {
			if ($(this).data('isNearStation')){
				//SWAP
				sendDataToLua('CheckIn', undefined)
				setTimeout(() => {
				sendDataToLua('ValidateCheckout', { fleetId: currentVehicle.fleetId, municipality: currentVehicle.municipality })
				}, 500);
			} else {
				$('#dialog-header').html("Swap Prohibited");
				$('#dialog-msg').html("You have to be near a station to checkout a new vehicle.");
				main.dialogContainer.fadeIn();
			}
		}
		sendDataToLua('SetUpdateRequests', false);
	});
	
	$('#dialog-close-button').click( function() { 
		if (main.vehicleCustomizeMain.is(':visible')){
			main.vehicleCustomizeMain.hide();
		} else {
			sendDataToLua('Close', undefined)
			main.myVehicleMain.hide();
		}
		main.dialogContainer.hide();
	});
	
	main.mpAssignmentsButton.click( function() {
		const isOpen = $(this).attr("is-open") === "true";
		const $icon = $(this).find(".icon-rotate");
		var autoHeight = main.mpAssignmentsContainer.css('height', 'auto').height();

        if (!isOpen) {
			main.mpAssignmentsContainer.height(0).animate({ height: autoHeight, marginTop: "0" }, 250, function() {
				$(this).height('auto');
			});
			$icon.css("transform", "rotate(180deg)");
			main.municipalitySelectorContainer.css("filter", "blur(2px)");
			main.municipalitySelectorContainer.css("pointer-events", "none"); 
        } else {
            main.mpAssignmentsContainer.animate({ height: "0", marginTop: "70%" }, 250);
			$icon.css("transform", "rotate(0deg)");
			main.municipalitySelectorContainer.css("filter", "none");
			main.municipalitySelectorContainer.css("pointer-events", "auto"); 
        }

		$(this).attr("is-open", !isOpen);
	});
		
	// My Vehicle Button Handlers
	$('#my-vehicle-exit').click( function() { 
		sendDataToLua('Close', undefined)
	});
	
	$('#my-vehicle-checkin').click( function() { 
		sendDataToLua('CheckIn', undefined)
	});
	
	$('#my-vehicle-respawn').click( function() { 
		sendDataToLua('RespawnVehicle', undefined)
	});
	
	$('#my-vehicle-extend').click( function() { 
		sendDataToLua('ExtendReservation', undefined)
	});
	
	$('#my-vehicle-stolen').click( function() { 
		sendDataToLua('ReportStolen', { vehicleNetId: null, state: true } );
	});
	
	$('#my-vehicle-allotment').click( function() { 
		sendDataToLua('ViewingAllotment', true)
		main.vehicleCustomizeCheckout.text('Swap');
		main.myVehicleMain.hide();
		main.municipalitySelectorMain.show();
		main.myVehicleReturn.show();
	});

	main.myVehicleReturn.click( function() { 
		sendDataToLua('ViewingAllotment', false)
		main.municipalitySelectorMain.hide();
		main.vehicleSelectorMain.hide();
		main.vehicleCustomizeMain.hide();
		main.myVehicleMain.show();
	});
	
	// Tablet button handlers
	$('#tablet-close').click( function () {
		sendDataToLua('CloseTablet', undefined);
	});	

	$('#manage-vehicle-close').click( function () {
		tablet.manageVehicleContainer.fadeOut();
	});
	
	$(document).on('click', '#view-checkedout', function() {
		tablet.oosContainer.hide();
		tablet.mpAssignmentsContainer.hide();
		tablet.checkedOutContainer.show();
		
		tablet.dateTimeLoading.fadeIn();
		
		// active button formatting
		$('#view-checkedout').addClass('active');
		$('#view-oos').removeClass('active');
		$('.view-mp-assignments').removeClass('active');
	});
	
	$(document).on('click', '#view-oos', function() {
		tablet.checkedOutContainer.hide();
		tablet.mpAssignmentsContainer.hide();
		tablet.oosContainer.show();
		
		tablet.dateTimeLoading.fadeIn();
		
		// active button formatting
		$('.view-mp-assignments').removeClass('active');
		$('#view-checkedout').removeClass('active');
		$('#view-oos').addClass('active');
	});
	
	$(document).on('click', '.view-mp-assignments', function() {
		tablet.checkedOutContainer.hide();
		tablet.oosContainer.hide();
		tablet.mpAssignmentsContainer.show();
		generateMpAssignmentsTabletTable(checkedOutRecords);
		
		tablet.dateTimeLoading.fadeIn();
		
		// active button formatting
		$('#view-checkedout').removeClass('active');
		$('#view-oos').removeClass('active');
		$('.view-mp-assignments').addClass('active');
	});
			
	$('#manage-vehicle-oos').click( function() {
		const targetRecord = checkedOutRecords[$(this).data('record-id')];
		openNewOOS(targetRecord);
	});
	
	$('#manage-vehicle-stolen').click( function() {
		const button = $(this);
		const targetRecord = checkedOutRecords[$(this).data('record-id')];
		const vehicleNetId = targetRecord.vehicleNetId;

		if (button.data('state') === 'stolen') {
			sendDataToLua('ReportStolen', { vehicleNetId: vehicleNetId, state: true });
			button.data('state', 'recovered');
			button.html('<i class="fa-solid fa-truck-ramp-box"></i> Report Recovered');
		} else {
			sendDataToLua('ReportStolen', { vehicleNetId: vehicleNetId, state: false });
			button.data('state', 'stolen');
			button.html('<i class="fa-solid fa-person-circle-exclamation"></i> Report Stolen');
		}
	});
	
	$('#oos-close-btn').click( function() { 
		tablet.oosFormContainer.fadeOut();
	});

	tablet.oosForm.submit( function(event) {
        event.preventDefault();
		var fleetId = $(this).data('fleet-id');
		var vehicleNetId = $(this).data('vehicle-net-id');
		
		var formData = { };
		$(this).find("input, select, textarea").each(function() {
			var name = $(this).attr("name");
			var value = $(this).val();

			if (name !== undefined) {
				formData[name] = value;
			}
		});
		
		if (formData.return === "Indefinite"){
			formData.return = "12/31/9999 23:59"
		}

		const newOOSData = {
			fleetId: fleetId,
			vehicleNetId: vehicleNetId,
			category: formData.category,
			operator: formData.operator,
			reporter: formData.reporter,
			recordDateTime: $('#date-time-value').text(),
			returnDateTime: formData.return,
			notes: formData.notes.toUpperCase(),
		}

		sendDataToLua('NewOOS', newOOSData);
		tablet.oosFormContainer.fadeOut();
	});

	$("#duration").change(function() {
		var selectedOptionValue = parseInt($(this).val());
		var formattedDate;
		
		if (selectedOptionValue > -1) {
			var currentDate = new Date();
			currentDate.setUTCHours(currentDate.getUTCHours() + selectedOptionValue);			
			var month = (currentDate.getUTCMonth() + 1).toString();
			var day = currentDate.getUTCDate().toString().padStart(2, '0');
			var year = currentDate.getUTCFullYear();
			
			var hours = currentDate.getUTCHours();
			var minutes = currentDate.getUTCMinutes().toString().padStart(2, '0');
			
			formattedDate = `${month}/${day}/${year} ${hours}:${minutes}`;
			
		} else {
			formattedDate = "Indefinite"
		}
		$('#return').val(formattedDate);
	});

	// Close display on escape.
	$(document).keyup(function(event) {
		if (event.keyCode === 27) 
		{
			sendDataToLua('Close', undefined);
			sendDataToLua('CloseTablet', undefined);
		}
	} );

	// NUI EVENT
    window.addEventListener('message', function (event) {
		if (event.data.action === 'OpenDisplay') {
			// reverse swap / allotment mode
			main.vehicleCustomizeCheckout.text('Checkout');
			main.vehicleCustomizeCheckout.data('isNearStation', true);
			main.myVehicleReturn.hide();
			const data = event.data.department;
			const department = event.data.departmentKey;
			const districtCoverageData = event.data.districtCoverageData;
			
			setDepartmentData(data, true);
			
			if (department === "SP_lp" || department === "SP"){
				$('#municipality-selector-header').text("San Andreas State Police")
			} else {
				$('#municipality-selector-header').text("Departments")
			}
			
			if (department === "MP"){
				main.mpAssignmentsButton.show()
				generateMpAssignmentsTable(districtCoverageData);
			} else {
				main.mpAssignmentsButton.hide()
			}

			main.municipalitySelectorMain.show();
        } else if (event.data.action === 'Close') {
			main.vehicleCustomizeMain.hide();
			main.dialogContainer.hide();
			main.loadingDialogContainer.hide();
			main.municipalitySelectorMain.fadeOut();
			main.vehicleSelectorMain.fadeOut();
			main.myVehicleMain.fadeOut();
        } else if (event.data.action === 'SetDepartmentData') {
			setDepartmentData(event.data.department, false)
		} else if (event.data.action === 'OpenReservation'){
			// Generate district coverage table
			const department = event.data.departmentKey;
			const districtCoverageData = event.data.districtCoverageData;
			
			if (department === "MP"){
				generateMpAssignmentsTable(districtCoverageData);
			}

			// set data on element for later checking if swap is allowed
			main.vehicleCustomizeCheckout.data('isNearStation', event.data.isNearStation)
			
			const reservation = event.data.reservation;
			if (!departmentData[reservation.municipality]) {
				console.log('Reservation municipality not found.');
				return;
			}
			
			var found = false;
			const vehicles = departmentData[reservation.municipality]
			for (const vehicle of vehicles) {
				if (vehicle.fleetId === reservation.fleetId) {
					found = true;
					
					var municipality = reservation.municipality
					if (municipality === "SP_lp"){
						municipality = "SP";
					}
					
					$('#my-vehicle-image').attr('src', 'textures/vehicles/' + vehicle.image + '.jpg');
					$('#my-vehicle-info-vehicle').text(vehicle.fullName);
					$('#my-vehicle-info-fleetId').text(reservation.fleetId);
					$('#my-vehicle-info-department').text(municipality);
					$('#my-vehicle-info-location').text(reservation.location);
					
					const currentTimeMillis = new Date().getTime() / 1000;
					const elapsedTimeMillis = (currentTimeMillis - reservation.checkedOutTime) * 12;
					const elapsedTimeHours = (elapsedTimeMillis / (60 * 60)).toFixed(1);

					$('#my-vehicle-info-duration').text(elapsedTimeHours);
					break;
				}
			}
			if (found){
				main.myVehicleMain.show();

				currentVehicle.fleetId = reservation.fleetId;
				currentVehicle.municipality = reservation.municipality;

				if (reservation.timer === false) {
					main.myVehicleInfoStatus.text("Reserved")
									  .removeClass("amber red")
									  .addClass("green");
				} else if (reservation.timer > 0) {
					main.myVehicleInfoStatus.text("Expiring - " + reservation.timer + ' minutes remain.')
									  .removeClass("green red")
									  .addClass("amber");
				} else {
					main.myVehicleInfoStatus.text("Expired - holding for occupancy.")
									  .removeClass("green amber")
									  .addClass("red");
				}
			} else {
				console.log('Reservation vehicle not found.');
				main.municipalitySelectorMain.show();
			}
		} else if (event.data.action === 'UpdateReservationStatus'){
			if ($("#my-vehicle-main").is(":visible")) {
				const status = event.data.status
				if (status === false){
					main.myVehicleInfoStatus.text("Reserved")
												.removeClass("amber")
												.removeClass("red")
												.addClass("green");
				} else if (status > 0) {
					main.myVehicleInfoStatus.text("Expiring - " + status + ' minutes remain.')
												.removeClass("green")
												.removeClass("red")
												.addClass("amber");
				} else {
					main.myVehicleInfoStatus.text("Expired - holding for occupancy.")
												.removeClass("green")
												.removeClass("amber")
												.addClass("red");
				}
			}
		} else if (event.data.action === 'SetDialogActive'){
			var headerMsg = event.data.header;

			var randomValue = Math.random();
			if (headerMsg === "We're Sorry..." && randomValue < easterEggProbability) {
				headerMsg = "I'm sorry, Dave. I'm afraid I can't do that.";
			}
			$('#dialog-header').html(headerMsg);
			$('#dialog-msg').html(event.data.message);
			main.dialogContainer.fadeIn();
		} else if (event.data.action === 'SetLoadingState') {
			$('#loading-message').html(event.data.message);
			if (event.data.state){
				main.loadingDialogContainer.fadeIn();
			} else {
				main.loadingDialogContainer.fadeOut();
			}
		// TABLET /////////////////////////////////////
		} else if (event.data.action === "SendTabletRecords"){
			usersName = event.data.usersName
			// clock display
			updateClock();
			clearInterval(timeDisplayHandle);
			timeDisplayHandle = setInterval(updateClock, 60000);
			
			tablet.tablet.fadeIn();

			// checked out table
			checkedOutRecords = event.data.tabletTable.checkedOutData;
			if (tablet.checkedOutContainer.is(':visible')) {
				processCheckedOut(checkedOutRecords);
			}

			// oos table
			oosRecords = event.data.tabletTable.oosData;
			if (tablet.oosContainer.is(':visible')) {
				processOosRecords(oosRecords);
			}
		} else if (event.data.action === 'SetTabletState') {
            if (!event.data.state) {
				if (tablet.mpAssignmentsContainer.is(':visible')){
					$('#view-checkedout').trigger('click');
				}
				tablet.manageVehicleContainer.fadeOut();
				tablet.oosFormContainer.fadeOut();
                tablet.tablet.fadeOut();
				clearInterval(timeDisplayHandle);
            } else {
				tabletDepartment = event.data.department;
				tabletSupervisor = event.data.supervisor;
				tablet.tabletLoadingContainer.fadeIn();
                tablet.tablet.fadeIn();
			}
		} else if (event.data.action === 'SetTrackingOverlayState'){
			if (event.data.state) {
				main.trackingOverlayContainer.fadeIn();
			} else {
				main.trackingOverlayContainer.fadeOut();
				
				main.trackingOverlayLocation.html('------------------------ LOADING ------------------------')
				main.trackingOverlayLapse.html('------------------------');
				main.trackingOverlaySpeed.html('------------------------');
				main.trackingOverlayDirection.html('------------------------');
				main.trackingOverlayModel.html('------------------------');
				main.trackingOverlayMunicipality.html('------------------------');
			}
		} else if (event.data.action === "SetTrackingOverlayData"){
			const trackingData 		= event.data.trackingData;
			
			const location 			= trackingData.location.toUpperCase();
			const timeElapsed 		= formattedTimeElapse(trackingData.locationAge, main.trackingOverlayLapse).toUpperCase();
			const direction 		= directions[trackingData.direction];
			const modelFormatted 	= trackingData.model.toUpperCase();
			var municipality 		= trackingData.municipalityFullName.toUpperCase();
			
			main.trackingOverlayLocation.html(location);
			main.trackingOverlayLapse.html(timeElapsed);
			main.trackingOverlaySpeed.html(trackingData.speed + ' MPH');
			main.trackingOverlayDirection.html(direction);
			main.trackingOverlayModel.html(modelFormatted);
			
			if (municipality === "SAN ANDREAS ENVIRONMENTAL POLICE") {
				municipality = "SAEP";
			} else if (municipality === "MARKED" || municipality === "LOW PROFILE & UNMARKED") {
				municipality = "STATE POLICE";
			}
			
			main.trackingOverlayMunicipality.html(municipality);
		} else if (event.data.action === "SetBypassInfo"){
			isMedia = event.data.isMedia;
			rewardsModels = event.data.rewardsModels || [ ];
		} else if (event.data.action === "SendConfigVars"){
			resourceName = event.data.resourceName;
		}
	});
});

// This function is used to send data back through to the LUA side 
function sendDataToLua(name, data) {
	$.post( "https://"+ resourceName +"/" + name, JSON.stringify( data ), function( datab ) {
        if (datab != "ok") {
            console.log(datab);
        } else if (typeof callback === 'function') {
            callback(datab); 
        }
	} );
}

// add municipality selector items, called when opened
function addMunicipalityElement(key, fullName, image, count){
	main.municipalitySelectorContainer.append(
		'<div class="municipality-grid-item" data-key="' + key + '" data-full-name="' + fullName + '">' +
			'<img src="textures/municipalities/' + image + '.jpg">' +
			'<div class="image-text">' + fullName + '</div>' +
			'<div class="image-text-counter larger-counter">' + (count === 0 ? '' : count) + '</div>' +
		'</div>'
	);
}

// add vehicle element dynamically, called on municipality selection
function addVehicleElement(vehicle){
	const containerSelector = vehicle.unmarked ? '#vehicle-selector-unmarked' : '#vehicle-selector-marked';
	$(containerSelector).append(
		'<div class="vehicle-grid-item' + (vehicle.currentCount >= vehicle.maxCount && !isMedia && !rewardsModels.includes(vehicle.model) ? ' disabled' : '') + '" data-key="' + vehicle.fleetId + '" data-full-name="' + vehicle.fullName +'">'+
			'<img src="textures/vehicles/' + vehicle.image + '.jpg">' +
			'<div class="image-text">' + vehicle.abbrevName + '</div>' +
			'<div class="image-text-counter">' + vehicle.currentCount + '/' + vehicle.maxCount + (vehicle.oosCount > 0 ? '<br><span class="oos-grid-display">' + vehicle.oosCount + ' OOS</span>' : '') + '</div>' +
			(vehicle.restricted ? 
				'<div class="image-restrictions"><i class="fa-solid fa-lock"></i></div>' +
				'<div class="restriction-overlay">' +
					'<div class="restrictions-inner">' +
						'<p class="restrictions-header"><i class="fa-solid fa-lock"></i> Restricted Usage</p>' +
						'<p class="restrictions-msg">Division or Supervisory Use Only.</p>' +
					'</div>' +
				'</div>' : '') +
		'</div>'
	);
}


 // update vehicle counts element wise on currently open municipality's vehicle selector
function updateVehicleCountElement(vehicle) {
	if (currentVehicle.municipality && departmentData[currentVehicle.municipality]) {		
        const vehicleItem = $('.vehicle-grid-item[data-key="' + vehicle.fleetId + '"]');
        if (vehicleItem.length) {
            const vehicleCounter = vehicleItem.find('.image-text-counter');
            vehicleCounter.html(vehicle.current + '/' + vehicle.max + (vehicle.oos > 0 ? '<br><span class="oos-grid-display">' + vehicle.oos + ' OOS</span>' : ''));

            if (vehicle.current >= vehicle.max && !isMedia && !rewardsModels.includes(vehicle.model)) {
                vehicleItem.addClass('disabled');
            } else {
                vehicleItem.removeClass('disabled');
            }
        }
	}
}

 // update municipality counts element wise on currently open municipality's vehicle selector
function updateMunicipalityCountElement(key, count) {
	const municipalityItem = $('.municipality-grid-item[data-key="' + key + '"]');
	if (municipalityItem.length) {
		const municipalityCounter = municipalityItem.find('.image-text-counter');
		municipalityCounter.html((count === 0 ? '' : count));
	}
}

// store department data, if municipality is currently open update elements individually
function setDepartmentData(data, addDepartmentElements){
	departmentData = {};
	
	if (addDepartmentElements){
		main.municipalitySelectorContainer.empty();
	}
	
	for (let i = 0; i < data.length; i++) {
		const municipality 				= data[i];
		const municipalityAbbrevName 	= municipality.abbrevName;
		const municipalityFullName 		= municipality.fullName;
		const municipalityImage			= municipality.image
		const municipalityCount 		= municipality.count;
		const markedVehicles 			= municipality.markedVehicles;
		const unmarkedVehicles 			= municipality.unmarkedVehicles;
		
		if (addDepartmentElements){
			addMunicipalityElement(municipalityAbbrevName, municipalityFullName, municipalityImage, municipalityCount);
		} else {
			updateMunicipalityCountElement(municipalityAbbrevName, municipalityCount)
		}
		
		markedVehicles.forEach(vehicle => {
			if (!departmentData[municipalityAbbrevName]) {
				departmentData[municipalityAbbrevName] = [];
			}
			departmentData[municipalityAbbrevName].push({
				fleetId: vehicle.fleetId,
				model: vehicle.model,
				abbrevName: vehicle.abbrevName,
				fullName: vehicle.fullName,
				image: vehicle.image,
				currentCount: vehicle.current,
				maxCount: vehicle.max,
				oosCount: vehicle.oos,
				unmarked: false,
				restricted: vehicle.restricted,
			});
			if (currentVehicle.municipality === municipalityAbbrevName) {
				updateVehicleCountElement(vehicle);
			}
		});	
		
		unmarkedVehicles.forEach(vehicle => {
			if (!departmentData[municipalityAbbrevName]) {
				departmentData[municipalityAbbrevName] = [];
			}
			departmentData[municipalityAbbrevName].push({
				fleetId: vehicle.fleetId,
				model: vehicle.model,
				abbrevName: vehicle.abbrevName,
				fullName: vehicle.fullName,
				image: vehicle.image,
				currentCount: vehicle.current,
				maxCount: vehicle.max,
				oosCount: vehicle.oos,
				unmarked: true,
				restricted: vehicle.restricted,
			});
			if (currentVehicle.municipality === municipalityAbbrevName) {
				updateVehicleCountElement(vehicle);
			}
		});
	};
	
	if(addDepartmentElements){
		addDynamicButtonHandlers();
	}
}

function addDynamicButtonHandlers(){
	// DYNAMIC BUTTON HANDLERS
	//	Municipality Selector Tiles; 
		// Locates and adds municipality vehicles, sets department header text, 
		// renames municipality sections for SASP, handles restriction overlay hovering.
		// hides empty vehicle selectors, reveals selector when ready.
	$(document).on('click', '.municipality-grid-item', function() {
		$('#vehicle-selector-marked').empty();
		$('#vehicle-selector-unmarked').empty();
		const departmentKey = $(this).data('key');
		const departmentFullName = $(this).data('full-name');
		currentVehicle.municipality = departmentKey;

		if (departmentData[departmentKey]) {
			sendDataToLua('SetUpdateRequests', true);

			departmentData[departmentKey].forEach(vehicle => {
				addVehicleElement(vehicle);
			});
			
			$('#vehicle-selector-header').text(departmentFullName);
			
			if (departmentKey === "SP_lp"){
				main.vehicleTypeMarked.text("Low Profile");
			} else if (departmentKey === "SP") {
				main.vehicleTypeMarked.text("");
			} else {
				main.vehicleTypeMarked.text("Marked");
			}	

			$('.image-restrictions').hover(
				function () {
					$(this).siblings('.restriction-overlay').css('opacity', 1);
				},
				function () {
					$(this).siblings('.restriction-overlay').css('opacity', 0);
				}
			);
			
			const hasUnmarkedVehicles = departmentData[departmentKey].some(vehicle => vehicle.unmarked);

			if (hasUnmarkedVehicles) {
				$('#vehicle-type-unmarked').text("Unmarked");
			} else {
				$('#vehicle-type-unmarked').text("");
			}
		}

		main.municipalitySelectorMain.hide();
		main.vehicleSelectorMain.show();
	});

	//	Vehicle Selector Tiles;
		// parses element key to store model and unmarked bool, updates and opens vehicle 
		// customization window. 
		// Must be event delegation, added dynamically.
	$(document).on('click', '.vehicle-grid-item', function() {
		currentVehicle.fleetId = $(this).data('key');
		const modelFullName = $(this).data('full-name');

		const imgElement = $(this).find("img");
		const imageSrc = imgElement.attr("src");

		$('#vehicle-preview-model').html(modelFullName);
		$('#vehicle-preview-image').attr('src', imageSrc);
		main.vehicleCustomizeMain.show();
	});
}

// MP municipality selector table view
function generateMpAssignmentsTable(districtCoverageData){
	var municipalityData = {};
	var tBodyRows = [];

	// Process the data and aggregate by municipality
	const municipalities = ['Davis PD', 'Del Perro PD', 'Vinewood PD', 'Sandy Shores PD', 'Grapeseed PD', 'Paleto Bay PD', 'Transit Police'];

	districtCoverageData.forEach(function (record) {
		var municipality = record.municipalityFullName;

		if (municipalities.includes(municipality)) {
			// Skip stolen vehicles.
			if (record.playerName.startsWith('STOLEN')) {
				return; 
			}

			if (!municipalityData[municipality]) {
				municipalityData[municipality] = { officers: [] };
			}

			municipalityData[municipality].officers.push(record.playerName);
		}
	});

	// Add header cells for each municipality
	municipalities.forEach(function (municipality) {
		var data = municipalityData[municipality];
		var officerCount = data ? data.officers.length : 0;
		const displayName = municipality.toUpperCase()
									 .replace(/\bPD\b/, '')
									 .replace(/\bPOLICE\b/, '')
									 
		const className =  displayName.toLowerCase()
									   .replace(/ /g, '')
		$('.mp-assignments-' + className).text(displayName + ' (' + officerCount + ')');
	});

	// Find the maximum number of officers for any municipality
	var maxOfficers = Math.max(...municipalities.map(function (municipality) {
		var data = municipalityData[municipality];
		return data ? data.officers.length : 0;
	}));

	// Add officer rows
	for (var i = 0; i < maxOfficers; i++) {
		var officerRow = '<tr>';

		// Iterate through the list of municipalities to insert officers in the correct columns
		municipalities.forEach(function (municipality) {
			var data = municipalityData[municipality];
			if (data && data.officers && i < data.officers.length) {
				officerRow += '<td>' + data.officers[i] + '</td>';
			} else {
				officerRow += '<td></td>';
			}
		});

		officerRow += '</tr>';
		tBodyRows.push(officerRow);
	}
	
	if ($.fn.DataTable.isDataTable('#mp-assignments-table')) {
		mpAssignmentsDataTable.clear().rows.add($(tBodyRows.join(''))).draw();
	} else {
		$('#mp-assignments-tBody').append(tBodyRows.join(''));
		mpAssignmentsDataTable = tablet.mpAssignmentTable.DataTable({
			destroy: false,
			bPaginate: false,
			bLengthChange: false,
			bFilter: false,
			bInfo: false,
			bAutoWidth: false,
			"ordering": false,
		});
	}
}



// ========= TABLET =========
function processCheckedOut(checkedOutRecords){
	// Iterate through all records dynamically creating table, markers
	var tBodyRows = []

	for (var i = 0; i < checkedOutRecords.length; i++) {
		var record = checkedOutRecords[i];	
		
		var municipality = record.municipalityFullName;
		if (municipality === "Marked" || municipality === "Low Profile & Unmarked"){
			municipality = "State Police";
		}
		
		var statusString = '';
		if (record.timer === false) {
			statusString = 'Reserved';
		} else if (record.timer > 0) {
			statusString = 'Expiring (' + record.timer + ' mins)';
		} else {
			statusString = 'Expired (occupied)';
		}
		
		// Location age timestamp -> seconds or minutes
		const locationAgeFormatted = ' (' + formattedTimeElapse(record.locationAge, undefined) + ')'
		checkedOutRecords[i].locationAge = locationAgeFormatted
		// Add records to table
		tBodyRows.push(
			'<tr><td class="player">' +
				record.playerName +
			'</td>' +
			'<td class="municipality">' + municipality + '</td>' +
			'<td class="model">' + record.model + '</td>' +
			'<td class="unmarked">' + (record.unmarked ? "✔" : "✘") + '</td>' +
			'<td class="direction-speed">' + record.direction + ' @ ' + record.speed + ' mph</td>' +
			'<td class="location">' + record.location + record.locationAge + '</td>' +
			'<td class="status">' + statusString + '</td>' +
			'<td class="tracking"><button class="table-btn' + (record.tracking ? ' active' : '') + '" id=' + i +' onClick="toggleTracking(this)"' + (tabletSupervisor ? '' : 'disabled') + '><i class="fa-sharp fa-solid fa-map-location-dot"></i></button></td>' +
			'<td class="manage"><button class="table-btn" id=' + i +' onClick="openManageView(this)"' + (tabletSupervisor ? '' : 'disabled') + '><i class="fa-sharp fa-solid fa-gear"></i></button></td></tr>'
		);
	}
		
	if ($.fn.DataTable.isDataTable('#checkedout-table')) {
		checkedOutDataTable.clear().rows.add($(tBodyRows.join(''))).draw();
	} else {
		$('#checkedout-tBody').append(tBodyRows.join(''));
		checkedOutDataTable = tablet.checkedOutTable.DataTable({
			destroy: false,
			bPaginate: true,
			bLengthChange: false,
			bFilter: true,
			bInfo: true,
			bAutoWidth: false,
			order: [[ 1, 'desc' ]],
			aoColumnDefs: [ 
				{ "bSortable": false, "aTargets": [ 7, 8 ] },
				{ type: 'direction-speed', targets: 4 }
			],
			initComplete: function(settings, json) {
				// dynamic row calculation
				var containerHeight = tablet.checkedOutContainer.height();
				var rowHeight = $('#checkedout-table tbody tr:first-child').height();
				var numRows = Math.floor(containerHeight / rowHeight) - 3;
				tablet.checkedOutTable.DataTable().page.len(numRows).draw(); 
				
				const tableViewToggles = 
				`
				<div id="table-toggle" style="float: left">
					<button id="view-oos" class="btn btn-primary btn-med">Out of Service</button>
					<button id="view-checkedout" class="btn btn-primary btn-med active">Checked Out</button>
					<button class="btn btn-primary btn-med view-mp-assignments">MP Assignments</button>
				</div>
				`
				
				$('#checkedout-table_filter').append($(tableViewToggles));

				// Create the nested checkbox dropdown filter
				var checkedoutFilterDropdown = $('<select multiple></select>')
				  .addClass('custom-filter')
				  .attr('id', 'checkedoutFilterDropdown');

				var groups = [
				  { label: 'MP', options: ['Del Perro PD', 'Vinewood PD', 'Davis PD', 'Paleto Bay PD', 'Sandy Shores PD', 'Grapeseed PD', 'Transit Police', 'San Andreas Environmental Police'] },
				  { label: 'SASP', options: ['State Police'] },
				  { label: 'SO', options: ['Los Santos Sheriffs Office'] } 
				];

				groups.forEach(function(group) {
				  var optgroup = $('<optgroup label="' + group.label + '"></optgroup>').appendTo(checkedoutFilterDropdown);
				  group.options.forEach(function(option) {
					$('<option value="' + option + '">' + option + '</option>').appendTo(optgroup);
				  });
				});

				// Append the filter dropdown to the DataTables filter area
				$('#checkedout-table_filter').append('<div class="multiselect-label">Department Filter: </div>', checkedoutFilterDropdown);

				// Initialize Bootstrap Multiselect after the element is defined
				$('#checkedoutFilterDropdown').multiselect({
				  includeSelectAllOption: true,
				  enableFiltering: false,
				  buttonClass: 'btn btn-default btn-fix',
				});

				// Apply filtering when dropdown selection changes
				$('#checkedoutFilterDropdown').on('change', function() {
				  var selectedValues = $(this).val();
				  tablet.checkedOutTable.DataTable().column(1).search(selectedValues.join('|'), true, false).draw();
				});
			}
		});
	}
	
	// Hide MP assignments sheet unless MP department
	if (tabletDepartment === 'MP'){
		$('.view-mp-assignments').show();
	} else {
		$('.view-mp-assignments').hide();
	}
	
	tablet.tabletLoadingContainer.fadeOut();
}

function processOosRecords(oosRecords){
	// Iterate through all records dynamically creating table, markers
	var tBodyRows = []
	
	for (var i = 0; i < oosRecords.length; i++) {
		var record = oosRecords[i];	
		
		var municipality = record.municipalityFullName;
		if (municipality === "Marked" || municipality === "Low Profile & Unmarked"){
			municipality = "State Police";
		}
		
		// Add records to table
		tBodyRows.push(
			'<tr>' +
			'<td>' + record.oosId + '</td>' +
			'<td>' + municipality + '</td>' +
			'<td>' + record.modelFullName + (record.unmarked ? " - UM" : "") +'</td>' +
			'<td>' + record.category + '</td>' +
			'<td>' + record.reporter + '</td>' +
			'<td>' + record.recordDateTime + '</td>' +
			'<td>' + record.returnDateTime + '</td>' +
			'<td>' + (record.status ? 'Active' : 'Complete') + '</td>' +
			'<td class="details"><button class="table-btn" id=' + i + ' onClick="openViewOosDialog(this)"><i class="fa-sharp fa-solid fa-gear"></i></button></td></tr>'
		);
	}
		
	if ($.fn.DataTable.isDataTable('#oos-table')) {
		oosDataTable.clear().rows.add($(tBodyRows.join(''))).draw();
	} else {
		$('#oos-tBody').append(tBodyRows.join(''));
		oosDataTable = tablet.oosTable.DataTable({
			destroy: false,
			bPaginate: true,
			bLengthChange: false,
			bFilter: true,
			bInfo: true,
			bAutoWidth: false,
			order: [[ 1, 'desc' ]],
			aoColumnDefs: [ 
				{ "bSortable": false, "aTargets": [ 8 ] },
			],
			initComplete: function(settings, json) {
				// dynamic row calculation
				var containerHeight = tablet.oosContainer.height();
				var rowHeight = $('#oos-table tbody tr:first-child').height();
				var numRows = Math.floor(containerHeight / rowHeight) - 3;
				tablet.oosTable.DataTable().page.len(numRows).draw(); 
				
				const tableViewToggles = 
				`
				<div id="table-toggle" style="float: left">
					<button id="view-oos" class="btn btn-primary btn-med active">Out of Service</button>
					<button id="view-checkedout" class="btn btn-primary btn-med">Checked Out</button>
					<button class="btn btn-primary btn-med view-mp-assignments">MP Assignments</button>
				</div>
				`
				
				$('#oos-table_filter').append($(tableViewToggles));
				
				// Create the nested checkbox dropdown filter
				var oosFilterDropdown = $('<select multiple></select>')
				  .addClass('custom-filter')
				  .attr('id', 'oosFilterDropdown');

				var groups = [
				  { label: 'MP', options: ['Del Perro PD', 'Vinewood PD', 'Davis PD', 'Paleto Bay PD', 'Sandy Shores PD', 'Grapeseed PD', 'Transit Police', 'San Andreas Environmental Police'] },
				  { label: 'SASP', options: ['State Police'] },
				  { label: 'SO', options: ['Los Santos Sheriffs Office'] } 
				];

				groups.forEach(function(group) {
				  var optgroup = $('<optgroup label="' + group.label + '"></optgroup>').appendTo(oosFilterDropdown);
				  group.options.forEach(function(option) {
					$('<option value="' + option + '">' + option + '</option>').appendTo(optgroup);
				  });
				});

				// Append the filter dropdown to the DataTables filter area
				$('#oos-table_filter').append('<div class="multiselect-label">Department Filter: </div>', oosFilterDropdown);

				// Initialize Bootstrap Multiselect after the element is defined
				$('#oosFilterDropdown').multiselect({
				  includeSelectAllOption: true,
				  enableFiltering: false,
				  buttonClass: 'btn btn-default btn-fix',
				});

				// Apply filtering when dropdown selection changes
				$('#oosFilterDropdown').on('change', function() {
				  var selectedValues = $(this).val();
				  tablet.oosTable.DataTable().column(1).search(selectedValues.join('|'), true, false).draw();
				});
			}
		});
	}
	
	// Hide MP assignment sheets for non-MP.
	if (tabletDepartment === 'MP'){
		$('.view-mp-assignments').show();
	} else {
		$('.view-mp-assignments').hide();
	}

	tablet.tabletLoadingContainer.fadeOut();
}

function generateMpAssignmentsTabletTable(checkedOutData){
	var municipalityData = {};
	var tBodyRows = [];

	// Process the data and aggregate by municipality
	const municipalities = ['Davis PD', 'Del Perro PD', 'Vinewood PD', 'Sandy Shores PD', 'Grapeseed PD', 'Paleto Bay PD', 'Transit Police'];
	const currentTime = Math.floor(Date.now() / 1000);

	checkedOutData.forEach(function (record) {
		var municipality = record.municipalityFullName;

		if (municipalities.includes(municipality)) {
			// Skip stolen vehicles.
			if (record.playerName.startsWith('STOLEN')) {
				return; 
			}
		
			var clockedInTime = record.clockedInTime;
			const formattedTime = getFormattedDuration(currentTime, clockedInTime)
			const rawDuration = getRawDuration(currentTime, clockedInTime);

			if (!municipalityData[municipality]) {
				municipalityData[municipality] = { officers: [] };
			}

			municipalityData[municipality].officers.push({
				name: record.playerName,
				rawDuration: rawDuration, 
				formattedTime: formattedTime
			});
			
		}
	});

	// Add header cells for each municipality
	municipalities.forEach(function (municipality) {
		var data = municipalityData[municipality];
		var officerCount = data ? data.officers.length : 0;
		const displayName = municipality.toUpperCase()
									 .replace(/\bPD\b/, '')
									 .replace(/\bPOLICE\b/, '')

		const className =  displayName.toLowerCase()
									   .replace(/ /g, '')

		$('.mp-assignments-' + className).text(displayName + ' (' + officerCount + ')');
	});

	// Find the maximum number of officers for any municipality
	var maxOfficers = Math.max(...municipalities.map(function (municipality) {
		var data = municipalityData[municipality];
		return data ? data.officers.length : 0;
	}));

	// Add officer rows
	for (var i = 0; i < maxOfficers; i++) {
		var officerRow = '<tr>';

		// Iterate through the list of municipalities to insert officers in the correct columns
		municipalities.forEach(function (municipality) {
			var data = municipalityData[municipality];
			if (data && data.officers && i < data.officers.length) {
				officerRow += '<td data-duration="' + data.officers[i].rawDuration + '">' + data.officers[i].name + ' (' + data.officers[i].formattedTime + ')' + '</td>';
			} else {
				officerRow += '<td></td>';
			}
		});

		officerRow += '</tr>';
		tBodyRows.push(officerRow);
	}
	
	if ($.fn.DataTable.isDataTable('#mp-assignments-tablet-table')) {
		mpAssignmentsDataTabletTable.clear().rows.add($(tBodyRows.join(''))).draw();
	} else {
		$('#mp-assignments-tablet-tBody').append(tBodyRows.join(''));
		mpAssignmentsDataTabletTable = $('#mp-assignments-tablet-table').DataTable({
			destroy: false,
			bPaginate: true,
			bLengthChange: false,
			bFilter: true,
			bInfo: true,
			bAutoWidth: false,
			ordering: false,
			initComplete: function(settings, json) {
				// dynamic row calculation
				var containerHeight = tablet.mpAssignmentsContainer.height();
				var rowHeight = $('#mp-assignments-tablet-table tbody tr:first-child').height();
				var numRows = Math.floor(containerHeight / rowHeight) - 3;
				$('#mp-assignments-tablet-table').DataTable().page.len(numRows).draw(); 
				
				const tableViewToggles = 
				`
				<div id="table-toggle" style="float: left">
					<button id="view-oos" class="btn btn-primary btn-med">Out of Service</button>
					<button id="view-checkedout" class="btn btn-primary btn-med">Checked Out</button>
					<button class="btn btn-primary btn-med view-mp-assignments">MP Assignments</button>
				</div>
				`
				$('#mp-assignments-tablet-table_filter').append($(tableViewToggles));
			},
			columnDefs: [
				{
					targets: '_all',
					defaultContent: "", // This sets a default empty string for all undefined or null data
					render: function (data, type, row, meta) {
						if (type === 'sort') {
							// Check if the data-duration attribute exists before using it
							var durationData = $(meta.row).find('td').eq(meta.col).data('duration');
							return durationData !== undefined ? durationData : 0;
						}
						return data;
					}
				}
			]
		});
	}
}

// ==== MANAGE VIEW ====
function openManageView(element) {
    const record = checkedOutRecords[element.id];	
	
	var municipality = record.municipalityFullName
	if (municipality === "Marked" || municipality === "Low Profile & Unmarked"){
		municipality = "State Police";
	}
	
	$('#manage-municipality').text(municipality);
	$('#manage-model').text(record.modelFullName + (record.unmarked ? ' - UNMARKED ' : ''));
	$('#manage-player').text(record.playerName);
	$('#manage-location').text(record.location + record.locationAge);
	$('#manage-direction-speed').text(record.direction + ' @ ' + record.speed + ' mph');
	const currentTime = Math.floor(Date.now() / 1000);
	const formattedTime = getFormattedDuration(currentTime, record.clockedInTime)
	$('#manage-duration').text(formattedTime);
	
	// buttons
	$('#manage-vehicle-oos').data('record-id', element.id);
	$('#manage-vehicle-stolen').data('record-id', element.id);
	
	if (record.hasOwnProperty('stolen') && record.stolen) {
		$('#manage-vehicle-stolen').data('state', 'recovered');
		$('#manage-vehicle-stolen').html('<i class="fa-solid fa-truck-ramp-box"></i> Report Recovered');
	} else {
		$('#manage-vehicle-stolen').data('state', 'stolen');
		$('#manage-vehicle-stolen').html('<i class="fa-solid fa-person-circle-exclamation"></i> Report Stolen');
	}
	
	tablet.manageVehicleContainer.fadeIn();
}

// ==== OOS ====
function openNewOOS(record) {
	tablet.manageVehicleContainer.fadeOut();
	$("#category")[0].selectedIndex = 0;
	$("#duration")[0].selectedIndex = 0;
	$("#return").val("");
	$("#notes").val("");
	tablet.oosForm.data('fleet-id', record.fleetId);
	tablet.oosForm.data('vehicle-net-id', record.vehicleNetId);

	var municipality = record.municipalityFullName
	if (municipality === "Marked" || municipality === "Low Profile & Unmarked"){
		municipality = "State Police";
	}

	$('#municipality').val(municipality);
	$('#model').val(record.modelFullName);
	$('#operator').val(record.playerName);
	$('#reporter').val(usersName);
	
	tablet.oosFormContainer.fadeIn();
}

// Open the dialog for review with existing record data
function openViewOosDialog(element) {
    const record = oosRecords[element.id];
	// Modify the form fields with existing data
	$('#oos-header').text('OOS ID: ' + record.oosId);
	
	var municipality = record.municipalityFullName;
	if (municipality === "Marked" || municipality === "Low Profile & Unmarked"){
		municipality = "State Police";
	}

	$('#municipality').val(municipality);
	$('#model').val(record.modelFullName + (record.unmarked ? " - UM" : ""));
	$('#category').val(record.category);
	$('#operator').val(record.operator);
	$('#reporter').val(record.reporter);
	$('#return').val(record.returnDateTime);
	$('#notes').val(record.notes);
	
	// Manage duration change, append new option
	$('#duration-label').text("OOS Timestamp:");
	$('#duration').append($('<option>', {
		value: 99,
		text: record.recordDateTime,
		disabled: true,
		selected: true 
	  }));
	
	$('#oos-action-button').val('Close');
	$('#category, #duration, #notes').prop('disabled', true);
	$('#category, #duration').addClass('select-disable-override');
	$('#oos-form-footer').hide();

	function revertViewMods(){
		setTimeout(function(){
			$('#oos-action-button').val('Submit');
			$('#category, #duration').removeClass('select-disable-override');
			$('#category, #duration, #notes').prop('disabled', false);
			$('#duration').find('option[value="99"]').remove();
			$('#duration-label').text("OOS Duration:");
			$('#oos-header').text('New OOS Record');
			$('#oos-form-footer').show();
		}, 500);
	}

	// Update the form submission behavior for review
	tablet.oosForm.off('submit').on('submit', function(event) {
		event.preventDefault();
		tablet.oosFormContainer.fadeOut();
		revertViewMods();
	});
  
	// Custom event handler temporarily to revert on exit.
	$('#oos-close-btn').click( function() { 
		revertViewMods();
	});

  // Show the dialog
  tablet.oosFormContainer.fadeIn();
}

// Toggle tracking overlay
function toggleTracking(element) {
    const record = checkedOutRecords[element.id];	
	
	// Ensure previous button is unselected
	$('.table-btn.tracking').removeClass('active');
	
	if (!record.hasOwnProperty('tracking')){
		record.tracking = false
	}
	
	record.tracking = !record.tracking
	
	if (record.tracking){
		$(element).addClass('active');
	} else {
		$(element).removeClass('active');
	}
	sendDataToLua('ToggleTracking', { vehicleNetId: record.vehicleNetId, state: record.tracking })
}

// Location age timestamp -> seconds or minutes
function formattedTimeElapse(timestamp, element){
	if (timestamp != 0){
		const currentZuluTime = new Date();
		const locationAgeDate = new Date(timestamp);
		const deltaMs = locationAgeDate - currentZuluTime;
		const deltaSeconds = Math.abs(Math.floor(deltaMs / 1000));

		if (element !== undefined) {
			if (deltaSeconds > 10){
				element.css({'color': 'red', 'font-weight': 'bold'});
			} else if (deltaSeconds > 5){
				element.css({'color': 'orange', 'font-weight': 'bold'});
			} else {
				element.css({'color': 'unset', 'font-weight': 'unset'});
			}
		}

		var locationAgeFormatted = deltaSeconds === 1 ? deltaSeconds + ' sec' : deltaSeconds + ' secs';
		if (deltaSeconds > 60){
			const ageInMinutes = Math.floor(deltaSeconds / 60);
			locationAgeFormatted = ageInMinutes === 1 ? ageInMinutes + ' min' : ageInMinutes + ' mins';
		}
		return locationAgeFormatted
	} 
	return '---'
}

function updateClock() {
	var dateTimeElement = document.getElementById('date-time-value');
	var currentTime = new Date();
	// Extract the individual components
	var month = currentTime.getUTCMonth() + 1; // Months are zero-based
	var day = currentTime.getUTCDate();
	var year = currentTime.getUTCFullYear();
	var hours = currentTime.getUTCHours();
	var minutes = currentTime.getUTCMinutes();

	// Add leading zeros if necessary
	day = day < 10 ? '0' + day : day;
	hours = hours < 10 ? '0' + hours : hours;
	minutes = minutes < 10 ? '0' + minutes : minutes;

	// Create the formatted date-time string
	var dateTimeString = month + '/' + day + '/' + year + ' ' + hours + ':' + minutes;
	dateTimeElement.textContent = dateTimeString;
	
	tablet.dateTimeLoading.fadeIn();
	setTimeout(function () {
		tablet.dateTimeLoading.fadeOut();
	}, 850);
}

function getFormattedDuration(currentTimeInSecs, timeStampInSecs) {
	try {
        if (typeof currentTimeInSecs !== 'number' || typeof timeStampInSecs !== 'number' || currentTimeInSecs < timeStampInSecs) {
            throw new Error('Invalid input values');
        }

		// delta time in minutes
		var timeSpent = Math.floor((currentTimeInSecs - timeStampInSecs) / 60);

		// Format the time spent
		if (timeSpent < 60) {
			return timeSpent + "m";
		} else if (timeSpent % 60 === 0) {
            return (timeSpent / 60) + "h";
		} else {
			var hours = Math.floor(timeSpent / 60);
			var minutes = timeSpent % 60;
            return hours + "h" + minutes + "m";
		}
	} catch (e) {
		console.log('getFormattedDuration(' + currentTimeInSecs + ', ' + timeStampInSecs + ') failed... ' + e.message, currentTimeInSecs, timeStampInSecs);
		return "ERROR";
	}
}

function getRawDuration(currentTimeInSecs, timeStampInSecs) {
	try {
        if (typeof currentTimeInSecs !== 'number' || typeof timeStampInSecs !== 'number' || currentTimeInSecs < timeStampInSecs) {
            throw new Error('Invalid input values');
        }

		// Logic to calculate raw duration in minutes or seconds
		return Math.floor((currentTimeInSecs - timeStampInSecs) / 60);
	} catch (e) {
		console.log('getRawDuration(' + currentTimeInSecs + ', ' + timeStampInSecs + ') failed... ' + e.message, currentTimeInSecs, timeStampInSecs);
		return 0;
	}
}
