import { v4 as uuidv4 } from "uuid";
import { NodeRect } from "./node-rect";
import { useStateStore, nodeLabel, AppState, nodeIsConnectable, useEnv, useGithubRepositories } from "@/lib/state";
import {
	ServiceNode,
	ServiceTypes,
	GatewayHttpsNode,
	GatewayTCPNode,
	BoundEnvVar,
	AppNode,
	GithubNode,
	Machines,
	Machine,
	MachinesSchema,
} from "config";
import { KeyboardEvent, FocusEvent, useCallback, useEffect, useMemo, useState, useRef } from "react";
import { z } from "zod";
import { useForm, EventType, DeepPartial } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem, FormMessage, FormLabel } from "./ui/form";
import { Button } from "./ui/button";
import { Handle, Position, useNodes } from "@xyflow/react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
import { Textarea } from "./ui/textarea";
import { Input } from "./ui/input";
import { Switch } from "./ui/switch";
import { Label } from "./ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
import { Code, Container, Network, Pencil, Variable } from "lucide-react";
import { Badge } from "./ui/badge";
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "./ui/accordion";
import { Name } from "./node-name";
import { NodeDetailsProps } from "@/lib/types";
import { Gateway } from "@/Gateways";
import { Port } from "config";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { RadioGroup, RadioGroupItem } from "./ui/radio-group";
import { useToast } from "@/hooks/use-toast";
import { LoaderCircle } from "lucide-react";

const sourceSchema = z.object({
	id: z.string().min(1, "required"),
	branch: z.string(),
	rootDir: z.string(),
});

const devSchema = z.object({
	enabled: z.boolean(),
	mode: z.enum(["VM", "PROXY"]).optional(),
});

const exposeSchema = z.object({
	network: z.string().min(1, "reqired"),
	subdomain: z.string().min(1, "required"),
});

const agentSchema = z.object({
	model: z.enum(["gemini", "claude"]),
	apiKey: z.string().optional(),
});

const proxySchema = z.object({
	address: z.string().min(1, "required"),
});

const portExposeSchema = z
	.object({
		type: z.enum(["https", "tcp"]),
		network: z.string().min(1, "Required"),
		subdomain: z.string().optional(),
	})
	.refine(
		(data) => {
			if (data.type === "https" || data.type === "tcp") {
				return !!data.subdomain && data.subdomain.length > 0;
			}
			return true;
		},
		{
			message: "Subdomain is required",
			path: ["subdomain"],
		},
	);

type PortExposeFormValues = z.infer<typeof portExposeSchema>;

export function NodeApp(node: ServiceNode) {
	const { id, selected } = node;
	const isConnectablePorts = useMemo(() => nodeIsConnectable(node, "ports"), [node]);
	const isConnectableRepository = useMemo(() => nodeIsConnectable(node, "repository"), [node]);
	return (
		<NodeRect id={id} selected={selected} node={node} state={node.data.state}>
			<div style={{ padding: "10px 20px" }}>
				{nodeLabel(node)}
				<Handle
					id="repository"
					type={"target"}
					position={Position.Left}
					isConnectableStart={isConnectableRepository}
					isConnectableEnd={isConnectableRepository}
					isConnectable={isConnectableRepository}
				/>
				<Handle
					id="ports"
					type={"source"}
					position={Position.Top}
					isConnectableStart={isConnectablePorts}
					isConnectableEnd={isConnectablePorts}
					isConnectable={isConnectablePorts}
				/>
				<Handle
					id="env_var"
					type={"target"}
					position={Position.Bottom}
					isConnectableStart={true}
					isConnectableEnd={true}
					isConnectable={true}
				/>
			</div>
		</NodeRect>
	);
}

const schema = z.object({
	name: z.string().min(1, "requried"),
	type: z.enum(ServiceTypes),
});

