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 {
        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]);
    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]);
    const [st, setSt] = useState<string>();
    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, setSt]);
    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, st]);
    const clear = useCallback(() => {
        store.setEdges([]);
        store.setNodes([]);
        instance.setViewport({ x: 0, y: 0, zoom: 1 });
    }, [store]);
    // 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]);
    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>
        </>
    )
}
