import { ChangeEvent, useCallback, useEffect, useState } from "react";
import { Project, useProjectId, useStateStore } from "./lib/state";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./components/ui/select";
import { useReactFlow } from "@xyflow/react";
import { Input } from "./components/ui/input";
import { Button } from "./components/ui/button";
import { Dialog, DialogContent, DialogTrigger } from "./components/ui/dialog";
import { useToast } from "@/hooks/use-toast";

export function ProjectSelect() {
	const { toast } = useToast();
	const store = useStateStore();
	const [projects, setProjects] = useState<Project[]>([]);
	const refreshProjects = useCallback(async () => {
		try {
			const resp = await fetch("/api/project");
			setProjects(await resp.json());
		} catch (e) {
			console.log(e);
		}
	}, [setProjects]);
	useEffect(() => {
		refreshProjects();
	}, [refreshProjects]);
	const project = useProjectId();
	const [createNewOpen, setCreateNewOpen] = useState(false);
	const onSelect = useCallback(
		(projectId: string) => {
			if (projectId === "create-new") {
				setCreateNewOpen(true);
			} else {
				store.setProject(projectId);
			}
		},
		[store],
	);
	const instance = useReactFlow();
	const restoreSaved = useCallback(
		async (projectId: string) => {
			const resp = await fetch(`/api/project/${projectId}/saved`, {
				method: "GET",
			});
			const inst = await resp.json();
			const { x = 0, y = 0, zoom = 1 } = inst.viewport;
			instance.setNodes(inst.nodes || []);
			instance.setEdges(inst.edges || []);
			instance.setViewport({ x, y, zoom });
		},
		[instance],
	);
	useEffect(() => {
		if (project == null) {
			return;
		}
		restoreSaved(project);
	}, [project, restoreSaved]);
	const [name, setName] = useState<string | undefined>(undefined);
	const updateName = useCallback(
		(e: ChangeEvent<HTMLInputElement>) => {
			setName(e.target.value);
		},
		[setName],
	);
	const createNew = useCallback(() => {
		console.log(name);
		if (!name) {
			return;
		}
		fetch("/api/project", {
			method: "POST",
			headers: {
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				name: name,
			}),
		})
			.then(async (resp) => {
				if (!resp.ok) {
					return;
				}
				const { id } = await resp.json();
				await refreshProjects();
				store.setProject(id as string);
				setCreateNewOpen(false);
				toast({
					title: `Created project: ${name}`,
				});
			})
			.catch((e) => {
				console.log(e);
				toast({
					variant: "destructive",
					title: `Failed to create project: ${name}`,
				});
			});
	}, [name, setCreateNewOpen, toast, store, refreshProjects]);
	return (
		<Select onValueChange={onSelect} value={project}>
			<SelectTrigger className="w-[200px]">
				<SelectValue placeholder="Choose Project" defaultValue={project} />
			</SelectTrigger>
			<SelectContent>
				<SelectItem value={"create-new"}>
					<Dialog open={createNewOpen} onOpenChange={setCreateNewOpen}>
						<DialogTrigger>Create New</DialogTrigger>
						<DialogContent>
							<Input type="text" placeholder="Name" onChange={updateName} />
							<Button onClick={createNew}>Create New</Button>
						</DialogContent>
					</Dialog>
				</SelectItem>
				{projects.map((p) => (
					<SelectItem key={p.id} value={p.id}>
						{p.name}
					</SelectItem>
				))}
			</SelectContent>
		</Select>
	);
}
