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 } from "config";
import { KeyboardEvent, FocusEvent, useCallback, useEffect, useMemo, useState } 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";

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),
});

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

const devSchema = z.object({
	enabled: z.boolean(),
});

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(),
});

export function NodeAppDetails({ node, disabled, showName = true, isOverview = false }: NodeDetailsProps<ServiceNode>) {
	const { data } = node;
	return (
		<>
			{showName ? <Name node={node} disabled={disabled} /> : null}
			<Tabs defaultValue="runtime">
				<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} />
				</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 }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const store = useStateStore();
	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()}`,
			}),
		});
		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 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">
								<Button
									variant="destructive"
									className="w-full"
									onClick={() => removePort(p.id)}
									disabled={disabled}
								>
									Remove
								</Button>
							</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 editAlias = useCallback(
		(e: BoundEnvVar) => {
			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],
	);
	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) {
						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") {
					event.preventDefault();
					saveAlias(e, event.currentTarget.value, store);
				}
			};
		},
		[store, saveAlias],
	);
	const saveAliasOnBlur = useCallback(
		(e: BoundEnvVar) => {
			return (event: FocusEvent<HTMLInputElement>) => {
				saveAlias(e, event.currentTarget.value, store);
			};
		},
		[store, saveAlias],
	);
	return (
		<ul>
			{data &&
				data.envVars &&
				data.envVars.map((v) => {
					if ("name" in v) {
						const value = "alias" in v ? v.alias : v.name;
						if (v.isEditting) {
							return (
								<li key={v.id}>
									<Input
										type="text"
										className="uppercase"
										defaultValue={value}
										onKeyUp={saveAliasOnEnter(v)}
										onBlur={saveAliasOnBlur(v)}
										autoFocus={true}
										disabled={disabled}
									/>
								</li>
							);
						}
						return (
							<li key={v.id} onClick={editAlias(v)}>
								<TooltipProvider>
									<Tooltip>
										<TooltipTrigger className="w-full">
											<div className="w-full flex flex-row items-center gap-1 cursor-text">
												<Pencil className="w-4 h-4" />
												<div className="uppercase">{value}</div>
											</div>
										</TooltipTrigger>
										<TooltipContent>{v.name}</TooltipContent>
									</Tooltip>
								</TooltipProvider>
							</li>
						);
					}
				})}
		</ul>
	);
}

function Dev({ node, disabled }: { node: ServiceNode; disabled?: boolean }): React.ReactNode {
	const { id, data } = node;
	const env = useEnv();
	const store = useStateStore();
	const devForm = useForm<z.infer<typeof devSchema>>({
		resolver: zodResolver(devSchema),
		mode: "onChange",
		defaultValues: {
			enabled: data.dev ? data.dev.enabled : false,
		},
	});
	useEffect(() => {
		const sub = devForm.watch((value, { name }) => {
			if (name === "enabled") {
				if (value.enabled) {
					const csGateway: Omit<GatewayHttpsNode, "position"> = {
						id: uuidv4(),
						type: "gateway-https",
						data: {
							readonly: true,
							https: {
								serviceId: id,
								portId: `${id}-code-server`,
							},
							network: data.dev?.expose?.network,
							subdomain: data.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: data.dev?.expose?.network,
							subdomain: data.dev?.expose?.subdomain,
							label: "",
							envVars: [],
							ports: [],
						},
					};
					store.addNode(csGateway);
					store.addNode(sshGateway);
					store.updateNodeData<"app">(id, {
						dev: {
							enabled: true,
							expose: data.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 (data.dev?.expose?.network !== undefined) {
						edges = edges.concat([
							{
								id: uuidv4(),
								source: csGateway.id,
								sourceHandle: "subdomain",
								target: data.dev.expose.network,
								targetHandle: "subdomain",
							},
							{
								id: uuidv4(),
								source: sshGateway.id,
								sourceHandle: "subdomain",
								target: data.dev.expose.network,
								targetHandle: "subdomain",
							},
						]);
					}
					store.setEdges(edges);
				} else {
					const { dev } = data;
					if (dev?.enabled) {
						store.setNodes(
							store.nodes.filter((n) => n.id !== dev.codeServerNodeId && n.id !== dev.sshNodeId),
						);
						store.setEdges(
							store.edges.filter((e) => e.target !== dev.codeServerNodeId && e.target !== dev.sshNodeId),
						);
					}
					store.updateNodeData<"app">(id, {
						dev: {
							enabled: false,
							expose: dev?.expose,
						},
						ports: (data.ports || []).filter((p) => p.name !== "code-server" && p.name !== "ssh"),
					});
				}
			}
		});
		return () => sub.unsubscribe();
	}, [id, data, devForm, store]);
	const exposeForm = useForm<z.infer<typeof exposeSchema>>({
		resolver: zodResolver(exposeSchema),
		mode: "onChange",
		defaultValues: {
			network: data.dev?.expose?.network,
			subdomain: data.dev?.expose?.subdomain,
		},
	});
	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) {
					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, exposeForm, 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">Dev VM</Label>
								</div>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			{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>
			)}
		</>
	);
}

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>
	);
}
