import { NodeRect } from "./node-rect";
import { nodeIsConnectable, nodeLabel, useStateStore, VolumeNode } from "@/lib/state";
import { useEffect, useMemo } from "react";
import { z } from "zod";
import { DeepPartial, EventType, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
import { Input } from "./ui/input";
import { Handle, Position } from "@xyflow/react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";

export function NodeVolume(node: VolumeNode) {
	const { id, data, selected } = node;
	const isConnectable = useMemo(() => nodeIsConnectable(node, "volume"), [node]);
	return (
		<NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
			<div style={{ padding: "10px 20px" }}>
				<div>{nodeLabel(node)}</div>
				<div>{data.type && `${data.type}`}</div>
				<div>{data.size && `${data.size}`}</div>
				<Handle
					id="volume"
					type={"source"}
					position={Position.Top}
					isConnectableStart={isConnectable}
					isConnectableEnd={isConnectable}
					isConnectable={isConnectable}
				/>
			</div>
		</NodeRect>
	);
}

const volumeTypes = ["ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany", "ReadWriteOncePod"] as const;

const schema = z.object({
	name: z.string().min(1),
	type: z.enum(volumeTypes),
	size: z.string().min(1).default("1Gi"),
});

export function NodeVolumeDetails({ id, data }: VolumeNode) {
	const store = useStateStore();
	const form = useForm<z.infer<typeof schema>>({
		resolver: zodResolver(schema),
		mode: "onChange",
		defaultValues: {
			name: "",
			type: undefined,
			size: "",
		},
	});
	useEffect(() => {
		const sub = form.watch(
			(
				value: DeepPartial<z.infer<typeof schema>>,
				{ name, type }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
			) => {
				if (type !== "change") {
					return;
				}
				console.log({ name, type, value });
				store.updateNodeData<"volume">(id, {
					label: value.name,
					type: value.type,
					size: value.size,
				});
			},
		);
		return () => sub.unsubscribe();
	}, [id, form, store]);
	useEffect(() => {
		form.reset({
			name: data.label,
			type: data.type,
			size: data.size,
		});
	}, [form, data]);
	return (
		<>
			<Form {...form}>
				<form className="space-y-2">
					<FormField
						control={form.control}
						name="name"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="name" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="type"
						render={({ field }) => (
							<FormItem>
								<Select onValueChange={field.onChange} defaultValue={field.value}>
									<FormControl>
										<SelectTrigger>
											<SelectValue placeholder="Volume Type" />
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{volumeTypes.map((t) => (
											<SelectItem key={t} value={t}>
												{t}
											</SelectItem>
										))}
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="size"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="size" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
		</>
	);
}
