import {
	AppNode,
	BoundEnvVar,
	Env,
	GatewayHttpsNode,
	GatewayTCPNode,
	MongoDBNode,
	Network,
	NetworkNode,
	Port,
	PostgreSQLNode,
	ServiceNode,
	VolumeNode,
} from "./graph.js";
import { Edge } from "@xyflow/react";
import { v4 as uuidv4 } from "uuid";
import { ConfigWithInput, Ingress, Service, Volume, PostgreSQL, MongoDB, Config, PortDomain } from "./types.js";

export function generateDodoConfig(appId: string | undefined, nodes: AppNode[], env: Env): ConfigWithInput | null {
	try {
		if (appId == null || env.managerAddr == null) {
			return null;
		}
		const networkMap = new Map(env.networks.map((n) => [n.domain, n.name]));
		const ingressNodes = nodes
			.filter((n) => n.type === "gateway-https")
			.filter((n) => n.data.https !== undefined && !n.data.readonly);
		const tcpNodes = nodes
			.filter((n) => n.type === "gateway-tcp")
			.filter((n) => n.data.exposed !== undefined && !n.data.readonly);
		const findExpose = (n: AppNode): PortDomain[] => {
			return n.data.ports
				.map((p) => [n.id, p.id, p.name])
				.flatMap((sp) => {
					return tcpNodes.flatMap((i) =>
						(i.data.exposed || [])
							.filter((t) => t.serviceId === sp[0] && t.portId === sp[1])
							.map(() => ({
								nodeId: i.id,
								network: networkMap.get(i.data.network!)!,
								subdomain: i.data.subdomain!,
								port: { name: sp[2] },
							})),
					);
				});
		};
		return {
			input: {
				appId: appId,
				managerAddr: env.managerAddr,
			},
			service: nodes
				.filter((n) => n.type === "app")
				.map((n): Service => {
					return {
						nodeId: n.id,
						type: n.data.type,
						name: n.data.label,
						source: {
							repository: nodes
								.filter((i) => i.type === "github")
								.find((i) => i.id === n.data.repository?.repoNodeId)!.data.repository!.sshURL,
							branch:
								n.data.repository != undefined && "branch" in n.data.repository
									? n.data.repository.branch
									: "main",
							rootDir:
								n.data.repository != undefined && "rootDir" in n.data.repository
									? n.data.repository.rootDir
									: "/",
						},
						ports: (n.data.ports || [])
							.filter((p) => !n.data.dev?.enabled || (p.value != 22 && p.value != 9090))
							.map((p) => ({
								name: p.name.toLowerCase(),
								value: p.value,
								protocol: "TCP", // TODO(gio)
							})),
						env: (n.data.envVars || [])
							.filter((e) => "name" in e)
							.map((e) => ({
								name: e.name,
								alias: "alias" in e ? e.alias : undefined,
							})),
						ingress: ingressNodes
							.filter((i) => i.data.https!.serviceId === n.id)
							.map(
								(i): Ingress => ({
									nodeId: i.id,
									network: networkMap.get(i.data.network!)!,
									subdomain: i.data.subdomain!,
									port: {
										name: n.data.ports.find((p) => p.id === i.data.https!.portId)!.name,
									},
									auth:
										i.data.auth?.enabled || false
											? {
													enabled: true,
													groups: i.data.auth!.groups,
													noAuthPathPatterns: i.data.auth!.noAuthPathPatterns,
												}
											: {
													enabled: false,
												},
								}),
							),
						expose: findExpose(n),
						preBuildCommands: n.data.preBuildCommands
							? n.data.preBuildCommands.split("\n").map((cmd) => ({ bin: cmd }))
							: [],
						dev: {
							enabled: n.data.dev ? n.data.dev.enabled : false,
							username: n.data.dev && n.data.dev.enabled ? env.user.username : undefined,
							codeServer:
								n.data.dev?.enabled && n.data.dev.expose != null
									? {
											network: networkMap.get(n.data.dev.expose.network)!,
											subdomain: n.data.dev.expose.subdomain,
										}
									: undefined,
							ssh:
								n.data.dev?.enabled && n.data.dev.expose != null
									? {
											network: networkMap.get(n.data.dev.expose.network)!,
											subdomain: n.data.dev.expose.subdomain,
										}
									: undefined,
						},
					};
				}),
			volume: nodes
				.filter((n) => n.type === "volume")
				.map(
					(n): Volume => ({
						nodeId: n.id,
						name: n.data.label,
						accessMode: n.data.type,
						size: n.data.size,
					}),
				),
			postgresql: nodes
				.filter((n) => n.type === "postgresql")
				.map(
					(n): PostgreSQL => ({
						nodeId: n.id,
						name: n.data.label,
						size: "1Gi", // TODO(gio)
						expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
					}),
				),
			mongodb: nodes
				.filter((n) => n.type === "mongodb")
				.map(
					(n): MongoDB => ({
						nodeId: n.id,
						name: n.data.label,
						size: "1Gi", // TODO(gio)
						expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
					}),
				),
		};
	} catch (e) {
		console.log(e);
		return { input: { appId: "qweqwe", managerAddr: "" } };
	}
}

