import { v4 as uuidv4 } from "uuid";
import {
	useStateStore,
	AppNode,
	GatewayHttpsNode,
	ServiceNode,
	nodeLabel,
	useEnv,
	nodeIsConnectable,
} from "@/lib/state";
import { Handle, Position, useNodes } from "@xyflow/react";
import { NodeRect } from "./node-rect";
import { useCallback, useEffect, useMemo } from "react";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, EventType, DeepPartial } from "react-hook-form";
import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
import { Input } from "./ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { Checkbox } from "./ui/checkbox";
import { Label } from "./ui/label";
import { Button } from "./ui/button";
import { XIcon } from "lucide-react";

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

const connectedToSchema = z.object({
	id: z.string(),
	portId: z.string(),
});

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

const authGroupSchema = z.object({
	group: z.string(),
});

const authNoAuthPatternSchema = z.object({
	noAuthPathPattern: z.string(),
});

export function NodeGatewayHttps(node: GatewayHttpsNode) {
	const { id, selected } = node;
	const isConnectableNetwork = useMemo(() => nodeIsConnectable(node, "subdomain"), [node]);
	const isConnectable = useMemo(() => nodeIsConnectable(node, "https"), [node]);
	return (
		<NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
			{nodeLabel(node)}
			<Handle
				type={"source"}
				id="subdomain"
				position={Position.Top}
				isConnectable={isConnectableNetwork}
				isConnectableStart={isConnectableNetwork}
				isConnectableEnd={isConnectableNetwork}
			/>
			<Handle
				type={"target"}
				id="https"
				position={Position.Bottom}
				isConnectable={isConnectable}
				isConnectableStart={isConnectable}
				isConnectableEnd={isConnectable}
			/>
		</NodeRect>
	);
}

