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 { Input } from "./components/ui/input";
import { Button } from "./components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "./components/ui/dialog";
import { useToast } from "@/hooks/use-toast";
import { Separator } from "./components/ui/separator";
import { Plus } from "lucide-react";
import { z } from "zod";

const createNewSchema = z.object({
	id: z.string().min(1),
});

export function ProjectSelect() {
	const { toast } = useToast();
	const store = useStateStore();
	const [projects, setProjects] = useState<Project[]>([]);
	const projectId = useProjectId();
	// Track the selected project ID locally to ensure UI consistency
	const [selectedId, setSelectedId] = useState<string | undefined>(projectId);

	// Keep local state in sync with global state
	useEffect(() => {
		setSelectedId(projectId);
	}, [projectId]);

	const refreshProjects = useCallback(
		async (id?: string) => {
			console.log("refreshProjects", id);
			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);
				if (id && !sortedProjects.some((p) => p.id === id)) {
					throw new Error("MUST NOT REACH!");
				}
				if (id == null) {
					id = sortedProjects[0].id;
				}
				if (id !== selectedId) {
					setSelectedId(id);
					store.setProject(id);
				}
			} catch (e) {
				console.log(e);
			}
		},
		[selectedId, store, setProjects, setSelectedId],
	);

	useEffect(() => {
		refreshProjects();
	});

	const [createNewOpen, setCreateNewOpen] = useState(false);
	const onSelect = useCallback(
		(projectId: string) => {
			if (projectId === "create-new") {
				setCreateNewOpen(true);
			} else {
				setSelectedId(projectId);
				store.setProject(projectId);
			}
		},
		[store, setSelectedId],
	);

	const [name, setName] = useState<string | undefined>(undefined);
	const updateName = useCallback(
		(e: ChangeEvent<HTMLInputElement>) => {
			setName(e.target.value);
		},
		[setName],
	);

	const createNew = useCallback(() => {
		if (!name) {
			toast({
				variant: "destructive",
				title: "Name is required",
			});
			return;
		}
		fetch("/api/project", {
			method: "POST",
			headers: {
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				name: name,
			}),
		})
			.then(async (resp) => {
				if (!resp.ok) {
					return false;
				}
				const result = createNewSchema.safeParse(await resp.json());
				if (!result.success) {
					toast({
						variant: "destructive",
						title: `Failed to create project: ${name}`,
					});
					return;
				}
				const { id } = result.data;
				await refreshProjects(id);
				setCreateNewOpen(false);
				setName(undefined); // Clear the input for next time
				toast({
					title: `Created project: ${name}`,
				});
			})
			.catch((e) => {
				console.log(e);
				toast({
					variant: "destructive",
					title: `Failed to create project: ${name}`,
				});
			});
	}, [name, setCreateNewOpen, toast, refreshProjects]);

	return (
		<>
			<Select onValueChange={onSelect} value={selectedId}>
				<SelectTrigger className="w-[200px] !border-none !shadow-none !focus:ring-0 !focus:ring-offset-0">
					<SelectValue placeholder="Choose Project" />
				</SelectTrigger>
				<SelectContent>
					{projects.map((p) => (
						<SelectItem key={p.id} value={p.id}>
							{p.name}
						</SelectItem>
					))}
					<Separator />
					<SelectItem value={"create-new"}>
						<div className="flex flex-row items-center gap-1">
							<Plus />
							<div>New project</div>
						</div>
					</SelectItem>
				</SelectContent>
			</Select>
			<Dialog open={createNewOpen} onOpenChange={setCreateNewOpen}>
				<DialogContent>
					<DialogHeader>
						<DialogTitle>New project</DialogTitle>
					</DialogHeader>
					<Input
						type="text"
						placeholder="Name"
						onChange={updateName}
						value={name || ""}
						onKeyDown={(e) => {
							if (e.key === "Enter") {
								createNew();
							}
						}}
					/>
					<DialogFooter>
						<Button onClick={createNew}>Create</Button>
					</DialogFooter>
				</DialogContent>
			</Dialog>
		</>
	);
}
