import type { CountPayload, Loc } from "./typing";
import { parsed } from "./utils";

interface LocCounts {
	locations: CountPayload[],
	ws: WebSocket | null,
	update: (locations: CountPayload[]) => void,
	getCount: (locationName: string) => void,
	connect: () => void,
	init: () => void,
	poll: () => void,
	pretendNew: () => void,
}

document.body.addEventListener("htmx:afterSwap", (e) => {
	if (window.Alpine) {
		if (e.target instanceof HTMLElement) {
			window.Alpine.initTree(e.target);
		}
	}
});

function registerLiveData() {
	if (!window.Alpine) return;

	Alpine.data(
		"liveData",
		(): LocCounts => ({
			locations: [],
			ws: null,

			update(locations) {
				const self = this as any;
				self.locations = locations;
			},

			getCount(locationName) {
				const match = this.locations.find(loc => loc.location_name === locationName)
				if (match) {
					console.log(match)
					return match.value
				}
			},

			connect() {
				const self = this as any
				self.ws = new WebSocket("/map/counts");

				self.ws.addEventListener("open", () => {
					self.ws.send("Hello Server!");
				});

				self.ws.addEventListener("message", (e: MessageEvent) => {
					const payload = parsed(e.data)
					switch (payload.notification_type) {
						case "card_count":
							console.info("Card count updated")
							self.update(payload.locations)
							break;
					}
				});

			},
			init() {
				const self = this as any
				self.ws = new WebSocket("/map/counts");

				self.ws.addEventListener("open", () => {
					if (self.ws.readyState === WebSocket.OPEN) {
						self.ws.send("p");
					}
				});

				self.ws.addEventListener("message", (e: MessageEvent) => {
					const payload = parsed(e.data)
					switch (payload.notification_type) {
						case "card_count":
							console.info("Card count updated")
							self.update(payload.locations)
							break;
					}
				});
			},
			async poll() {
				await fetch("/map/poll")
			},
			async pretendNew() {
				await fetch("/cards/test_new")
			}
		}),
	);

}

if (window.Alpine) {
	registerLiveData();
} else {
	document.addEventListener("alpine:init", registerLiveData);
}