function ExposeForm({
	node,
	port,
	onDone,
	disabled,
}: {
	node: ServiceNode;
	port: Port;
	onDone: () => void;
	disabled?: boolean;
}) {
	const store = useStateStore();
	const nodes = useNodes<AppNode>();
	const env = useEnv();
	const form = useForm<PortExposeFormValues>({
		resolver: zodResolver(portExposeSchema),
		mode: "onChange",
		defaultValues: {
			type: "https",
		},
	});

	const onSubmit = (data: PortExposeFormValues) => {
		const networkNode = nodes.find((n) => n.type === "network" && n.data.domain === data.network);
		if (!networkNode) {
			// TODO: should show an error to the user
			return;
		}
		if (data.type === "https") {
			const newNode: Omit<GatewayHttpsNode, "position"> = {
				id: uuidv4(),
				type: "gateway-https",
				data: {
					https: {
						serviceId: node.id,
						portId: port.id,
					},
					network: data.network,
					subdomain: data.subdomain!,
					label: "",
					envVars: [],
					ports: [],
				},
			};
			store.addNode(newNode);
			store.setEdges(
				store.edges.concat(
					{
						id: uuidv4(),
						source: node.id,
						sourceHandle: "ports",
						target: newNode.id,
						targetHandle: "https",
					},
					{
						id: uuidv4(),
						source: newNode.id,
						sourceHandle: "subdomain",
						target: networkNode.id,
						targetHandle: "subdomain",
					},
				),
			);
		} else if (data.type === "tcp") {
			const existingGateway = nodes.find(
				(n): n is GatewayTCPNode =>
					n.type === "gateway-tcp" && n.data.network === data.network && n.data.subdomain === data.subdomain,
			);
			if (existingGateway) {
				store.updateNodeData<"gateway-tcp">(existingGateway.id, {
					exposed: [...existingGateway.data.exposed, { serviceId: node.id, portId: port.id }],
				});
				let edges = store.edges.concat({
					id: uuidv4(),
					source: node.id,
					sourceHandle: "ports",
					target: existingGateway.id,
					targetHandle: "tcp",
				});
				if (
					!edges.find(
						(e) =>
							e.source === existingGateway.id &&
							e.target === networkNode.id &&
							e.sourceHandle === "subdomain" &&
							e.targetHandle === "subdomain",
					)
				) {
					edges = edges.concat({
						id: uuidv4(),
						source: existingGateway.id,
						sourceHandle: "subdomain",
						target: networkNode.id,
						targetHandle: "subdomain",
					});
				}
				store.setEdges(edges);
			} else {
				const newNode: Omit<GatewayTCPNode, "position"> = {
					id: uuidv4(),
					type: "gateway-tcp",
					data: {
						exposed: [{ serviceId: node.id, portId: port.id }],
						network: data.network,
						subdomain: data.subdomain,
						label: "",
						envVars: [],
						ports: [],
					},
				};
				store.addNode(newNode);
				store.setEdges(
					store.edges.concat(
						{
							id: uuidv4(),
							source: node.id,
							sourceHandle: "ports",
							target: newNode.id,
							targetHandle: "tcp",
						},
						{
							id: uuidv4(),
							source: newNode.id,
							sourceHandle: "subdomain",
							target: networkNode.id,
							targetHandle: "subdomain",
						},
					),
				);
			}
		}
		onDone();
	};

	const type = form.watch("type");

	return (
		<Form {...form}>
			<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-2 border-t mt-2 pt-2">
				<FormField
					control={form.control}
					name="type"
					render={({ field }) => (
						<FormItem>
							<FormLabel>Gateway Type</FormLabel>
							<Select onValueChange={field.onChange} defaultValue={field.value} disabled={disabled}>
								<FormControl>
									<SelectTrigger>
										<SelectValue placeholder="Select a type" />
									</SelectTrigger>
								</FormControl>
								<SelectContent>
									<SelectItem value="https">HTTPS</SelectItem>
									<SelectItem value="tcp">TCP</SelectItem>
								</SelectContent>
							</Select>
							<FormMessage />
						</FormItem>
					)}
				/>
				<FormField
					control={form.control}
					name="network"
					render={({ field }) => (
						<FormItem>
							<FormLabel>Network</FormLabel>
							<Select onValueChange={field.onChange} defaultValue={field.value} disabled={disabled}>
								<FormControl>
									<SelectTrigger>
										<SelectValue placeholder="Select a network" />
									</SelectTrigger>
								</FormControl>
								<SelectContent>
									{env.networks.map((n) => (
										<SelectItem key={n.domain} value={n.domain}>
											{n.name} - {n.domain}
										</SelectItem>
									))}
								</SelectContent>
							</Select>
							<FormMessage />
						</FormItem>
					)}
				/>
				{(type === "https" || type === "tcp") && (
					<FormField
						control={form.control}
						name="subdomain"
						render={({ field }) => (
							<FormItem>
								<FormLabel>Subdomain</FormLabel>
								<FormControl>
									<Input placeholder="subdomain" {...field} disabled={disabled} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
				)}
				<div className="flex justify-end gap-2">
					<Button type="button" variant="ghost" onClick={onDone} disabled={disabled}>
						Cancel
					</Button>
					<Button type="submit" disabled={disabled || !form.formState.isValid}>
						Expose
					</Button>
				</div>
			</form>
		</Form>
	);
}

export function NodeAppDetails({ node, disabled, showName = true, isOverview = false }: NodeDetailsProps<ServiceNode>) {
	const { data } = node;
	const defaultTab = useMemo(() => {
		if (data.dev?.enabled) {
			return "dev";
		}
		return "runtime";
	}, [data]);
	return (
		<>
			{showName ? <Name node={node} disabled={disabled} /> : null}
			<Tabs defaultValue={defaultTab}>
				<TabsList className="w-full flex flex-row justify-between">
					<TabsTrigger value="runtime">
						{isOverview ? (
							<div className="flex flex-row gap-1 items-center">
								<Container /> Runtime
							</div>
						) : (
							<TooltipProvider>
								<Tooltip>
									<TooltipTrigger>
										<Container />
									</TooltipTrigger>
									<TooltipContent>Runtime</TooltipContent>
								</Tooltip>
							</TooltipProvider>
						)}
					</TabsTrigger>
					<TabsTrigger value="ports">
						{isOverview ? (
							<div className="flex flex-row gap-1 items-center">
								<Network /> Ports
								<Badge className="rounded-full">{data.ports?.length ?? 0}</Badge>
							</div>
						) : (
							<TooltipProvider>
								<Tooltip>
									<TooltipTrigger className="flex flex-row gap-1 items-center">
										<Network />
									</TooltipTrigger>
									<TooltipContent>
										Ports{" "}
										<Badge variant="secondary" className="rounded-full">
											{data.ports?.length ?? 0}
										</Badge>
									</TooltipContent>
								</Tooltip>
							</TooltipProvider>
						)}
					</TabsTrigger>
					<TabsTrigger value="vars">
						{isOverview ? (
							<div className="flex flex-row gap-1 items-center">
								<Variable /> Variables
								<Badge className="rounded-full">{data.envVars?.length ?? 0}</Badge>
							</div>
						) : (
							<TooltipProvider>
								<Tooltip>
									<TooltipTrigger className="flex flex-row gap-1 items-center">
										<Variable />
									</TooltipTrigger>
									<TooltipContent>
										Variables{" "}
										<Badge variant="secondary" className="rounded-full">
											{data.envVars?.length ?? 0}
										</Badge>
									</TooltipContent>
								</Tooltip>
							</TooltipProvider>
						)}
					</TabsTrigger>
					{node.data.type !== "sketch:latest" && (
						<TabsTrigger value="dev">
							{isOverview ? (
								<div className="flex flex-row gap-1 items-center">
									<Code /> Dev
								</div>
							) : (
								<TooltipProvider>
									<Tooltip>
										<TooltipTrigger className="flex flex-row gap-1 items-center">
											<Code />
										</TooltipTrigger>
										<TooltipContent>Dev</TooltipContent>
									</Tooltip>
								</TooltipProvider>
							)}
						</TabsTrigger>
					)}
				</TabsList>
				<TabsContent value="runtime">
					<Runtime node={node} disabled={disabled} />
				</TabsContent>
				<TabsContent value="ports">
					<Ports node={node} disabled={disabled} isOverview={isOverview} />
				</TabsContent>
				<TabsContent value="vars">
					<EnvVars node={node} disabled={disabled} />
				</TabsContent>
				{node.data.type !== "sketch:latest" && (
					<TabsContent value="dev">
						<Dev node={node} disabled={disabled} />
					</TabsContent>
				)}
			</Tabs>
		</>
	);
}

function Runtime({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	const form = useForm<z.infer<typeof schema>>({
		resolver: zodResolver(schema),
		mode: "onChange",
		defaultValues: {
			name: data.label,
			type: data.type,
		},
	});
	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;
				}
				switch (name) {
					case "name":
						if (!value.name) {
							break;
						}
						store.updateNodeData<"app">(id, {
							label: value.name,
						});
						break;
					case "type":
						if (!value.type) {
							break;
						}
						store.updateNodeData<"app">(id, {
							type: value.type,
						});
						break;
				}
			},
		);
		return () => sub.unsubscribe();
	}, [id, form, store]);
	const [typeProps, setTypeProps] = useState({});
	useEffect(() => {
		if (data.activeField === "type") {
			setTypeProps({
				open: true,
				onOpenChange: () => store.updateNodeData(id, { activeField: undefined }),
			});
		} else {
			setTypeProps({});
		}
	}, [id, data, store, setTypeProps]);
	const setPreBuildCommands = useCallback(
		(e: React.ChangeEvent<HTMLTextAreaElement>) => {
			store.updateNodeData<"app">(id, {
				preBuildCommands: e.currentTarget.value,
			});
		},
		[id, store],
	);
	const agentForm = useForm<z.infer<typeof agentSchema>>({
		resolver: zodResolver(agentSchema),
		mode: "onChange",
		defaultValues: {
			apiKey: data.model?.apiKey,
			model: data.model?.name,
		},
	});
	useEffect(() => {
		const sub = agentForm.watch((value, { name }: { name?: keyof z.infer<typeof agentSchema> | undefined }) => {
			switch (name) {
				case "model":
					agentForm.setValue("apiKey", "", { shouldDirty: true });
					store.updateNodeData<"app">(id, {
						model: {
							name: value.model,
							apiKey: undefined,
						},
					});
					break;
				case "apiKey":
					store.updateNodeData<"app">(id, {
						model: {
							name: data.model?.name,
							apiKey: value.apiKey,
						},
					});
					break;
			}
		});
		return () => sub.unsubscribe();
	}, [id, agentForm, store, data]);
	return (
		<>
			<SourceRepo node={node} disabled={disabled} />
			{node.data.type !== "sketch:latest" && (
				<Form {...form}>
					<form className="space-y-2">
						<Label>Container Image</Label>
						<FormField
							control={form.control}
							name="type"
							render={({ field }) => (
								<FormItem>
									<Select
										onValueChange={field.onChange}
										value={field.value || ""}
										{...typeProps}
										disabled={disabled}
									>
										<FormControl>
											<SelectTrigger>
												<SelectValue />
											</SelectTrigger>
										</FormControl>
										<SelectContent>
											{ServiceTypes.filter((t) => t !== "sketch:latest").map((t) => (
												<SelectItem key={t} value={t}>
													{t}
												</SelectItem>
											))}
										</SelectContent>
									</Select>
									<FormMessage />
								</FormItem>
							)}
						/>
					</form>
				</Form>
			)}
			{node.data.type === "sketch:latest" && (
				<Form {...agentForm}>
					<form className="space-y-2">
						<FormField
							control={agentForm.control}
							name="model"
							render={({ field }) => (
								<FormItem>
									<FormLabel>AI Model</FormLabel>
									<Select
										onValueChange={field.onChange}
										defaultValue={field.value}
										disabled={disabled}
									>
										<FormControl>
											<SelectTrigger>
												<SelectValue placeholder="Select a model" />
											</SelectTrigger>
										</FormControl>
										<SelectContent>
											<SelectItem value="gemini">Gemini</SelectItem>
											<SelectItem value="claude">Claude</SelectItem>
										</SelectContent>
									</Select>
									<FormMessage />
								</FormItem>
							)}
						/>
						<Label>API Key</Label>
						<FormField
							control={agentForm.control}
							name="apiKey"
							render={({ field }) => (
								<FormItem>
									<FormControl>
										<Input
											type="password"
											placeholder="Override AI Model API key"
											{...field}
											value={field.value || ""}
											disabled={disabled}
										/>
									</FormControl>
									<FormMessage />
								</FormItem>
							)}
						/>
					</form>
				</Form>
			)}
			{node.data.type !== "sketch:latest" && (
				<>
					<Label>Pre-Build Commands</Label>
					<Textarea
						placeholder="new line separated list of commands to run before running the service"
						value={data.preBuildCommands}
						onChange={setPreBuildCommands}
						disabled={disabled}
					/>
				</>
			)}
		</>
	);
}

