import { PrismaClient } from "@prisma/client";
import express from "express";
import fs from "node:fs";
import { env } from "node:process";
import axios from "axios";
import { GithubClient } from "./github.js";
import { AppManager } from "./app_manager.js";
import { z } from "zod";
import { ProjectMonitor, WorkerSchema, LogItem } from "./project_monitor.js";
import tmp from "tmp";
import { NodeJSAnalyzer } from "./lib/nodejs.js";
import shell from "shelljs";
import { RealFileSystem } from "./lib/fs.js";
import path from "node:path";
import {
	Env,
	generateDodoConfig,
	ConfigSchema,
	Config,
	ConfigWithInput,
	configToGraph,
	Network,
	GithubRepository,
	Graph,
} from "config";
import { Instant, DateTimeFormatter, ZoneId } from "@js-joda/core";
import LogStore from "./log.js";
import { GraphOrConfigSchema, GraphSchema, GraphConfigOrDraft } from "config/dist/graph.js";

async function generateKey(root: string): Promise<[string, string]> {
	const privKeyPath = path.join(root, "key");
	const pubKeyPath = path.join(root, "key.pub");
	if (shell.exec(`ssh-keygen -t ed25519 -f ${privKeyPath} -N ""`).code !== 0) {
		throw new Error("Failed to generate SSH key pair");
	}
	const publicKey = await fs.promises.readFile(pubKeyPath, "utf8");
	const privateKey = await fs.promises.readFile(privKeyPath, "utf8");
	return [publicKey, privateKey];
}

const db = new PrismaClient();
const logStore = new LogStore(db);
const appManager = new AppManager();

const projectMonitors = new Map<number, ProjectMonitor>();

function parseGraph(data: string | null | undefined) {
	if (data == null) {
		return null;
	}
	return GraphSchema.safeParse(JSON.parse(data));
}

