<script lang="ts">
import { defineComponent, onMounted, PropType, Ref, ref, watch } from 'vue';
import "leaflet/dist/leaflet.css";
import L from "leaflet";

type Track = {
	id: number
	name: string
	driver: string
	vehicle: {
		name: string
		licenseplate: string
	}
	distance: number
}

export default defineComponent({
	name: 'Map',
	props: {
		track: {
			type: Number,
			default: 0,
			require: true,
		},
		geoJsonData: {
			type: Object as PropType<any>,
			required: true
		},
		multiple: {
			type: Boolean,
			required: true,
		},

	},
	setup(props) {
		const mapDiv = ref<HTMLElement | null>(null); // ref to map container element
		const mapInstance = ref<any>(null); // reference for the Leaflet map
		const track: Ref<Track> = ref({ id: 0, name: "N/A", driver: "N/A", vehicle: { name: "N/A", licenseplate: "N/A" }, distance: 0.0 })
		const multiple: Ref<boolean> = ref(props.multiple);

		// values for UI Information distribution
		const messageType: Ref<string> = ref("None");
		const message: Ref<string> = ref("");

		const initializeMap = () => {
			if (mapDiv.value) {
				mapInstance.value = L.map(mapDiv.value, {
					center: [51.4819, 7.2162],
					zoom: 13,
				});

				L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {}).addTo(mapInstance.value);
			}
		};

		onMounted(() => {
			console.log(props.geoJsonData)
			initializeMap();
		});

		const clearMap = () => {
			if (mapInstance.value) {
				mapInstance.value.eachLayer((layer: any) => {
					if (!(layer instanceof L.TileLayer)) {
						mapInstance.value.removeLayer(layer);
					}
				});
			}
		};

		const getTrackMeta = async (id: number) => {

			const headers: Headers = new Headers()
			headers.set('Content-Type', 'application/json')
			headers.set('Accept', 'application/json')

			const request: RequestInfo = new Request(`http://localhost:5000/track/meta?id=${id}`, {
				method: "GET",
				headers: headers
			})

			var response = await fetch(request)
			// make sure the request was successfull
			if (response.ok) {
				var jsonBody = await response.json()
				console.log(jsonBody)
				track.value = {
					id: jsonBody["id"],
					name: jsonBody["name"],
					driver: jsonBody["driver"]["name"],
					vehicle: {
						name: jsonBody["vehicle"]["name"],
						licenseplate: jsonBody["vehicle"]["licenseplate"] ?? "N/A"
					},
					distance: jsonBody["distance"]
				}
				console.log(track.value)
			} else {

				alert(`failed to load track meta with error: ${await response.statusText}`)
				messageType.value = "error";
				message.value = `failed to load track meta with error: ${await response.statusText}`;
			}
		}

		watch(() => props.geoJsonData, (newData) => {
			if (newData) {
				console.log("loading GeoJSON:", newData);

				if (mapInstance.value) {
					if (!props.multiple) {
						clearMap();
					}

					var geoJsonLayer = L.geoJSON(newData).addTo(mapInstance.value);

					// pull meta data for for a single track 
					// function wont be called if multiple tracks are loaded
					if (!props.multiple) {
						getTrackMeta(props.track);
					}

					// move camera view according to loaded track
					const bounds = geoJsonLayer.getBounds();
					mapInstance.value.fitBounds(bounds);
				} else {
					
					alert("Map or GeoJSON data not available.")
					console.error("Map or GeoJSON data not available.");
					messageType.value = "error";
					message.value = `"Map or GeoJSON data not available.`;
				}
			}
		});

		return {
			mapDiv,
			multiple,
			track,
			message,
			messageType
		};
	},
});
</script>


<template>
	<Message v-if="type == 'none'" :type="messageType" :message="message" @close="message = ''; messageType = 'None'"></Message>
	<div ref="mapDiv" style="width: 70vw; height: 75vh; overflow: hidden;"></div>
	<br>
	<div class="overflow-x-auto" style="width: 70vw;" v-if="!multiple">
		<table class="table">
			<!-- head -->
			<thead>
				<tr>
					<th>track name</th>
					<th>driver</th>
					<th>vehicle</th>
					<th>License Plate</th>
					<th>distance</th>
				</tr>
			</thead>
			<tbody>
				<!-- row 1 -->
				<tr v-if="track.id == 0" class="bg-base-200">
					<th>
						<div class="skeleton h-4 w-full"></div>
					</th>
					<td>
						<div class="skeleton h-4 w-full"></div>
					</td>
					<td>
						<div class="skeleton h-4 w-full"></div>
					</td>
					<td>
						<div class="skeleton h-4 w-full"></div>
					</td>
					<td>
						<div class="skeleton h-4 w-full"></div>
					</td>
				</tr>

				<tr v-if="track.id != 0" class="bg-base-200">
					<th>{{ track.name }}</th>
					<td>{{ track.driver }}</td>
					<td>{{ track.vehicle.name }}</td>
					<td>{{ track.vehicle.licenseplate }}</td>
					<td>{{ Math.round((track.distance / 1000) * 100) / 100 }}KM</td>
				</tr>
			</tbody>
		</table>
	</div>
</template>

<style scoped>
#mapDiv {
	width: 100vw;
	height: 70vh;
	margin: 0;
	padding: 0;
	overflow: hidden;
}

html,
body {
	margin: 0;
	padding: 0;
	height: 100%;
	width: 100%;
}
</style>
