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, 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 [createNewOpen, setCreateNewOpen] = useState(false);
	const onSelect = useCallback(
		(projectId: string) => {
			if (projectId === "create-new") {
				setCreateNewOpen(true);
			} else {
				store.setProject(projectId);
			}
		},
		[store],
	);
	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={projectId}>
			<SelectTrigger className="w-[200px] !border-none !shadow-none !focus:ring-0 !focus:ring-offset-0">
				<SelectValue placeholder="Choose Project" defaultValue={projectId} />
			</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>
	);
}