export function NodeGatewayHttpsDetails({ id, data }: GatewayHttpsNode) {
	const store = useStateStore();
	const env = useEnv();
	const form = useForm<z.infer<typeof schema>>({
		resolver: zodResolver(schema),
		mode: "onChange",
		defaultValues: {
			network: data.network,
			subdomain: data.subdomain,
		},
	});
	useEffect(() => {
		const sub = form.watch(
			(
				value: DeepPartial<z.infer<typeof schema>>,
				{ name }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
			) => {
				if (name === "network") {
					let edges = store.edges;
					if (data.network !== undefined) {
						edges = edges.filter((e) => {
							if (
								e.source === id &&
								e.sourceHandle === "subdomain" &&
								e.target === data.network &&
								e.targetHandle === "subdomain"
							) {
								return false;
							} else {
								return true;
							}
						});
					}
					if (value.network !== undefined) {
						edges = edges.concat({
							id: uuidv4(),
							source: id,
							sourceHandle: "subdomain",
							target: value.network,
							targetHandle: "subdomain",
						});
					}
					store.setEdges(edges);
					store.updateNodeData<"gateway-https">(id, { network: value.network });
				} else if (name === "subdomain") {
					store.updateNodeData<"gateway-https">(id, { subdomain: value.subdomain });
				}
			},
		);
		return () => sub.unsubscribe();
	}, [id, data, form, store]);
	const connectedToForm = useForm<z.infer<typeof connectedToSchema>>({
		resolver: zodResolver(connectedToSchema),
		mode: "onChange",
		defaultValues: {
			id: data.https?.serviceId,
			portId: data.https?.portId,
		},
	});
	useEffect(() => {
		connectedToForm.reset({
			id: data.https?.serviceId,
			portId: data.https?.portId,
		});
	}, [connectedToForm, data]);
	const nodes = useNodes<AppNode>();
	const selected = useMemo(() => {
		if (data !== undefined && data.https !== undefined) {
			const https = data.https;
			return nodes.find((n) => n.id === https.serviceId)! as ServiceNode;
		}
		return null;
	}, [data, nodes]);
	const selectable = useMemo(() => {
		return nodes.filter((n) => {
			if (n.id === id) {
				return false;
			}
			if (selected !== null && selected.id === id) {
				return true;
			}
			if (n.type !== "app") {
				return false;
			}
			return n.data && n.data.ports && n.data.ports.length > 0;
		});
	}, [id, nodes, selected]);
	useEffect(() => {
		const sub = connectedToForm.watch(
			(
				value: DeepPartial<z.infer<typeof connectedToSchema>>,
				{
					name,
					type,
				}: { name?: keyof z.infer<typeof connectedToSchema> | undefined; type?: EventType | undefined },
			) => {
				if (type !== "change") {
					return;
				}
				switch (name) {
					case "id": {
						if (!value.id) {
							break;
						}
						const current = store.edges.filter((e) => e.target === id);
						const cid = current[0] ? current[0].id : undefined;
						store.replaceEdge(
							{
								source: value.id,
								sourceHandle: "ports",
								target: id,
								targetHandle: "https",
							},
							cid,
						);
						break;
					}
					case "portId":
						store.updateNodeData<"gateway-https">(id, {
							https: {
								serviceId: value.id,
								portId: value.portId,
							},
						});
						break;
				}
			},
		);
		return () => sub.unsubscribe();
	}, [id, connectedToForm, store, selectable]);
	const authEnabledForm = useForm<z.infer<typeof authEnabledSchema>>({
		resolver: zodResolver(authEnabledSchema),
		mode: "onChange",
		defaultValues: {
			enabled: data.auth ? data.auth.enabled : false,
		},
	});
	const authGroupForm = useForm<z.infer<typeof authGroupSchema>>({
		resolver: zodResolver(authGroupSchema),
		mode: "onSubmit",
		defaultValues: {
			group: "",
		},
	});
	const authNoAuthPatternFrom = useForm<z.infer<typeof authNoAuthPatternSchema>>({
		resolver: zodResolver(authNoAuthPatternSchema),
		mode: "onChange",
		defaultValues: {
			noAuthPathPattern: "",
		},
	});
	useEffect(() => {
		const sub = authEnabledForm.watch((value, { name }) => {
			if (name === "enabled") {
				store.updateNodeData<"gateway-https">(id, {
					auth: {
						...data.auth,
						enabled: value.enabled,
					},
				});
			}
		});
		return () => sub.unsubscribe();
	}, [id, data, authEnabledForm, store]);
	const removeGroup = useCallback(
		(group: string) => {
			const groups = data?.auth?.groups || [];
			store.updateNodeData<"gateway-https">(id, {
				auth: {
					...data.auth,
					groups: groups.filter((g) => g !== group),
				},
			});
			return true;
		},
		[id, data, store],
	);
	const onGroupSubmit = useCallback(
		(values: z.infer<typeof authGroupSchema>) => {
			const groups = data.auth?.groups || [];
			groups.push(values.group);
			store.updateNodeData<"gateway-https">(id, {
				auth: {
					...data.auth,
					groups,
				},
			});
			authGroupForm.reset();
		},
		[id, data, store, authGroupForm],
	);
	const removeNoAuthPathPattern = useCallback(
		(path: string) => {
			const noAuthPathPatterns = data?.auth?.noAuthPathPatterns || [];
			store.updateNodeData<"gateway-https">(id, {
				auth: {
					...data.auth,
					noAuthPathPatterns: noAuthPathPatterns.filter((p) => p !== path),
				},
			});
			return true;
		},
		[id, data, store],
	);
	const onNoAuthPathPatternSubmit = useCallback(
		(values: z.infer<typeof authNoAuthPatternSchema>) => {
			const noAuthPathPatterns = data.auth?.noAuthPathPatterns || [];
			noAuthPathPatterns.push(values.noAuthPathPattern);
			store.updateNodeData<"gateway-https">(id, {
				auth: {
					...data.auth,
					noAuthPathPatterns,
				},
			});
			authNoAuthPatternFrom.reset();
		},
		[id, data, store, authNoAuthPatternFrom],
	);
	return (
		<>
			<Form {...form}>
				<form className="space-y-2">
					<FormField
						control={form.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={form.control}
						name="subdomain"
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input placeholder="subdomain" className="border border-black" {...field} />
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			<Form {...connectedToForm}>
				<form className="space-y-2">
					<FormField
						control={connectedToForm.control}
						name="id"
						render={({ field }) => (
							<FormItem>
								<Select onValueChange={field.onChange} defaultValue={field.value}>
									<FormControl>
										<SelectTrigger>
											<SelectValue placeholder="Service" />
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{selectable.map((n) => (
											<SelectItem key={n.id} value={n.id}>
												{nodeLabel(n)}
											</SelectItem>
										))}
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={connectedToForm.control}
						name="portId"
						render={({ field }) => (
							<FormItem>
								<Select onValueChange={field.onChange} defaultValue={field.value}>
									<FormControl>
										<SelectTrigger>
											<SelectValue placeholder="Port" />
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{selected &&
											selected.data.ports.map((p) => (
												<SelectItem key={p.id} value={p.id}>
													{p.name} - {p.value}
												</SelectItem>
											))}
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			Auth
			<Form {...authEnabledForm}>
				<form className="space-y-2">
					<FormField
						control={authEnabledForm.control}
						name="enabled"
						render={({ field }) => (
							<FormItem>
								<div className="flex flex-row gap-1 items-center">
									<Checkbox id="authEnabled" onCheckedChange={field.onChange} checked={field.value} />
									<Label htmlFor="authEnabled">Enabled</Label>
								</div>
								<FormMessage />
							</FormItem>
						)}
					/>
				</form>
			</Form>
			{data && data.auth && data.auth.enabled ? (
				<>
					Authorized Groups
					<ul>
						{(data.auth.groups || []).map((p) => (
							<li key={p} className="flex flex-row gap-1 items-center">
								<Button size={"icon"} variant={"ghost"} onClick={() => removeGroup(p)}>
									<XIcon />
								</Button>
								<div>{p}</div>
							</li>
						))}
					</ul>
					<Form {...authGroupForm}>
						<form className="flex flex-row space-x-1" onSubmit={authGroupForm.handleSubmit(onGroupSubmit)}>
							<FormField
								control={authGroupForm.control}
								name="group"
								render={({ field }) => (
									<FormItem>
										<FormControl>
											<Input placeholder="group" className="border border-black" {...field} />
										</FormControl>
										<FormMessage />
									</FormItem>
								)}
							/>
							<Button type="submit">Add Group</Button>
						</form>
					</Form>
					Auth optional path patterns
					<ul>
						{(data.auth.noAuthPathPatterns || []).map((p) => (
							<li key={p} className="flex flex-row gap-1 items-center">
								<Button size={"icon"} variant={"ghost"} onClick={() => removeNoAuthPathPattern(p)}>
									<XIcon />
								</Button>
								<div>{p}</div>
							</li>
						))}
					</ul>
					<Form {...authNoAuthPatternFrom}>
						<form
							className="flex flex-row space-x-1"
							onSubmit={authNoAuthPatternFrom.handleSubmit(onNoAuthPathPatternSubmit)}
						>
							<FormField
								control={authNoAuthPatternFrom.control}
								name="noAuthPathPattern"
								render={({ field }) => (
									<FormItem>
										<FormControl>
											<Input placeholder="group" className="border border-black" {...field} />
										</FormControl>
										<FormMessage />
									</FormItem>
								)}
							/>
							<Button type="submit">Add</Button>
						</form>
					</Form>
				</>
			) : (
				<></>
			)}
		</>
	);
}
