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

export function generateDodoConfig(appId: string | undefined, nodes: AppNode[], env: Env): Config | null {
	try {
		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] },
							})),
					);
				});
		};
		const services = nodes
			.filter((n) => n.type === "app")
			.map((n): Service => {
				return {
					nodeId: n.id,
					type: n.data.type,
					name: n.data.label,
					source:
						n.data.repository != undefined
							? {
									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
											: "/",
								}
							: undefined,
					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,
					},
					agent: n.data.agent
						? {
								geminiApiKey: n.data.agent.geminiApiKey,
							}
						: undefined,
				};
			});
		return {
			service: services.filter((s) => !isAgent(s)),
			agent: services.filter(isAgent),
			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 null;
	}
}

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

export function configToGraph(config: Config, networks: Network[], repos: GithubRepository[], current?: Graph): Graph {
	if (current == null) {
		current = { nodes: [], edges: [] };
	}
	const ret: Graph = {
		nodes: [],
		edges: [],
	};
	if (networks.length === 0) {
		return ret;
	}
	const repoNodes = (config.service || [])
		.filter((s) => s.source?.repository != null)
		.map((s): GithubNode | null => {
			const existing = current.nodes.find(
				(n) => n.type === "github" && n.data.repository?.sshURL === s.source!.repository,
			);
			const repo = repos.find((r) => r.ssh_url === s.source!.repository);
			if (repo == null) {
				return null;
			}
			return {
				id: existing != null ? existing.id : uuidv4(),
				type: "github",
				data: {
					label: repo.full_name,
					repository: {
						id: repo.id,
						sshURL: repo.ssh_url,
						fullName: repo.full_name,
					},
					envVars: [],
					ports: [],
				},
				position:
					existing != null
						? existing.position
						: {
								x: 0,
								y: 0,
							},
			};
		})
		.filter((n) => n != null);
	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 || []), ...(config.agent || [])].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: [],
				repository:
					s.source != null
						? {
								id: repoNodes.find((r) => r.data.repository?.sshURL === s.source!.repository)!.data
									.repository!.id,
								repoNodeId: repoNodes.find((r) => r.data.repository?.sshURL === s.source!.repository)!
									.id,
								branch: s.source!.branch,
								rootDir: s.source!.rootDir,
							}
						: undefined,
				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") || "",
				agent: s.agent,
				// 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,
		...repoNodes,
		...(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",
			},
		];
	});
	const repoEdges = (services || []).map((s): Edge => {
		return {
			id: uuidv4(),
			source: s.data.repository!.repoNodeId!,
			sourceHandle: "repository",
			target: s.id,
			targetHandle: "repository",
		};
	});
	ret.edges = [...repoEdges, ...envVarEdges, ...exposureEdges, ...ingressEdges];
	return ret;
}
