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, disabled }: VolumeNode & { disabled?: boolean }) {
	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} disabled={disabled} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="type"
						render={({ field }) => (
							<FormItem>
								<Select onValueChange={field.onChange} defaultValue={field.value} disabled={disabled}>
									<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} disabled={disabled} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
		</>
	);
}