export type Graph = {
	nodes: AppNode[];
	edges: Edge[];
};

export function configToGraph(config: Config, networks: Network[], current?: Graph): Graph {
	if (current == null) {
		current = { nodes: [], edges: [] };
	}
	const ret: Graph = {
		nodes: [],
		edges: [],
	};
	if (networks.length === 0) {
		return ret;
	}
	const networkNodes = networks.map((n): NetworkNode => {
		let existing: NetworkNode | undefined = undefined;
		existing = current.nodes
			.filter((i): i is NetworkNode => i.type === "network")
			.find((i) => i.data.domain === n.domain);
		return {
			id: n.domain,
			type: "network",
			data: {
				label: n.name,
				domain: n.domain,
				envVars: [],
				ports: [],
			},
			position: existing != null ? existing.position : { x: 0, y: 0 },
		};
	});
	const services = config.service?.map((s): ServiceNode => {
		let existing: ServiceNode | null = null;
		if (s.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === s.nodeId) as ServiceNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "app",
			data: {
				label: s.name,
				type: s.type,
				env: [],
				ports: (s.ports || []).map(
					(p): Port => ({
						id: uuidv4(),
						name: p.name,
						value: p.value,
					}),
				),
				envVars: (s.env || []).map((e): BoundEnvVar => {
					if (e.alias != null) {
						return {
							id: uuidv4(),
							name: e.name,
							source: null,
							alias: e.alias,
							isEditting: false,
						};
					} else {
						return {
							id: uuidv4(),
							name: e.name,
							source: null,
							isEditting: false,
						};
					}
				}),
				volume: s.volume || [],
				preBuildCommands: s.preBuildCommands?.map((p) => p.bin).join("\n") || "",
				// TODO(gio): dev
				isChoosingPortToConnect: false,
			},
			// TODO(gio): generate position
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	const serviceGateways = config.service?.flatMap((s, index): GatewayHttpsNode[] => {
		return (s.ingress || []).map((i): GatewayHttpsNode => {
			let existing: GatewayHttpsNode | null = null;
			if (i.nodeId !== undefined) {
				existing = current.nodes.find((n) => n.id === i.nodeId) as GatewayHttpsNode;
			}
			console.log("!!!", i.network, networks);
			return {
				id: existing != null ? existing.id : uuidv4(),
				type: "gateway-https",
				data: {
					label: i.subdomain,
					envVars: [],
					ports: [],
					network: networks.find((n) => n.name.toLowerCase() === i.network.toLowerCase())!.domain,
					subdomain: i.subdomain,
					https: {
						serviceId: services![index]!.id,
						portId: services![index]!.data.ports.find((p) => {
							const port = i.port;
							if ("name" in port) {
								return p.name === port.name;
							} else {
								return `${p.value}` === port.value;
							}
						})!.id,
					},
					auth: i.auth.enabled
						? {
								enabled: true,
								groups: i.auth.groups || [],
								noAuthPathPatterns: i.auth.noAuthPathPatterns || [],
							}
						: {
								enabled: false,
								groups: [],
								noAuthPathPatterns: [],
							},
				},
				position: {
					x: 0,
					y: 0,
				},
			};
		});
	});
	const exposures = new Map<string, GatewayTCPNode>();
	config.service
		?.flatMap((s, index): GatewayTCPNode[] => {
			return (s.expose || []).map((e): GatewayTCPNode => {
				let existing: GatewayTCPNode | null = null;
				if (e.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === e.nodeId) as GatewayTCPNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-tcp",
					data: {
						label: e.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === e.network.toLowerCase())!.domain,
						subdomain: e.subdomain,
						exposed: [
							{
								serviceId: services![index]!.id,
								portId: services![index]!.data.ports.find((p) => {
									const port = e.port;
									if ("name" in port) {
										return p.name === port.name;
									} else {
										return p.value === port.value;
									}
								})!.id,
							},
						],
					},
					position: existing != null ? existing.position : { x: 0, y: 0 },
				};
			});
		})
		.forEach((n) => {
			const key = `${n.data.network}-${n.data.subdomain}`;
			if (!exposures.has(key)) {
				exposures.set(key, n);
			} else {
				exposures.get(key)!.data.exposed.push(...n.data.exposed);
			}
		});
	const volumes = config.volume?.map((v): VolumeNode => {
		let existing: VolumeNode | null = null;
		if (v.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === v.nodeId) as VolumeNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "volume",
			data: {
				label: v.name,
				type: v.accessMode,
				size: v.size,
				attachedTo: [],
				envVars: [],
				ports: [],
			},
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	const postgresql = config.postgresql?.map((p): PostgreSQLNode => {
		let existing: PostgreSQLNode | null = null;
		if (p.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === p.nodeId) as PostgreSQLNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "postgresql",
			data: {
				label: p.name,
				volumeId: "", // TODO(gio): volume
				envVars: [],
				ports: [
					{
						id: "connection",
						name: "connection",
						value: 5432,
					},
				],
			},
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	config.postgresql
		?.flatMap((p, index): GatewayTCPNode[] => {
			return (p.expose || []).map((e): GatewayTCPNode => {
				let existing: GatewayTCPNode | null = null;
				if (e.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === e.nodeId) as GatewayTCPNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-tcp",
					data: {
						label: e.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === e.network.toLowerCase())!.domain,
						subdomain: e.subdomain,
						exposed: [
							{
								serviceId: postgresql![index]!.id,
								portId: "connection",
							},
						],
					},
					position: existing != null ? existing.position : { x: 0, y: 0 },
				};
			});
		})
		.forEach((n) => {
			const key = `${n.data.network}-${n.data.subdomain}`;
			if (!exposures.has(key)) {
				exposures.set(key, n);
			} else {
				exposures.get(key)!.data.exposed.push(...n.data.exposed);
			}
		});
	const mongodb = config.mongodb?.map((m): MongoDBNode => {
		let existing: MongoDBNode | null = null;
		if (m.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === m.nodeId) as MongoDBNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "mongodb",
			data: {
				label: m.name,
				volumeId: "", // TODO(gio): volume
				envVars: [],
				ports: [
					{
						id: "connection",
						name: "connection",
						value: 27017,
					},
				],
			},
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	config.mongodb
		?.flatMap((p, index): GatewayTCPNode[] => {
			return (p.expose || []).map((e): GatewayTCPNode => {
				let existing: GatewayTCPNode | null = null;
				if (e.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === e.nodeId) as GatewayTCPNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-tcp",
					data: {
						label: e.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === e.network.toLowerCase())!.domain,
						subdomain: e.subdomain,
						exposed: [
							{
								serviceId: mongodb![index]!.id,
								portId: "connection",
							},
						],
					},
					position: existing != null ? existing.position : { x: 0, y: 0 },
				};
			});
		})
		.forEach((n) => {
			const key = `${n.data.network}-${n.data.subdomain}`;
			if (!exposures.has(key)) {
				exposures.set(key, n);
			} else {
				exposures.get(key)!.data.exposed.push(...n.data.exposed);
			}
		});
	ret.nodes = [
		...networkNodes,
		...ret.nodes,
		...(services || []),
		...(serviceGateways || []),
		...(volumes || []),
		...(postgresql || []),
		...(mongodb || []),
		...(exposures.values() || []),
	];
	services?.forEach((s) => {
		s.data.envVars.forEach((e) => {
			if (!("name" in e)) {
				return;
			}
			if (!e.name.startsWith("DODO_")) {
				return;
			}
			let r: {
				type: string;
				name: string;
			} | null = null;
			if (e.name.startsWith("DODO_PORT_")) {
				return;
			} else if (e.name.startsWith("DODO_POSTGRESQL_")) {
				r = {
					type: "postgresql",
					name: e.name.replace("DODO_POSTGRESQL_", "").replace("_URL", "").toLowerCase(),
				};
			} else if (e.name.startsWith("DODO_MONGODB_")) {
				r = {
					type: "mongodb",
					name: e.name.replace("DODO_MONGODB_", "").replace("_URL", "").toLowerCase(),
				};
			} else if (e.name.startsWith("DODO_VOLUME_")) {
				r = {
					type: "volume",
					name: e.name.replace("DODO_VOLUME_", "").toLowerCase(),
				};
			}
			if (r != null) {
				e.source = ret.nodes.find((n) => n.type === r.type && n.data.label.toLowerCase() === r.name)!.id;
			}
		});
	});
	const envVarEdges = [...(services || [])].flatMap((n): Edge[] => {
		return n.data.envVars.flatMap((e): Edge[] => {
			if (e.source == null) {
				return [];
			}
			const sn = ret.nodes.find((n) => n.id === e.source!)!;
			const sourceHandle = sn.type === "app" ? "ports" : sn.type === "volume" ? "volume" : "env_var";
			return [
				{
					id: uuidv4(),
					source: e.source!,
					sourceHandle: sourceHandle,
					target: n.id,
					targetHandle: "env_var",
				},
			];
		});
	});
	const exposureEdges = [...exposures.values()].flatMap((n): Edge[] => {
		return n.data.exposed.flatMap((e): Edge[] => {
			return [
				{
					id: uuidv4(),
					source: e.serviceId,
					sourceHandle: ret.nodes.find((n) => n.id === e.serviceId)!.type === "app" ? "ports" : "env_var",
					target: n.id,
					targetHandle: "tcp",
				},
				{
					id: uuidv4(),
					source: n.id,
					sourceHandle: "subdomain",
					target: n.data.network!,
					targetHandle: "subdomain",
				},
			];
		});
	});
	const ingressEdges = [...(serviceGateways || [])].flatMap((n): Edge[] => {
		return [
			{
				id: uuidv4(),
				source: n.data.https!.serviceId,
				sourceHandle: "ports",
				target: n.id,
				targetHandle: "https",
			},
			{
				id: uuidv4(),
				source: n.id,
				sourceHandle: "subdomain",
				target: n.data.network!,
				targetHandle: "subdomain",
			},
		];
	});
	ret.edges = [...envVarEdges, ...exposureEdges, ...ingressEdges];
	return ret;
}
