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";
import { Separator } from "./components/ui/separator";
import { Plus } from "lucide-react";

export function ProjectSelect() {
	const { toast } = useToast();
	const store = useStateStore();
	const [projects, setProjects] = useState<Project[]>([]);
	const projectId = useProjectId();

	const refreshProjects = useCallback(async () => {
		try {
			const resp = await fetch("/api/project");
			const projectList = await resp.json();
			const sortedProjects = [...projectList].sort((a, b) =>
				a.name.localeCompare(b.name, undefined, { sensitivity: "base" }),
			);
			setProjects(sortedProjects);
		} catch (e) {
			console.log(e);
		}
	}, [setProjects]);

	useEffect(() => {
		if (projects.length > 0 && (projectId == null || !projects.some((p) => p.id === projectId))) {
			store.setProject(projects[0].id);
		}
	}, [projectId, projects, store]);
	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] !border-none !shadow-none !focus:ring-0 !focus:ring-offset-0">
				<SelectValue placeholder="Choose Project" defaultValue={project} />
			</SelectTrigger>
			<SelectContent>
				{projects.map((p) => (
					<SelectItem key={p.id} value={p.id}>
						{p.name}
					</SelectItem>
				))}
				<Separator />
				<SelectItem value={"create-new"}>
					<Dialog open={createNewOpen} onOpenChange={setCreateNewOpen}>
						<DialogTrigger className="flex flex-row items-center">
							<Plus />
							Create New
						</DialogTrigger>
						<DialogContent>
							<Input type="text" placeholder="Name" onChange={updateName} />
							<Button onClick={createNew}>Create New</Button>
						</DialogContent>
					</Dialog>
				</SelectItem>
			</SelectContent>
		</Select>
	);
}
