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);
	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(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 [props, setProps] = useState({});
	useEffect(() => {
		if (loading) {
			setProps({ loading: true });
		} else if (ok) {
			setProps({ disabled: false });
		} else {
			setProps({ disabled: true });
		}
	}, [ok, loading, setProps]);
	return (
		<>
			<Button onClick={deploy} {...props}>
				Deploy
			</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>
		</>
	);
}
