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";
import {
	DropdownMenuGroup,
	DropdownMenuItem,
	DropdownMenu,
	DropdownMenuContent,
	DropdownMenuTrigger,
} from "./ui/dropdown-menu";
import { Menu } from "lucide-react";

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);
		store.setMode("deploy");
		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) {
			store.setMode("edit");
			console.log(e);
			toast({
				variant: "destructive",
				title: "Deployment failed",
			});
		} finally {
			setLoading(false);
		}
	}, [projectId, instance, nodes, env, setLoading, toast, monitor, store]);
	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/${store.mode === "deploy" ? "deploy" : "draft"}`, {
			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]);
	const edit = useCallback(async () => {
		store.setMode("edit");
	}, [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: "Project deleted",
			});
		} else {
			toast({
				variant: "destructive",
				title: "Failed to delete project",
				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]);
	if (store.mode === "deploy") {
		return (
			<div className="flex flex-row gap-1 items-center">
				<Button onClick={edit} {...reloadProps}>
					Edit
				</Button>
				<DropdownMenu>
					<DropdownMenuTrigger>
						<Menu className="rounded-md bg-gray-200 opacity-50" />
					</DropdownMenuTrigger>
					<DropdownMenuContent className="w-56">
						<DropdownMenuGroup>
							<DropdownMenuItem
								onClick={reload}
								className="cursor-pointer hover:bg-gray-200"
								{...reloadProps}
							>
								Reload Services
							</DropdownMenuItem>
							<DropdownMenuItem
								onClick={deleteProject}
								disabled={projectId === undefined}
								className="cursor-pointer hover:bg-gray-200"
							>
								Delete Project
							</DropdownMenuItem>
						</DropdownMenuGroup>
					</DropdownMenuContent>
				</DropdownMenu>
			</div>
		);
	} else {
		return (
			<div className="flex flex-row gap-1 items-center">
				<Button onClick={deploy} {...deployProps}>
					Deploy
				</Button>
				<Button onClick={save}>Save</Button>
				<DropdownMenu>
					<DropdownMenuTrigger>
						<Menu />
					</DropdownMenuTrigger>
					<DropdownMenuContent className="w-56">
						<DropdownMenuGroup>
							<DropdownMenuItem
								onClick={restoreSaved}
								disabled={projectId === undefined}
								className="cursor-pointer hover:bg-gray-200"
							>
								Restore
							</DropdownMenuItem>
							<DropdownMenuItem onClick={clear} className="cursor-pointer hover:bg-gray-200">
								Clear
							</DropdownMenuItem>
							<DropdownMenuItem
								onClick={deleteProject}
								disabled={projectId === undefined}
								className="cursor-pointer hover:bg-gray-200"
							>
								Delete Project
							</DropdownMenuItem>
						</DropdownMenuGroup>
					</DropdownMenuContent>
				</DropdownMenu>
			</div>
		);
	}
}
