import { v4 as uuidv4 } from "uuid";
import { NodeRect } from "./node-rect";
import {
	useStateStore,
	ServiceNode,
	ServiceTypes,
	nodeLabel,
	BoundEnvVar,
	AppState,
	nodeIsConnectable,
	GatewayTCPNode,
	GatewayHttpsNode,
	AppNode,
	GithubNode,
	useEnv,
} from "@/lib/state";
import { KeyboardEvent, FocusEvent, useCallback, useEffect, useMemo, useState } from "react";
import { z } from "zod";
import { DeepPartial, EventType, useForm, ControllerRenderProps, FieldPath } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem, FormMessage } 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 { PencilIcon, XIcon } from "lucide-react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
import { Textarea } from "./ui/textarea";
import { Input } from "./ui/input";
import { Checkbox } from "./ui/checkbox";
import { Label } from "./ui/label";

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} type={node.type} 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 portSchema = z.object({
	name: z.string().min(1, "required"),
	value: z.coerce.number().gt(0, "must be positive").lte(65535, "must be less than 65535"),
});

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

export function NodeAppDetails({ id, data }: ServiceNode) {
	const store = useStateStore();
	const nodes = useNodes<AppNode>();
	const env = useEnv();
	const form = useForm<z.infer<typeof schema>>({
		resolver: zodResolver(schema),
		mode: "onChange",
		defaultValues: {
			name: data.label,
			type: data.type,
		},
	});
	const portForm = useForm<z.infer<typeof portSchema>>({
		resolver: zodResolver(portSchema),
		mode: "onSubmit",
		defaultValues: {
			name: "",
			value: 0,
		},
	});
	const onSubmit = useCallback(
		(values: z.infer<typeof portSchema>) => {
			const portId = uuidv4();
			store.updateNodeData<"app">(id, {
				ports: (data.ports || []).concat({
					id: portId,
					name: values.name.toLowerCase(),
					value: values.value,
				}),
				envVars: (data.envVars || []).concat({
					id: uuidv4(),
					source: null,
					portId,
					name: `DODO_PORT_${values.name.toUpperCase()}`,
				}),
			});
			portForm.reset();
		},
		[id, data, portForm, store],
	);
	useEffect(() => {
		const sub = form.watch(
			(
				value: DeepPartial<z.infer<typeof schema>>,
				{ name, type }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
			) => {
				console.log({ name, type });
				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 focus = useCallback(
		(field: ControllerRenderProps<z.infer<typeof schema>, FieldPath<z.infer<typeof schema>>>, name: string) => {
			return (e: HTMLElement | null) => {
				field.ref(e);
				if (e != null && name === data.activeField) {
					console.log(e);
					e.focus();
					store.updateNodeData(id, {
						activeField: undefined,
					});
				}
			};
		},
		[id, data, 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 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(),
						};
					}
					console.log(o);
					if ("alias" in o) {
						const { alias: _, ...rest } = o;
						console.log(rest);
						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],
	);
	const removePort = useCallback(
		(portId: string) => {
			// TODO(gio): this is ugly
			const tcpRemoved = new Set<string>();
			console.log(store.edges);
			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],
	);
	const setPreBuildCommands = useCallback(
		(e: React.ChangeEvent<HTMLTextAreaElement>) => {
			store.updateNodeData<"app">(id, {
				preBuildCommands: e.currentTarget.value,
			});
		},
		[id, store],
	);

	const sourceForm = useForm<z.infer<typeof sourceSchema>>({
		resolver: zodResolver(sourceSchema),
		mode: "onChange",
		defaultValues: {
			id: data?.repository?.id,
			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 },
			) => {
				console.log(value);
				if (name === "id") {
					let edges = store.edges;
					if (data?.repository?.id !== undefined) {
						edges = edges.filter((e) => {
							if (e.target === id && e.targetHandle === "repository" && e.source === data.repository.id) {
								return false;
							} else {
								return true;
							}
						});
					}
					if (value.id !== undefined) {
						edges = edges.concat({
							id: uuidv4(),
							source: value.id,
							sourceHandle: "repository",
							target: id,
							targetHandle: "repository",
						});
					}
					store.setEdges(edges);
					store.updateNodeData<"app">(id, {
						repository: {
							id: value.id,
						},
					});
				} 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]);
	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 {...exposeForm}>
				<form className="space-y-2">
					<FormField
						control={form.control}
						name="name"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input
										placeholder="name"
										className="lowercase"
										{...field}
										ref={focus(field, "name")}
									/>
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name="type"
						render={({ field }) => (
							<FormItem>
								<Select onValueChange={field.onChange} defaultValue={field.value} {...typeProps}>
									<FormControl>
										<SelectTrigger>
											<SelectValue placeholder="Runtime" />
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{ServiceTypes.map((t) => (
											<SelectItem key={t} value={t}>
												{t}
											</SelectItem>
										))}
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			Source
			<Form {...sourceForm}>
				<form className="space-y-2">
					<FormField
						control={sourceForm.control}
						name="id"
						render={({ field }) => (
							<FormItem>
								<Select onValueChange={field.onChange} defaultValue={field.value}>
									<FormControl>
										<SelectTrigger>
											<SelectValue placeholder="Repository" />
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{(
											nodes.filter(
												(n) => n.type === "github" && n.data.repository?.id !== undefined,
											) as GithubNode[]
										).map((n) => (
											<SelectItem
												key={n.id}
												value={n.id}
											>{`${n.data.repository?.fullName}`}</SelectItem>
										))}
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={sourceForm.control}
						name="branch"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="master" className="lowercase" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={sourceForm.control}
						name="rootDir"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="/" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			Ports
			<ul>
				{data &&
					data.ports &&
					data.ports.map((p) => (
						<li key={p.id} className="flex flex-row items-center gap-1">
							<Button size={"icon"} variant={"ghost"} onClick={() => removePort(p.id)}>
								<XIcon />
							</Button>
							<div>
								{p.name} - {p.value}
							</div>
						</li>
					))}
			</ul>
			<Form {...portForm}>
				<form className="flex flex-row space-x-1" onSubmit={portForm.handleSubmit(onSubmit)}>
					<FormField
						control={portForm.control}
						name="name"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="name" className="lowercase" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={portForm.control}
						name="value"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="value" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<Button type="submit">Add Port</Button>
				</form>
			</Form>
			Env Vars
			<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}
										/>
									</li>
								);
							}
							return (
								<li key={v.id} onClick={editAlias(v)}>
									<TooltipProvider>
										<Tooltip>
											<TooltipTrigger>
												<div className="flex flex-row items-center gap-1">
													<Button size={"icon"} variant={"ghost"}>
														<PencilIcon />
													</Button>
													<div>{value}</div>
												</div>
											</TooltipTrigger>
											<TooltipContent>{v.name}</TooltipContent>
										</Tooltip>
									</TooltipProvider>
								</li>
							);
						}
					})}
			</ul>
			Pre-Build Commands
			<Textarea
				placeholder="new line separated list of commands to run before running the service"
				value={data.preBuildCommands}
				onChange={setPreBuildCommands}
			/>
			Dev
			<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">
									<Checkbox id="devEnabled" onCheckedChange={field.onChange} checked={field.value} />
									<Label htmlFor="devEnabled">Enabled</Label>
								</div>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			{data.dev && data.dev.enabled && (
				<Form {...exposeForm}>
					<form className="space-y-2">
						<FormField
							control={exposeForm.control}
							name="network"
							render={({ field }) => (
								<FormItem>
									<Select onValueChange={field.onChange} defaultValue={field.value}>
										<FormControl>
											<SelectTrigger>
												<SelectValue placeholder="Network" />
											</SelectTrigger>
										</FormControl>
										<SelectContent>
											{env.networks.map((n) => (
												<SelectItem
													key={n.name}
													value={n.domain}
												>{`${n.name} - ${n.domain}`}</SelectItem>
											))}
										</SelectContent>
									</Select>
									<FormMessage />
								</FormItem>
							)}
						/>
						<FormField
							control={exposeForm.control}
							name="subdomain"
							render={({ field }) => (
								<FormItem>
									<FormControl>
										<Input placeholder="subdomain" {...field} />
									</FormControl>
									<FormMessage />
								</FormItem>
							)}
						/>
					</form>
				</Form>
			)}
		</>
	);
}
