import { AppNode, nodeLabel, useEnv, useMessages, useProjectId, useStateStore } from "@/lib/state";
import { Button } from "./ui/button";
import { useCallback, useEffect, useState } from "react";
import { generateDodoConfig } from "@/lib/config";
import { useNodes, useReactFlow } from "@xyflow/react";
import { useToast } from "@/hooks/use-toast";

function toNodeType(t: string): string {
	if (t === "ingress") {
		return "gateway-https";
	} else if (t === "service") {
		return "app";
	} else {
		return t;
	}
}

export function Actions() {
	const { toast } = useToast();
	const store = useStateStore();
	const projectId = useProjectId();
	const nodes = useNodes<AppNode>();
	const env = useEnv();
	const messages = useMessages();
	const instance = useReactFlow();
	const [ok, setOk] = useState(false);
	const [loading, setLoading] = useState(false);
	const [reloading, setReloading] = useState(false);
	useEffect(() => {
		setOk(!messages.some((m) => m.type === "FATAL"));
	}, [messages, setOk]);
	const monitor = useCallback(async () => {
		const m = async function () {
			const resp = await fetch(`/api/project/${projectId}/status`, {
				method: "GET",
				headers: {
					"Content-Type": "application/json",
				},
			});
			if (resp.status !== 200) {
				return;
			}
			const data: { type: string; name: string; status: string }[] = await resp.json();
			console.log(data);
			for (const n of nodes) {
				if (n.type === "network") {
					continue;
				}
				const d = data.find((d) => n.type === toNodeType(d.type) && nodeLabel(n) === d.name);
				if (d !== undefined) {
					store.updateNodeData(n.id, {
						state: d?.status,
					});
				}
			}
			if (data.find((d) => d.status !== "success" && d.status != "failure") !== undefined) {
				setTimeout(m, 1000);
			}
		};
		setTimeout(m, 100);
	}, [projectId, nodes, store]);
	const deploy = useCallback(async () => {
		if (projectId == null) {
			return;
		}
		setLoading(true);
		try {
			const config = generateDodoConfig(projectId, nodes, env);
			if (config == null) {
				throw new Error("MUST NOT REACH!");
			}
			const resp = await fetch(`/api/project/${projectId}/deploy`, {
				method: "POST",
				headers: {
					"Content-Type": "application/json",
				},
				body: JSON.stringify({
					state: JSON.stringify(instance.toObject()),
					config,
				}),
			});
			if (resp.ok) {
				toast({
					title: "Deployment succeeded",
				});
				monitor();
			} else {
				toast({
					variant: "destructive",
					title: "Deployment failed",
					description: await resp.text(),
				});
			}
		} catch (e) {
			console.log(e);
			toast({
				variant: "destructive",
				title: "Deployment failed",
			});
		} finally {
			setLoading(false);
		}
	}, [projectId, instance, nodes, env, setLoading, toast, monitor]);
	const save = useCallback(async () => {
		if (projectId == null) {
			return;
		}
		const resp = await fetch(`/api/project/${projectId}/saved`, {
			method: "POST",
			headers: {
				"Content-Type": "application/json",
			},
			body: JSON.stringify(instance.toObject()),
		});
		if (resp.ok) {
			toast({
				title: "Save succeeded",
			});
		} else {
			toast({
				variant: "destructive",
				title: "Save failed",
				description: await resp.text(),
			});
		}
	}, [projectId, instance, toast]);
	const restoreSaved = useCallback(async () => {
		if (projectId == null) {
			return;
		}
		const resp = await fetch(`/api/project/${projectId}/saved`, {
			method: "GET",
		});
		const inst = await resp.json();
		const { x = 0, y = 0, zoom = 1 } = inst.viewport;
		store.setNodes(inst.nodes || []);
		store.setEdges(inst.edges || []);
		instance.setViewport({ x, y, zoom });
	}, [projectId, instance, store]);
	const clear = useCallback(() => {
		store.setEdges([]);
		store.setNodes([]);
		instance.setViewport({ x: 0, y: 0, zoom: 1 });
	}, [store, instance]);
	// TODO(gio): Update store
	const deleteProject = useCallback(async () => {
		if (projectId == null) {
			return;
		}
		const resp = await fetch(`/api/project/${projectId}`, {
			method: "DELETE",
		});
		if (resp.ok) {
			clear();
			store.setProject(undefined);
			toast({
				title: "Save succeeded",
			});
		} else {
			toast({
				variant: "destructive",
				title: "Save failed",
				description: await resp.text(),
			});
		}
	}, [store, clear, projectId, toast]);
	const reload = useCallback(async () => {
		if (projectId == null) {
			return;
		}
		setReloading(true);
		try {
			const resp = await fetch(`/api/project/${projectId}/reload`, {
				method: "POST",
				headers: {
					"Content-Type": "application/json",
				},
			});
			if (resp.ok) {
				toast({
					title: "Reload triggered successfully",
				});
			} else {
				toast({
					variant: "destructive",
					title: "Reload failed",
					description: await resp.text(),
				});
			}
		} catch (e) {
			console.log(e);
			toast({
				variant: "destructive",
				title: "Reload failed",
			});
		} finally {
			setReloading(false);
		}
	}, [projectId, toast]);
	const [deployProps, setDeployProps] = useState({});
	const [reloadProps, setReloadProps] = useState({});
	useEffect(() => {
		if (loading) {
			setDeployProps({ loading: true });
		} else if (ok) {
			setDeployProps({ disabled: false });
		} else {
			setDeployProps({ disabled: true });
		}

		if (reloading) {
			setReloadProps({ loading: true });
		} else {
			setReloadProps({ disabled: projectId === undefined });
		}
	}, [ok, loading, reloading, projectId]);
	return (
		<>
			<Button onClick={deploy} {...deployProps}>
				Deploy
			</Button>
			<Button onClick={reload} {...reloadProps}>
				Reload
			</Button>
			<Button onClick={save}>Save</Button>
			<Button onClick={restoreSaved}>Restore</Button>
			<Button onClick={clear} variant="destructive">
				Clear
			</Button>
			<Button onClick={deleteProject} variant="destructive" disabled={projectId === undefined}>
				Delete
			</Button>
		</>
	);
}
