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.toUpperCase(),
							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: n.data.dev?.enabled
						? {
								enabled: true,
								username: env.user.username,
								codeServer:
									n.data.dev.expose != null
										? {
												network: networkMap.get(n.data.dev.expose.network)!,
												subdomain: n.data.dev.expose.subdomain,
											}
										: undefined,
								ssh:
									n.data.dev.expose != null
										? {
												network: networkMap.get(n.data.dev.expose.network)!,
												subdomain: n.data.dev.expose.subdomain,
											}
										: undefined,
							}
						: {
								enabled: false,
							},
					...(n.data.agent != null
						? {
								agent: {
									geminiApiKey: n.data.agent.geminiApiKey,
								},
							}
						: {}),
				};
			});
		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;
}