const handleProjectCreate: express.Handler = async (req, resp) => {
	try {
		const tmpDir = tmp.dirSync().name;
		const [publicKey, privateKey] = await generateKey(tmpDir);
		const { id } = await db.project.create({
			data: {
				userId: resp.locals.userId,
				name: req.body.name,
				deployKey: privateKey,
				deployKeyPublic: publicKey,
			},
		});
		resp.status(200);
		resp.header("Content-Type", "application/json");
		resp.write(
			JSON.stringify({
				id: id.toString(),
			}),
		);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleProjectAll: express.Handler = async (req, resp) => {
	try {
		const r = await db.project.findMany({
			where: {
				userId: resp.locals.userId,
			},
		});
		resp.status(200);
		resp.header("Content-Type", "application/json");
		resp.write(
			JSON.stringify(
				r.map((p) => ({
					id: p.id.toString(),
					name: p.name,
				})),
			),
		);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

async function getState(projectId: number, userId: string, state: "deploy" | "draft"): Promise<Graph | null> {
	const r = await db.project.findUnique({
		where: {
			id: projectId,
			userId: userId,
		},
		select: {
			state: true,
			draft: true,
		},
	});
	if (r == null) {
		return null;
	}
	let currentState: Graph | null = null;
	if (state === "deploy") {
		if (r.state != null) {
			currentState = parseGraph(r.state)!.data!;
		}
	} else {
		if (r.draft == null) {
			if (r.state == null) {
				currentState = {
					nodes: [],
					edges: [],
					viewport: { x: 0, y: 0, zoom: 1 },
				};
			} else {
				currentState = parseGraph(r.state)!.data!;
			}
		} else {
			currentState = parseGraph(r.draft)!.data!;
		}
	}
	return currentState;
}

function handleSavedGet(state: "deploy" | "draft"): express.Handler {
	return async (req, resp) => {
		try {
			const projectId = Number(req.params["projectId"]);
			const graph = await getState(projectId, resp.locals.userId, state);
			if (graph == null) {
				resp.status(404);
				return;
			}
			const env = await getEnv(projectId, resp.locals.userId, resp.locals.username);
			const config = generateDodoConfig(projectId.toString(), graph.nodes, env);
			resp.status(200);
			resp.header("content-type", "application/json");
			resp.write(
				JSON.stringify({
					state: graph,
					config,
				}),
			);
		} catch (e) {
			console.log(e);
			resp.status(500);
		} finally {
			resp.end();
		}
	};
}

const handleProjectDelete: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const p = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				instanceId: true,
				githubToken: true,
				deployKeyPublic: true,
				state: true,
				draft: true,
			},
		});
		if (p === null) {
			resp.status(404);
			return;
		}
		if (p.githubToken && p.deployKeyPublic) {
			const allRepos = [...new Set([...extractGithubRepos(p.state), ...extractGithubRepos(p.draft)])];
			if (allRepos.length > 0) {
				const diff: RepoDiff = { toDelete: allRepos, toAdd: [] };
				const github = new GithubClient(p.githubToken);
				await manageGithubRepos(github, diff, p.deployKeyPublic, env.PUBLIC_ADDR);
				console.log(
					`Attempted to remove deploy keys for project ${projectId} from associated GitHub repositories.`,
				);
			}
		}
		if (p.instanceId !== null) {
			if (!(await appManager.removeInstance(p.instanceId))) {
				resp.status(500);
				resp.write(JSON.stringify({ error: "Failed to remove deployment from cluster" }));
				return;
			}
		}
		await db.project.delete({
			where: {
				id: projectId,
			},
		});
		resp.status(200);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

function extractGithubRepos(serializedState: string | null | undefined): string[] {
	if (!serializedState) {
		return [];
	}
	try {
		const stateObj = JSON.parse(serializedState);
		const githubNodes = stateObj.nodes.filter(
			// eslint-disable-next-line @typescript-eslint/no-explicit-any
			(n: any) => n.type === "github" && n.data?.repository?.id,
		);
		// eslint-disable-next-line @typescript-eslint/no-explicit-any
		return githubNodes.map((n: any) => n.data.repository.sshURL);
	} catch (error) {
		console.error("Failed to parse state or extract GitHub repos:", error);
		return [];
	}
}

type RepoDiff = {
	toAdd?: string[];
	toDelete?: string[];
};

function calculateRepoDiff(oldRepos: string[], newRepos: string[]): RepoDiff {
	const toAdd = newRepos.filter((repo) => !oldRepos.includes(repo));
	const toDelete = oldRepos.filter((repo) => !newRepos.includes(repo));
	return { toAdd, toDelete };
}

async function manageGithubRepos(
	github: GithubClient,
	diff: RepoDiff,
	deployKey: string,
	publicAddr?: string,
): Promise<void> {
	for (const repoUrl of diff.toDelete ?? []) {
		try {
			await github.removeDeployKey(repoUrl, deployKey);
			console.log(`Removed deploy key from repository ${repoUrl}`);
			if (publicAddr) {
				const webhookCallbackUrl = `${publicAddr}/api/webhook/github/push`;
				await github.removePushWebhook(repoUrl, webhookCallbackUrl);
				console.log(`Removed push webhook from repository ${repoUrl}`);
			}
		} catch (error) {
			console.error(`Failed to remove deploy key from repository ${repoUrl}:`, error);
		}
	}
	for (const repoUrl of diff.toAdd ?? []) {
		try {
			await github.addDeployKey(repoUrl, deployKey);
			console.log(`Added deploy key to repository ${repoUrl}`);
			if (publicAddr) {
				const webhookCallbackUrl = `${publicAddr}/api/webhook/github/push`;
				await github.addPushWebhook(repoUrl, webhookCallbackUrl);
				console.log(`Added push webhook to repository ${repoUrl}`);
			}
		} catch (error) {
			console.error(`Failed to add deploy key from repository ${repoUrl}:`, error);
		}
	}
}

const handleDeploy: express.Handler = async (req, resp) => {
	try {
		const reqParsed = GraphConfigOrDraft.safeParse(req.body);
		if (!reqParsed.success) {
			resp.status(400);
			resp.write(JSON.stringify({ error: "Invalid request body", issues: reqParsed.error.format() }));
			return;
		}
		const projectId = Number(req.params["projectId"]);
		const p = await db.project.findUnique({
			where: {
				id: projectId,
				// userId: resp.locals.userId, TODO(gio): validate
			},
			select: {
				instanceId: true,
				githubToken: true,
				deployKey: true,
				deployKeyPublic: true,
				state: true,
				draft: true,
				geminiApiKey: true,
				anthropicApiKey: true,
			},
		});
		if (p === null) {
			resp.status(404);
			return;
		}
		let graph: Graph | null = null;
		let config: Config | null = null;
		if (reqParsed.data.type === "config") {
			const parsed = ConfigSchema.safeParse(reqParsed.data.config);
			if (parsed.success) {
				config = parsed.data;
			} else {
				resp.status(400);
				resp.write(JSON.stringify({ error: "Invalid configuration", issues: parsed.error.format() }));
				return;
			}
			let oldGraph: Graph | undefined = undefined;
			if (p.state != null) {
				oldGraph = parseGraph(p.state)!.data;
			} else if (p.draft != null) {
				oldGraph = parseGraph(p.draft)!.data;
			}
			let repos: GithubRepository[] = [];
			if (p.githubToken) {
				const github = new GithubClient(p.githubToken);
				repos = await github.getRepositories();
			}
			graph = configToGraph(config, getNetworks(resp.locals.username), repos, oldGraph);
		} else if (reqParsed.data.type === "graph") {
			graph = reqParsed.data.graph;
			const env = await getEnv(projectId, resp.locals.userId, resp.locals.username);
			config = generateDodoConfig(projectId.toString(), graph?.nodes || [], env);
		} else if (reqParsed.data.type === "draft") {
			if (p.draft == null) {
				resp.status(400);
				resp.write(JSON.stringify({ error: "Invalid request body" }));
				return;
			}
			graph = parseGraph(p.draft)!.data!;
			const env = await getEnv(projectId, resp.locals.userId, resp.locals.username);
			config = generateDodoConfig(projectId.toString(), graph?.nodes || [], env);
		}
		if (config == null || graph == null) {
			resp.status(500);
			resp.write(JSON.stringify({ error: "Failed to generate configuration" }));
			return;
		}
		await db.project.update({
			where: {
				id: projectId,
			},
			data: {
				draft: JSON.stringify(graph),
			},
		});
		let deployKey: string | null = p.deployKey;
		let deployKeyPublic: string | null = p.deployKeyPublic;
		if (deployKeyPublic == null) {
			[deployKeyPublic, deployKey] = await generateKey(tmp.dirSync().name);
			await db.project.update({
				where: { id: projectId },
				data: { deployKeyPublic, deployKey },
			});
		}
		let diff: RepoDiff | null = null;
		const cfg: ConfigWithInput = {
			...config,
			input: {
				appId: projectId.toString(),
				managerAddr: env.INTERNAL_API_ADDR!,
				key: {
					public: deployKeyPublic!,
					private: deployKey!,
				},
				geminiApiKey: p.geminiApiKey ?? undefined,
				anthropicApiKey: p.anthropicApiKey ?? undefined,
			},
		};
		try {
			if (p.instanceId == null) {
				const deployResponse = await appManager.deploy(cfg);
				await db.project.update({
					where: {
						id: projectId,
					},
					data: {
						state: JSON.stringify(graph),
						draft: null,
						instanceId: deployResponse.id,
						access: JSON.stringify(deployResponse.access),
					},
				});
				diff = { toAdd: extractGithubRepos(JSON.stringify(graph)) };
			} else {
				const deployResponse = await appManager.update(p.instanceId, cfg);
				diff = calculateRepoDiff(extractGithubRepos(p.state), extractGithubRepos(JSON.stringify(graph)));
				await db.project.update({
					where: {
						id: projectId,
					},
					data: {
						state: JSON.stringify(graph),
						draft: null,
						access: JSON.stringify(deployResponse.access),
					},
				});
			}
			if (diff && p.githubToken && deployKey) {
				const github = new GithubClient(p.githubToken);
				await manageGithubRepos(github, diff, deployKeyPublic!, env.PUBLIC_ADDR);
			}
			resp.status(200);
		} catch (error) {
			console.error("Deployment error:", error);
			resp.status(500);
			resp.write(JSON.stringify({ error: "Deployment failed" }));
		}
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleSave: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const p = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				instanceId: true,
				githubToken: true,
				deployKey: true,
				deployKeyPublic: true,
				state: true,
				geminiApiKey: true,
				anthropicApiKey: true,
			},
		});
		if (p === null) {
			resp.status(404);
			return;
		}
		const gc = GraphOrConfigSchema.safeParse(req.body);
		if (!gc.success) {
			resp.status(400);
			resp.write(JSON.stringify({ error: "Invalid configuration", issues: gc.error.format() }));
			return;
		}
		if (gc.data.type === "graph") {
			await db.project.update({
				where: { id: projectId },
				data: { draft: JSON.stringify(gc.data.graph) },
			});
			resp.status(200);
			return;
		}
		let repos: GithubRepository[] = [];
		if (p.githubToken) {
			const github = new GithubClient(p.githubToken);
			repos = await github.getRepositories();
		}
		const state = JSON.stringify(
			configToGraph(
				gc.data.config,
				getNetworks(resp.locals.username),
				repos,
				p.state ? parseGraph(p.state)!.data! : undefined,
			),
		);
		await db.project.update({
			where: { id: projectId },
			data: { draft: state },
		});
		resp.status(200);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleStatus: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const p = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				instanceId: true,
			},
		});
		if (p === null) {
			resp.status(404);
			return;
		}
		if (p.instanceId == null) {
			resp.status(404);
			return;
		}
		try {
			const status = await appManager.getStatus(p.instanceId);
			resp.status(200);
			resp.write(JSON.stringify(status));
		} catch (error) {
			console.error("Error getting status:", error);
			resp.status(500);
		}
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleConfigGet: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const project = await db.project.findUnique({
			where: {
				id: projectId,
			},
			select: {
				state: true,
			},
		});

		if (!project || !project.state) {
			resp.status(404).send({ error: "No deployed configuration found." });
			return;
		}

		const state = parseGraph(project.state)!.data!;
		const env = await getEnv(projectId, resp.locals.userId, resp.locals.username);
		const config = generateDodoConfig(projectId.toString(), state.nodes, env);

		if (!config) {
			resp.status(500).send({ error: "Failed to generate configuration." });
			return;
		}
		resp.status(200).json(config);
	} catch (e) {
		console.log(e);
		resp.status(500).send({ error: "Internal server error" });
	} finally {
		console.log("config get done");
		resp.end();
	}
};

