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

class SessionHistoryViewModel {
	sessions = $state([] as FlowInfo[]);
	chosenSession = $state(undefined as FlowInfo | undefined);
	isLoading = $state(true);
	includeDeleted = $state(false);

	// For pagination
	currentPage = $state(1);
	totalPages = $state(1);
	pageSize = $state(20);

	async loadSessions() {
		this.isLoading = true;
		const api = get(trpcApiStore);

		if (!api) {
			this.isLoading = false;
			return;
		}

		try {
			const result = await api.ckflow.getAllSessionsList.query({
				includeDeleted: this.includeDeleted,
			});

			console.log(result);

			if (result.error) {
				toast.error(result.error.message, {
					description: result.error.detail,
				});
				return;
			}

			this.sessions = result.data || [];

			// Calculate total pages
			this.totalPages = Math.max(
				1,
				Math.ceil(this.sessions.length / this.pageSize),
			);

			// Ensure current page is valid
			if (this.currentPage > this.totalPages) {
				this.currentPage = this.totalPages;
			}
		} catch (error) {
			toast.error("Failed to load sessions", {
				description: "An error occurred when trying to get sessions",
			});
		} finally {
			this.isLoading = false;
		}
	}

	get currentPageSessions(): FlowInfo[] {
		const startIdx = (this.currentPage - 1) * this.pageSize;
		const endIdx = startIdx + this.pageSize;
		return this.sessions.slice(startIdx, endIdx);
	}

	async viewSessionDetails(session: FlowInfo) {
		this.chosenSession = session;
	}

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

		try {
			const result = await api.ckflow.softDeleteSession.mutate({ flowId });

			if (result.error) {
				return result;
			}

			// Update local data
			this.sessions = this.sessions.map((session) =>
				session.flowId === flowId
					? { ...session, isDeleted: true }
					: session,
			);

			// If the deleted session is currently selected, update it
			if (this.chosenSession?.flowId === flowId) {
				this.chosenSession = { ...this.chosenSession, isDeleted: true };
			}

			return result;
		} catch (error) {
			return {
				error: {
					message: "Failed to delete session",
					detail:
						error instanceof Error ? error.message : "Unknown error",
				},
			};
		}
	}

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

		try {
			const result = await api.ckflow.restoreSession.mutate({ flowId });

			if (result.error) {
				return result;
			}

			// Update local data
			this.sessions = this.sessions.map((session) =>
				session.flowId === flowId
					? { ...session, isDeleted: false }
					: session,
			);

			// If the restored session is currently selected, update it
			if (this.chosenSession?.flowId === flowId) {
				this.chosenSession = { ...this.chosenSession, isDeleted: false };
			}

			return result;
		} catch (error) {
			return {
				error: {
					message: "Failed to restore session",
					detail:
						error instanceof Error ? error.message : "Unknown error",
				},
			};
		}
	}

	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);
		}
	}

	setPage(page: number) {
		if (page < 1) page = 1;
		if (page > this.totalPages) page = this.totalPages;
		this.currentPage = page;
	}

	nextPage() {
		this.setPage(this.currentPage + 1);
	}

	prevPage() {
		this.setPage(this.currentPage - 1);
	}

	toggleIncludeDeleted() {
		this.includeDeleted = !this.includeDeleted;
		this.loadSessions();
	}

	resetSelection() {
		this.chosenSession = undefined;
	}
}

export const sessionHistoryVM = new SessionHistoryViewModel();