function Ports({
	node,
	disabled,
	isOverview,
}: {
	node: ServiceNode;
	disabled?: boolean;
	isOverview?: boolean;
}): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	const nodes = useNodes<AppNode>();
	const [portIngresses, setPortIngresses] = useState<Record<string, string[]>>({});
	const [exposingPortId, setExposingPortId] = useState<string | null>(null);

	const httpsGateways = useMemo(
		() => nodes.filter((n): n is GatewayHttpsNode => n.type === "gateway-https"),
		[nodes],
	);

	useEffect(() => {
		if (!data.ports) {
			setPortIngresses({});
			return;
		}
		const newIngresses: Record<string, string[]> = {};
		for (const port of data.ports) {
			newIngresses[port.id] = [];
		}
		for (const gateway of httpsGateways) {
			const https = gateway.data.https;
			if (https && https.serviceId === id && https.portId && gateway.data.network && gateway.data.subdomain) {
				const url = `https://${gateway.data.subdomain}.${gateway.data.network}`;
				if (newIngresses[https.portId]) {
					newIngresses[https.portId].push(url);
				} else {
					newIngresses[https.portId] = [url];
				}
			}
		}
		setPortIngresses(newIngresses);
		console.log(newIngresses);
	}, [id, data.ports, httpsGateways]);

	const [name, setName] = useState("");
	const [value, setValue] = useState("");
	const onSubmit = useCallback(() => {
		const portId = uuidv4();
		store.updateNodeData<"app">(id, {
			ports: (data.ports || []).concat({
				id: portId,
				name: name.toUpperCase(),
				value: Number(value),
			}),
			envVars: (data.envVars || []).concat(
				{
					id: uuidv4(),
					source: null,
					portId,
					name: `DODO_PORT_${name.toUpperCase()}`,
				},
				{
					id: uuidv4(),
					source: null,
					portId,
					name: `DODO_PORT_${name.toUpperCase()}`,
					alias: name.toUpperCase(),
				},
			),
		});
		setName("");
		setValue("");
	}, [id, data, store, name, value, setName, setValue]);
	const removePort = useCallback(
		(portId: string) => {
			// TODO(gio): this is ugly
			const tcpRemoved = new Set<string>();
			store.setEdges(
				store.edges.filter((e) => {
					if (e.source !== id || e.sourceHandle !== "ports") {
						return true;
					}
					const tn = store.nodes.find((n) => n.id == e.target)!;
					if (e.targetHandle === "https") {
						const t = tn as GatewayHttpsNode;
						if (t.data.https?.serviceId === id && t.data.https.portId === portId) {
							return false;
						}
					}
					if (e.targetHandle === "tcp") {
						const t = tn as GatewayTCPNode;
						if (tcpRemoved.has(t.id)) {
							return true;
						}
						if (t.data.exposed.find((e) => e.serviceId === id && e.portId === portId)) {
							tcpRemoved.add(t.id);
							return false;
						}
					}
					if (e.targetHandle === "env_var") {
						if (
							tn &&
							(tn.data.envVars || []).find(
								(ev) => ev.source === id && "portId" in ev && ev.portId === portId,
							)
						) {
							return false;
						}
					}
					return true;
				}),
			);
			store.nodes
				.filter(
					(n) =>
						n.type === "gateway-https" &&
						n.data.https &&
						n.data.https.serviceId === id &&
						n.data.https.portId === portId,
				)
				.forEach((n) => {
					store.updateNodeData<"gateway-https">(n.id, {
						https: undefined,
					});
				});
			store.nodes
				.filter((n) => n.type === "gateway-tcp")
				.forEach((n) => {
					const filtered = n.data.exposed.filter((e) => {
						if (e.serviceId === id && e.portId === portId) {
							return false;
						} else {
							return true;
						}
					});
					if (filtered.length != n.data.exposed.length) {
						store.updateNodeData<"gateway-tcp">(n.id, {
							exposed: filtered,
						});
					}
				});
			store.nodes
				.filter((n) => n.type === "app" && n.data.envVars)
				.forEach((n) => {
					store.updateNodeData<"app">(n.id, {
						envVars: n.data.envVars.filter((ev) => {
							if (ev.source === id && "portId" in ev && ev.portId === portId) {
								return false;
							}
							return true;
						}),
					});
				});
			store.updateNodeData<"app">(id, {
				ports: (data.ports || []).filter((p) => p.id !== portId),
				envVars: (data.envVars || []).filter(
					(ev) => !(ev.source === null && "portId" in ev && ev.portId === portId),
				),
			});
		},
		[id, data, store],
	);
	return (
		<div className="flex flex-col gap-1">
			<div className="grid grid-cols-[1fr_1fr_auto] gap-1">
				{data &&
					data.ports &&
					data.ports.map((p) => (
						<div key={p.id} className="contents">
							<div className="contents">
								<div className="flex items-center px-3">{p.name.toUpperCase()}</div>
								<div className="flex items-center px-3">{p.value}</div>
								<div className="flex items-center gap-1">
									{isOverview && (
										<Button
											variant="outline"
											onClick={() => setExposingPortId(p.id)}
											disabled={disabled}
										>
											Expose
										</Button>
									)}
									<Button
										variant="destructive"
										className="w-full"
										onClick={() => removePort(p.id)}
										disabled={disabled}
									>
										Remove
									</Button>
								</div>
							</div>
							{portIngresses[p.id]?.length > 0 && (
								<div key={p.id} className="col-span-full pl-6">
									{portIngresses[p.id].map((url) => (
										<Gateway key={url} g={{ type: "https", address: url, name: p.name }} />
									))}
								</div>
							)}
							{exposingPortId === p.id && (
								<Dialog open={true} onOpenChange={() => setExposingPortId(null)}>
									<DialogContent>
										<DialogHeader>
											<DialogTitle>
												Expose Port {p.name}:{p.value}
											</DialogTitle>
										</DialogHeader>
										<ExposeForm
											node={node}
											port={p}
											onDone={() => setExposingPortId(null)}
											disabled={disabled}
										/>
									</DialogContent>
								</Dialog>
							)}
						</div>
					))}
				<div>
					<Input
						placeholder="name"
						className="uppercase w-0 min-w-full"
						disabled={disabled}
						value={name}
						onChange={(e) => setName(e.target.value)}
					/>
				</div>
				<div>
					<Input
						placeholder="0"
						className="w-0 min-w-full"
						disabled={disabled}
						value={value}
						onChange={(e) => setValue(e.target.value)}
					/>
				</div>
				<div>
					<Button type="submit" className="w-full" disabled={disabled} onClick={onSubmit}>
						Add
					</Button>
				</div>
			</div>
		</div>
	);
}