const handleRemoveDeployment: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const p = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				instanceId: true,
				githubToken: true,
				deployKeyPublic: true,
				state: true,
				draft: true,
			},
		});
		if (p === null) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "Project not found" }));
			return;
		}
		if (p.instanceId == null) {
			resp.status(400);
			resp.write(JSON.stringify({ error: "Project not deployed" }));
			return;
		}
		const removed = await appManager.removeInstance(p.instanceId);
		if (!removed) {
			resp.status(500);
			resp.write(JSON.stringify({ error: "Failed to remove deployment from cluster" }));
			return;
		}
		if (p.githubToken && p.deployKeyPublic && p.state) {
			try {
				const github = new GithubClient(p.githubToken);
				const repos = extractGithubRepos(p.state);
				const diff = { toDelete: repos, toAdd: [] };
				await manageGithubRepos(github, diff, p.deployKeyPublic, env.PUBLIC_ADDR);
			} catch (error) {
				console.error("Error removing GitHub deploy keys:", error);
			}
		}
		await db.project.update({
			where: {
				id: projectId,
			},
			data: {
				instanceId: null,
				deployKeyPublic: null,
				access: null,
				state: null,
				draft: p.draft ?? p.state,
			},
		});
		resp.status(200);
		resp.write(JSON.stringify({ success: true }));
	} catch (e) {
		console.error("Error removing deployment:", e);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Internal server error" }));
	} finally {
		resp.end();
	}
};

