import { trpcApiStore } from "$lib/stores/api";
import { toast } from "svelte-sonner";
import { get } from "svelte/store";
import type { FlowInfo, PendingAction } from "./data";

class CKFlowViewModel {
	activeSessions = $state([] as FlowInfo[]);
	chosenSession = $state(undefined as FlowInfo | undefined);
	isRefreshing = $state(false);

	private sessionPoller: ReturnType<typeof setInterval> | null = null;

	setupPoller() {
		this.refreshSessionsList();
		this.sessionPoller = setInterval(() => {
			this.refreshSessionsList();
			// If we have a chosen session, refresh its data too
			if (this.chosenSession) {
				this.refreshSessionDetail(this.chosenSession.flowId);
			}
		}, 2000);
	}

	clearPoller() {
		if (this.sessionPoller) {
			clearInterval(this.sessionPoller);
			this.sessionPoller = null;
		}
	}

	async refreshSessionsList() {
		if (this.isRefreshing) return;

		this.isRefreshing = true;
		const api = get(trpcApiStore);
		if (!api) {
			this.isRefreshing = false;
			return;
		}

		try {
			const sessions = await api.ckflow.getActiveSessionsList.query();
			if (sessions.error) {
				toast.error(sessions.error.message, {
					description: sessions.error.detail,
				});
				return;
			}

			// Sort sessions by lastPinged (most recent first)
			const sortedSessions = [...(sessions.data || [])].sort(
				(a, b) =>
					new Date(b.lastPinged).getTime() -
					new Date(a.lastPinged).getTime(),
			);

			this.activeSessions = sortedSessions;

			// If currently selected session was updated, update it
			if (this.chosenSession) {
				const updatedSession = sortedSessions.find(
					(s) => s.flowId === this.chosenSession?.flowId,
				);
				if (updatedSession) {
					this.chosenSession = updatedSession;
				}
			}
		} catch (error) {
			toast.error("Failed to refresh sessions", {
				description:
					"An error occurred when trying to get active sessions",
			});
		} finally {
			this.isRefreshing = false;
		}
	}

	async refreshSessionDetail(flowId: string) {
		const api = get(trpcApiStore);
		if (!api) return;

		try {
			const result = await api.ckflow.getFlowInfo.query({ flowId });
			if (result.error) {
				return;
			}

			if (result.data && this.chosenSession?.flowId === flowId) {
				this.chosenSession = result.data;
			}
		} catch (error) {
			console.error("Failed to refresh session detail", error);
		}
	}

	async sendAction(flowId: string, action: PendingAction) {
		const api = get(trpcApiStore);
		if (!api) return { error: { message: "API not available" } };

		try {
			return await api.ckflow.updateSessionAction.mutate({
				flowId,
				action,
			});
		} catch (error) {
			return {
				error: {
					message: "Failed to send action",
					detail:
						error instanceof Error ? error.message : "Unknown error",
				},
			};
		}
	}
}

export const ckflowVM = new CKFlowViewModel();