function EnvVars({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	const [name, setName] = useState("");
	const [value, setValue] = useState("");

	const addEnvVar = useCallback(() => {
		if (!name.trim() || !value.trim()) return;
		store.updateNodeData<"app">(id, {
			envVars: (data.envVars || []).concat({
				id: uuidv4(),
				source: null,
				name: name.toUpperCase(),
				value: value,
			}),
		});
		setName("");
		setValue("");
	}, [id, data, store, name, value]);

	const removeEnvVar = useCallback(
		(varId: string) => {
			store.updateNodeData<"app">(id, {
				envVars: (data.envVars || []).filter((v) => v.id !== varId),
			});
		},
		[id, data, store],
	);

	const editValueEnvVar = useCallback(
		(varId: string) => {
			if (disabled) return;
			store.updateNodeData<"app">(id, {
				envVars: (data.envVars || []).map((v) => (v.id === varId ? { ...v, isEditting: true } : v)),
			});
		},
		[id, data, store, disabled],
	);

	const saveValueEnvVar = useCallback(
		(varId: string, newName: string, newValue: string) => {
			store.updateNodeData<"app">(id, {
				envVars: (data.envVars || []).map((v) => {
					if (v.id === varId) {
						return { ...v, name: newName.toUpperCase(), value: newValue, isEditting: false };
					}
					return v;
				}),
			});
		},
		[id, data, store],
	);

	const editAlias = useCallback(
		(e: BoundEnvVar) => {
			return () => {
				if (disabled) {
					return;
				}
				store.updateNodeData(id, {
					...data,
					envVars: data.envVars!.map((o) => {
						if (o.id !== e.id) {
							return o;
						} else
							return {
								...o,
								isEditting: true,
							};
					}),
				});
			};
		},
		[id, data, store, disabled],
	);

	const saveAlias = useCallback(
		(e: BoundEnvVar, value: string, store: AppState) => {
			store.updateNodeData(id, {
				...data,
				envVars: data.envVars!.map((o) => {
					if (o.id !== e.id) {
						return o;
					}
					if (value) {
						if ("name" in o && value.toUpperCase() === o.name.toUpperCase()) {
							return {
								...o,
								isEditting: false,
								alias: undefined,
							};
						} else {
							return {
								...o,
								isEditting: false,
								alias: value.toUpperCase(),
							};
						}
					}
					if ("alias" in o) {
						const { alias: _, ...rest } = o;
						return {
							...rest,
							isEditting: false,
						};
					}
					return {
						...o,
						isEditting: false,
					};
				}),
			});
		},
		[id, data],
	);

	const saveAliasOnEnter = useCallback(
		(e: BoundEnvVar) => {
			return (event: KeyboardEvent<HTMLInputElement>) => {
				if (event.key === "Enter") {
					saveAlias(e, event.currentTarget.value, store);
				} else if (event.key === "Escape") {
					store.updateNodeData(id, {
						...data,
						envVars: data.envVars!.map((o) => (o.id === e.id ? { ...o, isEditting: false } : o)),
					});
				}
			};
		},
		[store, saveAlias, id, data],
	);

	const saveAliasOnBlur = useCallback(
		(e: BoundEnvVar) => {
			return (event: FocusEvent<HTMLInputElement>) => {
				saveAlias(e, event.currentTarget.value, store);
			};
		},
		[store, saveAlias],
	);

	return (
		<div className="flex flex-col gap-1">
			<div className="grid grid-cols-[auto_1fr_1fr_auto] gap-1">
				{data?.envVars?.map((v) => {
					if ("value" in v) {
						if (v.isEditting) {
							return (
								<div key={v.id} className="contents">
									<Input
										className="uppercase col-start-2"
										defaultValue={v.name}
										onKeyUp={(e) => {
											if (e.key === "Enter") {
												const nameInput = e.currentTarget;
												const valueInput = nameInput.parentElement?.querySelector(
													'input[placeholder="Value"]',
												) as HTMLInputElement;
												if (valueInput) {
													saveValueEnvVar(v.id, nameInput.value, valueInput.value);
												}
											} else if (e.key === "Escape") {
												store.updateNodeData(id, {
													...data,
													envVars: data.envVars!.map((o) =>
														o.id === v.id ? { ...o, isEditting: false } : o,
													),
												});
											}
										}}
										autoFocus
										disabled={disabled}
									/>
									<Input
										placeholder="Value"
										defaultValue={v.value}
										onKeyUp={(e) => {
											if (e.key === "Enter") {
												const valueInput = e.currentTarget;
												const nameInput = valueInput.parentElement?.querySelector(
													'input:not([placeholder="Value"])',
												) as HTMLInputElement;
												if (nameInput) {
													saveValueEnvVar(v.id, nameInput.value, valueInput.value);
												}
											} else if (e.key === "Escape") {
												store.updateNodeData(id, {
													...data,
													envVars: data.envVars!.map((o) =>
														o.id === v.id ? { ...o, isEditting: false } : o,
													),
												});
											}
										}}
										disabled={disabled}
									/>
									<Button
										variant="destructive"
										size="sm"
										onClick={() => removeEnvVar(v.id)}
										disabled={disabled}
									>
										Remove
									</Button>
								</div>
							);
						}
						return (
							<div
								key={v.id}
								className={`contents ${disabled ? "" : "cursor-text"}`}
								onClick={() => editValueEnvVar(v.id)}
							>
								<div>{!disabled && <Pencil className="w-4 h-4" />}</div>
								<div className={`${disabled ? "col-span-2" : ""} col-start-2`}>{v.name}</div>
								<div>{v.value}</div>
								<Button
									variant="destructive"
									size="sm"
									onClick={(e) => {
										e.stopPropagation();
										removeEnvVar(v.id);
									}}
									disabled={disabled}
								>
									Remove
								</Button>
							</div>
						);
					}
					if ("name" in v) {
						const value = "alias" in v ? v.alias : v.name;
						if (v.isEditting) {
							return (
								<Input
									type="text"
									className="uppercase col-start-2 col-span-3"
									defaultValue={value}
									onKeyUp={saveAliasOnEnter(v)}
									onBlur={saveAliasOnBlur(v)}
									autoFocus={true}
									disabled={disabled}
								/>
							);
						}
						return (
							<div
								key={v.id}
								onClick={editAlias(v)}
								className={`contents ${disabled ? "" : "cursor-text"}`}
							>
								{!disabled && <Pencil className="w-4 h-4" />}
								<div className="col-start-2 col-span-3">
									<TooltipProvider>
										<Tooltip>
											<TooltipTrigger className="uppercase">{value}</TooltipTrigger>
											<TooltipContent>{v.name}</TooltipContent>
										</Tooltip>
									</TooltipProvider>
								</div>
							</div>
						);
					}
					return null;
				})}
				{!disabled && (
					<div className="contents">
						<Input
							placeholder="Name"
							className="uppercase col-start-2"
							value={name}
							onChange={(e) => setName(e.target.value)}
							disabled={disabled}
						/>
						<Input
							placeholder="Value"
							value={value}
							onChange={(e) => setValue(e.target.value)}
							disabled={disabled}
						/>
						<Button onClick={addEnvVar} disabled={disabled || !name.trim() || !value.trim()}>
							Add
						</Button>
					</div>
				)}
			</div>
		</div>
	);
}

function usePrevious<T>(value: T) {
	const ref = useRef<T>();
	useEffect(() => {
		ref.current = value;
	}, [value]);
	return ref.current;
}

function DevVM({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const { dev } = data;
	const prevDev = usePrevious(dev);
	const env = useEnv();
	const store = useStateStore();
	useEffect(() => {
		console.log("DDDEV", prevDev, dev);
		if (!dev && !prevDev) {
			return;
		}
		if (
			dev &&
			prevDev &&
			dev.enabled === prevDev.enabled &&
			"mode" in dev &&
			"mode" in prevDev &&
			dev.mode === prevDev.mode
		) {
			return;
		}
		if (!dev?.enabled || dev.mode !== "VM") {
			if (prevDev?.enabled && prevDev.mode === "VM") {
				store.setNodes(
					store.nodes.filter((n) => n.id !== prevDev.codeServerNodeId && n.id !== prevDev.sshNodeId),
				);
				store.setEdges(
					store.edges.filter((e) => e.target !== prevDev.codeServerNodeId && e.target !== prevDev.sshNodeId),
				);
				if (dev?.enabled) {
					store.updateNodeData<"app">(id, {
						dev: {
							enabled: dev.enabled,
							mode: dev.mode,
						},
						ports: (data.ports || []).filter((p) => p.name !== "code-server" && p.name !== "ssh"),
					});
				} else {
					store.updateNodeData<"app">(id, {
						dev: {
							enabled: false,
						},
						ports: (data.ports || []).filter((p) => p.name !== "code-server" && p.name !== "ssh"),
					});
				}
			}
		} else {
			if (!prevDev?.enabled || prevDev.mode !== "VM") {
				const csGateway: Omit<GatewayHttpsNode, "position"> = {
					id: uuidv4(),
					type: "gateway-https",
					data: {
						readonly: true,
						https: {
							serviceId: id,
							portId: `${id}-code-server`,
						},
						network: dev?.expose?.network,
						subdomain: dev?.expose?.subdomain,
						label: "",
						envVars: [],
						ports: [],
					},
				};
				const sshGateway: Omit<GatewayTCPNode, "position"> = {
					id: uuidv4(),
					type: "gateway-tcp",
					data: {
						readonly: true,
						exposed: [
							{
								serviceId: id,
								portId: `${id}-ssh`,
							},
						],
						network: dev?.expose?.network,
						subdomain: dev?.expose?.subdomain,
						label: "",
						envVars: [],
						ports: [],
					},
				};
				store.addNode(csGateway);
				store.addNode(sshGateway);
				store.updateNodeData<"app">(id, {
					dev: {
						enabled: true,
						mode: "VM",
						expose: dev?.expose,
						codeServerNodeId: csGateway.id,
						sshNodeId: sshGateway.id,
					},
					ports: (data.ports || []).concat(
						{
							id: `${id}-code-server`,
							name: "code-server",
							value: 9090,
						},
						{
							id: `${id}-ssh`,
							name: "ssh",
							value: 22,
						},
					),
				});
				let edges = store.edges.concat([
					{
						id: uuidv4(),
						source: id,
						sourceHandle: "ports",
						target: csGateway.id,
						targetHandle: "https",
					},
					{
						id: uuidv4(),
						source: id,
						sourceHandle: "ports",
						target: sshGateway.id,
						targetHandle: "tcp",
					},
				]);
				if (dev?.expose?.network !== undefined) {
					edges = edges.concat([
						{
							id: uuidv4(),
							source: csGateway.id,
							sourceHandle: "subdomain",
							target: dev.expose.network,
							targetHandle: "subdomain",
						},
						{
							id: uuidv4(),
							source: sshGateway.id,
							sourceHandle: "subdomain",
							target: dev.expose.network,
							targetHandle: "subdomain",
						},
					]);
				}
				store.setEdges(edges);
			}
		}
	}, [id, data, dev, prevDev, store]);
	const exposeForm = useForm<z.infer<typeof exposeSchema>>({
		resolver: zodResolver(exposeSchema),
		mode: "onChange",
		defaultValues: {
			network: dev && "expose" in dev ? dev.expose?.network : undefined,
			subdomain: dev && "expose" in dev ? dev.expose?.subdomain : undefined,
		},
	});
	useEffect(() => {
		const sub = exposeForm.watch(
			(
				value: DeepPartial<z.infer<typeof exposeSchema>>,
				{ name }: { name?: keyof z.infer<typeof exposeSchema> | undefined; type?: EventType | undefined },
			) => {
				const { dev } = data;
				if (!dev?.enabled || dev.mode !== "VM") {
					return;
				}
				if (name === "network") {
					let edges = store.edges;
					if (dev.enabled && dev.expose?.network !== undefined) {
						edges = edges.filter((e) => {
							if (
								(e.source === dev.codeServerNodeId || e.source === dev.sshNodeId) &&
								e.sourceHandle === "subdomain" &&
								e.target === dev.expose?.network &&
								e.targetHandle === "subdomain"
							) {
								return false;
							} else {
								return true;
							}
						});
					}
					if (value.network !== undefined) {
						edges = edges.concat(
							{
								id: uuidv4(),
								source: dev.codeServerNodeId,
								sourceHandle: "subdomain",
								target: value.network,
								targetHandle: "subdomain",
							},
							{
								id: uuidv4(),
								source: dev.sshNodeId,
								sourceHandle: "subdomain",
								target: value.network,
								targetHandle: "subdomain",
							},
						);
					}
					store.setEdges(edges);
					store.updateNodeData<"app">(id, {
						dev: {
							...dev,
							expose: {
								network: value.network,
								subdomain: dev.expose?.subdomain,
							},
						},
					});
					store.updateNodeData<"gateway-https">(dev.codeServerNodeId, { network: value.network });
					store.updateNodeData<"gateway-tcp">(dev.sshNodeId, { network: value.network });
				} else if (name === "subdomain") {
					store.updateNodeData<"app">(id, {
						dev: {
							...dev,
							expose: {
								network: dev.expose?.network,
								subdomain: value.subdomain,
							},
						},
					});
					store.updateNodeData<"gateway-https">(dev.codeServerNodeId, { subdomain: value.subdomain });
					store.updateNodeData<"gateway-tcp">(dev.sshNodeId, { subdomain: value.subdomain });
				}
			},
		);
		return () => sub.unsubscribe();
	}, [id, data, dev, prevDev, exposeForm, store]);
	if (!dev?.enabled || dev.mode !== "VM") {
		return null;
	}
	return (
		<div>
			{data.dev && data.dev.enabled && (
				<Form {...exposeForm}>
					<form className="space-y-2">
						<Label>Network</Label>
						<FormField
							control={exposeForm.control}
							name="network"
							render={({ field }) => (
								<FormItem>
									<Select
										onValueChange={field.onChange}
										value={field.value || ""}
										disabled={disabled}
									>
										<FormControl>
											<SelectTrigger>
												<SelectValue />
											</SelectTrigger>
										</FormControl>
										<SelectContent>
											{env.networks.map((n) => (
												<SelectItem
													key={n.name}
													value={n.domain}
												>{`${n.name} - ${n.domain}`}</SelectItem>
											))}
										</SelectContent>
									</Select>
									<FormMessage />
								</FormItem>
							)}
						/>
						<Label>Subdomain</Label>
						<FormField
							control={exposeForm.control}
							name="subdomain"
							render={({ field }) => (
								<FormItem>
									<FormControl>
										<Input {...field} disabled={disabled} />
									</FormControl>
									<FormMessage />
								</FormItem>
							)}
						/>
					</form>
				</Form>
			)}
		</div>
	);
}

function DevProxy({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	const { toast } = useToast();
	const [machines, setMachines] = useState<Machines>([]);
	const [loading, setLoading] = useState(false);
	const [error, setError] = useState<string | null>(null);

	const fetchMachines = useCallback(async () => {
		setLoading(true);
		setError(null);
		try {
			const response = await fetch("/api/machines", {
				method: "GET",
				headers: {
					"Content-Type": "application/json",
				},
			});

			if (!response.ok) {
				throw new Error(`Failed to fetch machines: ${response.statusText}`);
			}

			const machinesData = MachinesSchema.safeParse(await response.json());
			if (machinesData.success) {
				setMachines(machinesData.data);
			} else {
				throw new Error("Invalid machines data");
			}
		} catch (err) {
			const errorMessage = err instanceof Error ? err.message : "Failed to fetch machines";
			setError(errorMessage);
			toast({
				variant: "destructive",
				title: "Error",
				description: errorMessage,
			});
		} finally {
			setLoading(false);
		}
	}, [toast]);

	useEffect(() => {
		if (data.dev?.enabled && "mode" in data.dev && data.dev.mode === "PROXY") {
			fetchMachines();
		}
	}, [data.dev, fetchMachines]);

	const proxyForm = useForm<z.infer<typeof proxySchema>>({
		resolver: zodResolver(proxySchema),
		mode: "onChange",
		defaultValues: {
			address: data.dev && "address" in data.dev ? data.dev.address : undefined,
		},
	});

	useEffect(() => {
		const sub = proxyForm.watch((value, { name }) => {
			if (name === "address" && value.address) {
				store.updateNodeData<"app">(id, {
					dev: {
						enabled: true,
						mode: "PROXY",
						address: value.address,
					},
				});
			}
		});
		return () => sub.unsubscribe();
	}, [id, proxyForm, store]);

	if (!data.dev?.enabled || data.dev.mode !== "PROXY") {
		return null;
	}
	return (
		<div className="space-y-2">
			<Form {...proxyForm}>
				<form className="space-y-2">
					<FormField
						control={proxyForm.control}
						name="address"
						render={({ field }) => (
							<FormItem>
								<Select
									onValueChange={field.onChange}
									value={field.value || ""}
									disabled={disabled || loading}
								>
									<FormControl>
										<SelectTrigger>
											{loading ? (
												<div className="flex items-center gap-2">
													<LoaderCircle className="h-4 w-4 animate-spin" />
													<span>Loading machines...</span>
												</div>
											) : (
												<SelectValue placeholder="Select a machine" />
											)}
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{loading ? (
											<div className="flex items-center justify-center p-4">
												<LoaderCircle className="h-4 w-4 animate-spin" />
												<span className="ml-2">Loading...</span>
											</div>
										) : error ? (
											<div className="flex flex-col items-center justify-center p-4 text-destructive">
												<span className="text-sm">Failed to load machines</span>
												<Button
													variant="ghost"
													size="sm"
													className="mt-2"
													onClick={fetchMachines}
												>
													Retry
												</Button>
											</div>
										) : machines.length === 0 ? (
											<div className="flex items-center justify-center p-4 text-muted-foreground">
												<span className="text-sm">No machines available</span>
											</div>
										) : (
											machines.map((machine: Machine) => (
												<SelectItem key={machine.name} value={machine.name}>
													{machine.name}
												</SelectItem>
											))
										)}
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
		</div>
	);
}

function Dev({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	const devForm = useForm<z.infer<typeof devSchema>>({
		resolver: zodResolver(devSchema),
		mode: "onChange",
		defaultValues: {
			enabled: data.dev ? data.dev.enabled : false,
			mode: data.dev?.enabled ? data.dev.mode : undefined,
		},
	});
	useEffect(() => {
		const sub = devForm.watch((value, { name }) => {
			console.log("DDDEVV", name, value, data.dev);
			if (name === "enabled") {
				if (value.enabled) {
					if (data.dev?.enabled && data.dev.mode === "VM") {
						return;
					}
					store.updateNodeData<"app">(id, {
						dev: {
							enabled: true,
							mode: "VM",
						},
					});
					devForm.setValue("mode", "VM");
				} else {
					store.updateNodeData<"app">(id, {
						dev: {
							enabled: false,
						},
					});
				}
			} else if (name === "mode") {
				if (data.dev?.enabled && data.dev.mode === value.mode) {
					return;
				}
				store.updateNodeData<"app">(id, {
					dev: {
						enabled: true,
						mode: value.mode,
					},
				});
			}
		});
		return () => sub.unsubscribe();
	}, [id, data, devForm, store]);
	return (
		<>
			<Form {...devForm}>
				<form className="space-y-2">
					<FormField
						control={devForm.control}
						name="enabled"
						render={({ field }) => (
							<FormItem>
								<div className="flex flex-row gap-1 items-center">
									<Switch
										id="devEnabled"
										onCheckedChange={field.onChange}
										checked={field.value}
										disabled={disabled}
									/>
									<Label htmlFor="devEnabled">Development Mode</Label>
								</div>
								<FormMessage />
							</FormItem>
						)}
					/>
					{data.dev?.enabled && (
						<FormField
							control={devForm.control}
							name="mode"
							render={({ field }) => (
								<FormItem>
									<div className="flex flex-row gap-1 items-center">
										<RadioGroup
											onValueChange={field.onChange}
											value={field.value}
											disabled={disabled}
										>
											<div className="flex items-center space-x-2">
												<RadioGroupItem value="VM" id="vm" />
												<Label htmlFor="vm">Create a VM</Label>
											</div>
											<div className="flex items-center space-x-2">
												<RadioGroupItem value="PROXY" id="proxy" />
												<Label htmlFor="proxy">Proxy to existing machine</Label>
											</div>
										</RadioGroup>
									</div>
								</FormItem>
							)}
						/>
					)}
				</form>
			</Form>
			<DevVM node={node} disabled={disabled} />
			<DevProxy node={node} disabled={disabled} />
		</>
	);
}

function SourceRepo({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	const nodes = useNodes<AppNode>();
	const repo = useMemo(() => {
		return nodes
			.filter((n): n is GithubNode => n.type === "github")
			.find((n) => n.id === data.repository?.repoNodeId);
	}, [nodes, data.repository?.repoNodeId]);
	const repos = useGithubRepositories();
	const sourceForm = useForm<z.infer<typeof sourceSchema>>({
		resolver: zodResolver(sourceSchema),
		mode: "onChange",
		defaultValues: {
			id: data?.repository?.id?.toString(),
			branch: data.repository && "branch" in data.repository ? data.repository.branch : undefined,
			rootDir: data.repository && "rootDir" in data.repository ? data.repository.rootDir : undefined,
		},
	});
	useEffect(() => {
		const sub = sourceForm.watch(
			(
				value: DeepPartial<z.infer<typeof sourceSchema>>,
				{ name }: { name?: keyof z.infer<typeof sourceSchema> | undefined; type?: EventType | undefined },
			) => {
				if (name === "id") {
					const newRepoId = value.id ? parseInt(value.id, 10) : undefined;
					if (!newRepoId) return;

					const oldGithubNodeId = data.repository?.repoNodeId;
					const selectedRepo = repos.find((r) => r.id === newRepoId);

					if (!selectedRepo) return;

					// If a node for the selected repo already exists, connect to it.
					const existingNodeForSelectedRepo = nodes
						.filter((n): n is GithubNode => n.type === "github")
						.find((n) => n.data.repository?.id === selectedRepo.id);

					if (existingNodeForSelectedRepo) {
						let { nodes, edges } = store;
						if (oldGithubNodeId) {
							edges = edges.filter(
								(e) =>
									!(
										e.target === id &&
										e.source === oldGithubNodeId &&
										e.targetHandle === "repository"
									),
							);
						}
						edges = edges.concat({
							id: uuidv4(),
							source: existingNodeForSelectedRepo.id,
							sourceHandle: "repository",
							target: id,
							targetHandle: "repository",
						});
						nodes = nodes.map((n) => {
							if (n.id !== id) {
								return n;
							} else {
								const sn = n as ServiceNode;
								return {
									...sn,
									data: {
										...sn.data,
										repository: {
											...sn.data.repository,
											id: newRepoId,
											repoNodeId: existingNodeForSelectedRepo.id,
										},
									},
								};
							}
						});
						if (oldGithubNodeId && oldGithubNodeId !== existingNodeForSelectedRepo.id) {
							const isOldNodeStillUsed = edges.some(
								(e) => e.source === oldGithubNodeId && e.sourceHandle === "repository",
							);
							if (!isOldNodeStillUsed) {
								nodes = nodes.filter((n) => n.id !== oldGithubNodeId);
							}
						}
						store.setNodes(nodes);
						store.setEdges(edges);
						return;
					}

					// No node for selected repo, decide whether to update old node or create a new one.
					if (oldGithubNodeId) {
						const isOldNodeShared =
							store.edges.filter(
								(e) =>
									e.source === oldGithubNodeId && e.target !== id && e.sourceHandle === "repository",
							).length > 0;

						if (!isOldNodeShared) {
							// Update old node
							store.updateNodeData<"github">(oldGithubNodeId, {
								repository: {
									id: selectedRepo.id,
									sshURL: selectedRepo.ssh_url,
									fullName: selectedRepo.full_name,
								},
								label: selectedRepo.full_name,
							});
							store.updateNodeData<"app">(id, {
								repository: {
									...data.repository,
									id: newRepoId,
								},
							});
						} else {
							// Create new node because old one is shared
							const newGithubNodeId = uuidv4();
							store.addNode({
								id: newGithubNodeId,
								type: "github",
								data: {
									repository: {
										id: selectedRepo.id,
										sshURL: selectedRepo.ssh_url,
										fullName: selectedRepo.full_name,
									},
									label: selectedRepo.full_name,
									envVars: [],
									ports: [],
								},
							});

							let edges = store.edges;
							// remove old edge
							edges = edges.filter(
								(e) =>
									!(
										e.target === id &&
										e.source === oldGithubNodeId &&
										e.targetHandle === "repository"
									),
							);
							// add new edge
							edges = edges.concat({
								id: uuidv4(),
								source: newGithubNodeId,
								sourceHandle: "repository",
								target: id,
								targetHandle: "repository",
							});
							store.setEdges(edges);
							store.updateNodeData<"app">(id, {
								repository: {
									...data.repository,
									id: newRepoId,
									repoNodeId: newGithubNodeId,
								},
							});
						}
					} else {
						// No old github node, so create a new one
						const newGithubNodeId = uuidv4();
						store.addNode({
							id: newGithubNodeId,
							type: "github",
							data: {
								repository: {
									id: selectedRepo.id,
									sshURL: selectedRepo.ssh_url,
									fullName: selectedRepo.full_name,
								},
								label: selectedRepo.full_name,
								envVars: [],
								ports: [],
							},
						});
						store.setEdges(
							store.edges.concat({
								id: uuidv4(),
								source: newGithubNodeId,
								sourceHandle: "repository",
								target: id,
								targetHandle: "repository",
							}),
						);
						store.updateNodeData<"app">(id, {
							repository: {
								...data.repository,
								id: newRepoId,
								repoNodeId: newGithubNodeId,
							},
						});
					}
				} else if (name === "branch") {
					store.updateNodeData<"app">(id, {
						repository: {
							...data?.repository,
							branch: value.branch,
						},
					});
				} else if (name === "rootDir") {
					store.updateNodeData<"app">(id, {
						repository: {
							...data?.repository,
							rootDir: value.rootDir,
						},
					});
				}
			},
		);
		return () => sub.unsubscribe();
	}, [id, data, sourceForm, store, nodes, repos]);
	const [isExpanded, setIsExpanded] = useState(false);
	// useEffect(() => {
	// 	if (data.repository === undefined) {
	// 		setIsExpanded(true);
	// 	}
	// }, [data.repository, setIsExpanded]);
	console.log(data.repository, isExpanded, repo);
	return (
		<Accordion type="single" collapsible>
			<AccordionItem value="repository" className="border-none">
				<AccordionTrigger onClick={() => setIsExpanded(!isExpanded)}>
					Source {!isExpanded && repo !== undefined && repo.data.repository?.fullName}
				</AccordionTrigger>
				<AccordionContent className="px-1">
					<Form {...sourceForm}>
						<form className="space-y-2">
							<Label>Repository</Label>
							<FormField
								control={sourceForm.control}
								name="id"
								render={({ field }) => (
									<FormItem>
										<Select onValueChange={field.onChange} value={field.value} disabled={disabled}>
											<FormControl>
												<SelectTrigger>
													<SelectValue />
												</SelectTrigger>
											</FormControl>
											<SelectContent>
												{repos.map((r) => (
													<SelectItem
														key={r.id}
														value={r.id.toString()}
													>{`${r.full_name}`}</SelectItem>
												))}
											</SelectContent>
										</Select>
										<FormMessage />
									</FormItem>
								)}
							/>
							<Label>Branch</Label>
							<FormField
								control={sourceForm.control}
								name="branch"
								render={({ field }) => (
									<FormItem>
										<FormControl>
											<Input
												placeholder="master"
												className="lowercase"
												{...field}
												disabled={disabled}
											/>
										</FormControl>
										<FormMessage />
									</FormItem>
								)}
							/>
							<Label>Root Directory</Label>
							<FormField
								control={sourceForm.control}
								name="rootDir"
								render={({ field }) => (
									<FormItem>
										<FormControl>
											<Input placeholder="/" {...field} disabled={disabled} />
										</FormControl>
										<FormMessage />
									</FormItem>
								)}
							/>
						</form>
					</Form>
				</AccordionContent>
			</AccordionItem>
		</Accordion>
	);
}