const handleGithubRepos: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const project = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				githubToken: true,
			},
		});
		if (!project?.githubToken) {
			resp.status(400);
			resp.write(JSON.stringify({ error: "GitHub token not configured" }));
			return;
		}
		const github = new GithubClient(project.githubToken);
		const repositories = await github.getRepositories();
		resp.status(200);
		resp.header("Content-Type", "application/json");
		resp.write(JSON.stringify(repositories));
	} catch (e) {
		console.log(e);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Failed to fetch repositories" }));
	} finally {
		resp.end();
	}
};

const handleUpdateGithubToken: express.Handler = async (req, resp) => {
	try {
		await db.project.update({
			where: {
				id: Number(req.params["projectId"]),
				userId: resp.locals.userId,
			},
			data: {
				githubToken: req.body.githubToken,
			},
		});
		resp.status(200);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleUpdateGeminiToken: express.Handler = async (req, resp) => {
	try {
		await db.project.update({
			where: {
				id: Number(req.params["projectId"]),
				userId: resp.locals.userId,
			},
			data: {
				geminiApiKey: req.body.geminiApiKey,
			},
		});
		resp.status(200);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleUpdateAnthropicToken: express.Handler = async (req, resp) => {
	try {
		await db.project.update({
			where: {
				id: Number(req.params["projectId"]),
				userId: resp.locals.userId,
			},
			data: {
				anthropicApiKey: req.body.anthropicApiKey,
			},
		});
		resp.status(200);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const getNetworks = (username?: string | undefined): Network[] => {
	return [
		{
			name: "Trial",
			domain: "trial.dodoapp.xyz",
			hasAuth: false,
		},
		// TODO(gio): Remove
	].concat(
		username === "gio" || 1 == 1
			? [
					{
						name: "Public",
						domain: "v1.dodo.cloud",
						hasAuth: true,
					},
					{
						name: "Private",
						domain: "p.v1.dodo.cloud",
						hasAuth: true,
					},
				]
			: [],
	);
};

const getEnv = async (projectId: number, userId: string, username: string): Promise<Env> => {
	const project = await db.project.findUnique({
		where: {
			id: projectId,
			userId,
		},
		select: {
			deployKeyPublic: true,
			githubToken: true,
			geminiApiKey: true,
			anthropicApiKey: true,
			access: true,
			instanceId: true,
		},
	});
	if (!project) {
		throw new Error("Project not found");
	}
	const monitor = projectMonitors.get(projectId);
	const serviceNames = monitor ? monitor.getAllServiceNames() : [];
	const services = serviceNames.map((name: string) => ({
		name,
		workers: [...(monitor ? monitor.getWorkerStatusesForService(name) : new Map()).entries()].map(
			([id, status]) => ({
				...status,
				id,
			}),
		),
	}));
	return {
		deployKeyPublic: project.deployKeyPublic == null ? undefined : project.deployKeyPublic,
		instanceId: project.instanceId == null ? undefined : project.instanceId,
		access: JSON.parse(project.access ?? "[]"),
		integrations: {
			github: !!project.githubToken,
			gemini: !!project.geminiApiKey,
			anthropic: !!project.anthropicApiKey,
		},
		networks: getNetworks(username),
		services,
		user: {
			id: userId,
			username: username,
		},
	};
};

const handleEnv: express.Handler = async (req, resp) => {
	const projectId = Number(req.params["projectId"]);
	try {
		const env = await getEnv(projectId, resp.locals.userId, resp.locals.username);
		resp.status(200);
		resp.write(JSON.stringify(env));
	} catch (error) {
		console.error("Error getting env:", error);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Internal server error" }));
	} finally {
		resp.end();
	}
};

const handleServiceLogs: express.Handler = async (req, resp) => {
	const projectId = Number(req.params["projectId"]);
	const service = req.params["service"];
	const workerId = req.params["workerId"];

	resp.setHeader("Content-Type", "text/event-stream");
	resp.setHeader("Cache-Control", "no-cache");
	resp.setHeader("Connection", "keep-alive");
	resp.flushHeaders();

	const timestampFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	const sendLogs = (logs: LogItem[]) => {
		if (logs.length == 0) {
			return;
		}
		const logString = logs
			.map((l) => {
				const t = Instant.ofEpochMilli(l.timestampMilli);
				const formattedTimestamp = t.atZone(ZoneId.UTC).format(timestampFormat);
				return `\x1b[38;5;240m${formattedTimestamp}\x1b[0m ${l.contents}`;
			})
			.join("\n");
		resp.write("event: message\n");
		resp.write(`data: ${JSON.stringify({ logs: logString })}\n\n`);
	};

	try {
		const project = await db.project.findUnique({
			where: { id: projectId, userId: resp.locals.userId },
		});

		if (!project) {
			resp.status(404).end();
			return;
		}

		const monitor = projectMonitors.get(projectId);
		if (!monitor) {
			resp.status(404).end();
			return;
		}

		let lastLogId: number | undefined = undefined;
		const initialLogs = (await logStore.get(projectId, service, workerId)) || [];
		await sendLogs(initialLogs);
		if (initialLogs.length > 0) {
			lastLogId = initialLogs[initialLogs.length - 1].id;
		}
		resp.flushHeaders();

		const intervalId = setInterval(async () => {
			const currentLogs = (await logStore.get(projectId, service, workerId, lastLogId)) || [];
			if (currentLogs.length > 0) {
				await sendLogs(currentLogs);
				lastLogId = currentLogs[currentLogs.length - 1].id;
			}
		}, 500);

		req.on("close", () => {
			clearInterval(intervalId);
			resp.end();
		});
	} catch (e) {
		console.log(e);
		resp.status(500).end();
	}
};

const handleRegisterWorker: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const result = WorkerSchema.safeParse(req.body);
		if (!result.success) {
			console.log(JSON.stringify(result.error));
			resp.status(400);
			resp.write(
				JSON.stringify({
					error: "Invalid request data",
					details: result.error.format(),
				}),
			);
			return;
		}
		let monitor = projectMonitors.get(projectId);
		if (!monitor) {
			monitor = new ProjectMonitor();
			projectMonitors.set(projectId, monitor);
		}
		monitor.registerWorker(result.data);
		if (result.data.logs) {
			await logStore.store(projectId, result.data.service, result.data.id, result.data.logs);
		}
		resp.status(200);
		resp.write(
			JSON.stringify({
				success: true,
				logItemsConsumed: result.data.logs?.length ?? 0,
			}),
		);
	} catch (e) {
		console.log(e);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Failed to register worker" }));
	} finally {
		resp.end();
	}
};

async function reloadProject(projectId: number): Promise<boolean> {
	const monitor = projectMonitors.get(projectId);
	const projectWorkers = monitor ? monitor.getWorkerAddresses() : [];
	const workerCount = projectWorkers.length;
	if (workerCount === 0) {
		return true;
	}
	const results = await Promise.all(
		projectWorkers.map(async (workerAddress: string) => {
			try {
				const { data } = await axios.get(`http://${workerAddress}/reload`);
				return data.every((s: { status: string }) => s.status === "ok");
			} catch (error) {
				console.error(`Failed to reload worker ${workerAddress}:`, error);
				return false;
			}
		}),
	);
	return results.reduce((acc: boolean, curr: boolean) => acc && curr, true);
}

const handleReload: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const projectAuth = await db.project.findFirst({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: { id: true },
		});
		if (!projectAuth) {
			resp.status(404);
			return;
		}
		const success = await reloadProject(projectId);
		if (success) {
			resp.status(200);
		} else {
			resp.status(500);
		}
	} catch (e) {
		console.error(e);
		resp.status(500);
	}
};

const handleQuitWorker: express.Handler = async (req, resp) => {
	const projectId = Number(req.params["projectId"]);
	const serviceName = req.params["serviceName"];
	const workerId = req.params["workerId"];

	const projectMonitor = projectMonitors.get(projectId);
	if (!projectMonitor) {
		resp.status(404).send({ error: "Project monitor not found" });
		return;
	}

	try {
		await projectMonitor.terminateWorker(serviceName, workerId);
		resp.status(200).send({ message: "Worker termination initiated" });
	} catch (error) {
		console.error(
			`Failed to terminate worker ${workerId} in service ${serviceName} for project ${projectId}:`,
			error,
		);
		const errorMessage = error instanceof Error ? error.message : "Unknown error";
		resp.status(500).send({ error: `Failed to terminate worker: ${errorMessage}` });
	}
};

const handleReloadWorker: express.Handler = async (req, resp) => {
	const projectId = Number(req.params["projectId"]);
	const serviceName = req.params["serviceName"];
	const workerId = req.params["workerId"];

	const projectMonitor = projectMonitors.get(projectId);
	if (!projectMonitor) {
		resp.status(404).send({ error: "Project monitor not found" });
		return;
	}

	try {
		await projectMonitor.reloadWorker(serviceName, workerId);
		resp.status(200).send({ message: "Worker reload initiated" });
	} catch (error) {
		console.error(`Failed to reload worker ${workerId} in service ${serviceName} for project ${projectId}:`, error);
		const errorMessage = error instanceof Error ? error.message : "Unknown error";
		resp.status(500).send({ error: `Failed to reload worker: ${errorMessage}` });
	}
};

const analyzeRepoReqSchema = z.object({
	address: z.string(),
});

const handleAnalyzeRepo: express.Handler = async (req, resp) => {
	const projectId = Number(req.params["projectId"]);
	const project = await db.project.findUnique({
		where: {
			id: projectId,
			userId: resp.locals.userId,
		},
		select: {
			githubToken: true,
			deployKey: true,
			deployKeyPublic: true,
		},
	});
	if (!project) {
		resp.status(404).send({ error: "Project not found" });
		return;
	}
	if (!project.githubToken) {
		resp.status(400).send({ error: "GitHub token not configured" });
		return;
	}
	let tmpDir: tmp.DirResult | null = null;
	try {
		let deployKey: string | null = project.deployKey;
		let deployKeyPublic: string | null = project.deployKeyPublic;
		if (!deployKeyPublic) {
			[deployKeyPublic, deployKey] = await generateKey(tmp.dirSync().name);
			await db.project.update({
				where: { id: projectId },
				data: {
					deployKeyPublic: deployKeyPublic,
					deployKey: deployKey,
				},
			});
		}
		const github = new GithubClient(project.githubToken);
		const result = analyzeRepoReqSchema.safeParse(req.body);
		if (!result.success) {
			resp.status(400).send({ error: "Invalid request data" });
			return;
		}
		const { address } = result.data;
		tmpDir = tmp.dirSync({
			unsafeCleanup: true,
		});
		await github.addDeployKey(address, deployKeyPublic);
		await fs.promises.writeFile(path.join(tmpDir.name, "key"), deployKey!, {
			mode: 0o600,
		});
		shell.exec(
			`GIT_SSH_COMMAND='ssh -i ${tmpDir.name}/key -o IdentitiesOnly=yes' git clone ${address} ${tmpDir.name}/code`,
		);
		const fsc = new RealFileSystem(`${tmpDir.name}/code`);
		const analyzer = new NodeJSAnalyzer();
		const info = await analyzer.analyze(fsc, "/");
		resp.status(200).send([info]);
	} catch (e) {
		console.error(e);
		resp.status(500).send({ error: "Failed to analyze repository" });
	} finally {
		if (tmpDir) {
			tmpDir.removeCallback();
		}
		resp.end();
	}
};

const auth = (req: express.Request, resp: express.Response, next: express.NextFunction) => {
	// Hardcoded user for development
	resp.locals.userId = "1";
	resp.locals.username = "gio";
	next();
};

const handleGithubPushWebhook: express.Handler = async (req, resp) => {
	try {
		// TODO(gio): Implement GitHub signature verification for security
		const webhookSchema = z.object({
			repository: z.object({
				ssh_url: z.string(),
			}),
		});

		const result = webhookSchema.safeParse(req.body);
		if (!result.success) {
			console.warn("GitHub webhook: Invalid payload:", result.error.issues);
			resp.status(400).json({ error: "Invalid webhook payload" });
			return;
		}
		const { ssh_url: addr } = result.data.repository;
		const allProjects = await db.project.findMany({
			select: {
				id: true,
				state: true,
			},
			where: {
				instanceId: {
					not: null,
				},
			},
		});
		// TODO(gio): This should run in background
		new Promise<boolean>((resolve, reject) => {
			setTimeout(() => {
				const projectsToReloadIds: number[] = [];
				for (const project of allProjects) {
					if (project.state && project.state.length > 0) {
						const projectRepos = extractGithubRepos(project.state);
						if (projectRepos.includes(addr)) {
							projectsToReloadIds.push(project.id);
						}
					}
				}
				Promise.all(projectsToReloadIds.map((id) => reloadProject(id)))
					.then((results) => {
						resolve(results.reduce((acc, curr) => acc && curr, true));
					})
					// eslint-disable-next-line @typescript-eslint/no-explicit-any
					.catch((reason: any) => reject(reason));
			}, 10);
		});
		// eslint-disable-next-line @typescript-eslint/no-explicit-any
	} catch (error: any) {
		console.error(error);
		resp.status(500);
	}
};

const handleValidateConfig: express.Handler = async (req, resp) => {
	try {
		const validationResult = ConfigSchema.safeParse(req.body);
		if (!validationResult.success) {
			resp.status(400);
			resp.header("Content-Type", "application/json");
			resp.write(JSON.stringify({ success: false, errors: validationResult.error.flatten() }));
		} else {
			resp.status(200);
			resp.header("Content-Type", "application/json");
			resp.write(JSON.stringify({ success: true }));
		}
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

function handleStateGetStream(state: "deploy" | "draft"): express.Handler {
	return async (req, resp) => {
		resp.setHeader("Content-Type", "text/event-stream");
		resp.setHeader("Cache-Control", "no-cache");
		resp.setHeader("Connection", "keep-alive");
		resp.flushHeaders();

		try {
			let intervalId: NodeJS.Timeout | null = null;
			let lastState: Graph | null = null;
			const sendState = async () => {
				const currentState = await getState(Number(req.params["projectId"]), resp.locals.userId, state);
				if (currentState == null) {
					resp.status(404).end();
					return;
				}
				if (JSON.stringify(currentState) !== JSON.stringify(lastState)) {
					lastState = currentState;
					resp.write("event: message\n");
					resp.write(`data: ${JSON.stringify(currentState)}\n\n`);
				}
				intervalId = setTimeout(sendState, 500);
			};

			await sendState();

			req.on("close", () => {
				if (intervalId) {
					clearTimeout(intervalId);
				}
				resp.end();
			});
		} catch (e) {
			console.log(e);
			resp.end();
		}
	};
}

async function start() {
	await db.$connect();
	const app = express();
	app.set("json spaces", 2);
	app.use(express.json()); // Global JSON parsing

	// Public webhook route - no auth needed
	app.post("/api/webhook/github/push", handleGithubPushWebhook);

	// Authenticated project routes
	const projectRouter = express.Router();
	projectRouter.use(auth);
	projectRouter.post("/:projectId/analyze", handleAnalyzeRepo);
	projectRouter.post("/:projectId/saved", handleSave);
	projectRouter.get("/:projectId/state/stream/deploy", handleStateGetStream("deploy"));
	projectRouter.get("/:projectId/state/stream/draft", handleStateGetStream("draft"));
	projectRouter.get("/:projectId/saved/deploy", handleSavedGet("deploy"));
	projectRouter.get("/:projectId/saved/draft", handleSavedGet("draft"));
	projectRouter.post("/:projectId/deploy", handleDeploy);
	projectRouter.get("/:projectId/status", handleStatus);
	projectRouter.get("/:projectId/config", handleConfigGet);
	projectRouter.delete("/:projectId", handleProjectDelete);
	projectRouter.get("/:projectId/repos/github", handleGithubRepos);
	projectRouter.post("/:projectId/github-token", handleUpdateGithubToken);
	projectRouter.post("/:projectId/gemini-token", handleUpdateGeminiToken);
	projectRouter.post("/:projectId/anthropic-token", handleUpdateAnthropicToken);
	projectRouter.get("/:projectId/env", handleEnv);
	projectRouter.post("/:projectId/reload/:serviceName/:workerId", handleReloadWorker);
	projectRouter.post("/:projectId/quitquitquit/:serviceName/:workerId", handleQuitWorker);
	projectRouter.post("/:projectId/reload", handleReload);
	projectRouter.get("/:projectId/logs/:service/:workerId", handleServiceLogs);
	projectRouter.post("/:projectId/remove-deployment", handleRemoveDeployment);
	projectRouter.get("/", handleProjectAll);
	projectRouter.post("/", handleProjectCreate);

	app.use("/api/project", projectRouter); // Mount the authenticated router

	app.use("/", express.static("../front/dist"));

	const internalApi = express();
	internalApi.use(express.json());
	internalApi.post("/api/project/:projectId/workers", handleRegisterWorker);
	internalApi.get("/api/project/:projectId/config", handleConfigGet);
	internalApi.post("/api/project/:projectId/saved", handleSave);
	internalApi.post("/api/project/:projectId/deploy", handleDeploy);
	internalApi.post("/api/validate-config", handleValidateConfig);

	app.listen(env.DODO_PORT_WEB, () => {
		console.log("Web server started on port", env.DODO_PORT_WEB);
	});

	internalApi.listen(env.DODO_PORT_API, () => {
		console.log("Internal API server started on port", env.DODO_PORT_API);
	});
}

start();
