import { PrismaClient } from "@prisma/client";
import express from "express";
import { env } from "node:process";
import axios from "axios";
import { GithubClient } from "./github";
import { AppManager } from "./app_manager";
import { z } from "zod";

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

const workers = new Map<number, string[]>();
const logs = new Map<number, Map<string, string>>();

const handleProjectCreate: express.Handler = async (req, resp) => {
	try {
		const { id } = await db.project.create({
			data: {
				userId: resp.locals.userId,
				name: req.body.name,
			},
		});
		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();
	}
};

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

function handleSavedGet(state: "deploy" | "draft"): express.Handler {
	return async (req, resp) => {
		try {
			const r = await db.project.findUnique({
				where: {
					id: Number(req.params["projectId"]),
					userId: resp.locals.userId,
				},
				select: {
					state: true,
					draft: true,
				},
			});
			if (r == null) {
				resp.status(404);
				return;
			}
			resp.status(200);
			resp.header("content-type", "application/json");
			if (state === "deploy") {
				if (r.state == null) {
					resp.send({
						nodes: [],
						edges: [],
						viewport: { x: 0, y: 0, zoom: 1 },
					});
				} else {
					resp.send(JSON.parse(Buffer.from(r.state).toString("utf8")));
				}
			} else {
				if (r.draft == null) {
					if (r.state == null) {
						resp.send({
							nodes: [],
							edges: [],
							viewport: { x: 0, y: 0, zoom: 1 },
						});
					} else {
						resp.send(JSON.parse(Buffer.from(r.state).toString("utf8")));
					}
				} else {
					resp.send(JSON.parse(Buffer.from(r.draft).toString("utf8")));
				}
			}
		} catch (e) {
			console.log(e);
			resp.status(500);
		} finally {
			resp.end();
		}
	};
}

const handleDelete: 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;
		}
		let ok = false;
		if (p.instanceId === null) {
			ok = true;
		} else {
			ok = await appManager.removeInstance(p.instanceId);
		}
		if (ok) {
			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): 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 manageGithubKeys(github: GithubClient, deployKey: string, diff: RepoDiff): Promise<void> {
	for (const repoUrl of diff.toDelete ?? []) {
		try {
			await github.removeDeployKey(repoUrl, deployKey);
			console.log(`Removed deploy key 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}`);
		} catch (error) {
			console.error(`Failed to add deploy key from repository ${repoUrl}:`, error);
		}
	}
}

const handleDeploy: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const state = JSON.stringify(req.body.state);
		const p = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				instanceId: true,
				githubToken: true,
				deployKey: true,
				state: true,
			},
		});
		if (p === null) {
			resp.status(404);
			return;
		}
		await db.project.update({
			where: {
				id: projectId,
			},
			data: {
				draft: state,
			},
		});
		let diff: RepoDiff | null = null;
		let deployKey: string | null = null;
		try {
			if (p.instanceId == null) {
				const deployResponse = await appManager.deploy(req.body.config);
				await db.project.update({
					where: {
						id: projectId,
					},
					data: {
						state,
						draft: null,
						instanceId: deployResponse.id,
						deployKey: deployResponse.deployKey,
						access: JSON.stringify(deployResponse.access),
					},
				});
				diff = { toAdd: extractGithubRepos(state) };
				deployKey = deployResponse.deployKey;
			} else {
				const deployResponse = await appManager.update(p.instanceId, req.body.config);
				diff = calculateRepoDiff(extractGithubRepos(p.state), extractGithubRepos(state));
				deployKey = p.deployKey;
				await db.project.update({
					where: {
						id: projectId,
					},
					data: {
						state,
						draft: null,
						access: JSON.stringify(deployResponse.access),
					},
				});
			}
			if (diff && p.githubToken && deployKey) {
				const github = new GithubClient(p.githubToken);
				await manageGithubKeys(github, deployKey, diff);
			}
			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 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 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,
				deployKey: 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.deployKey && p.state) {
			try {
				const github = new GithubClient(p.githubToken);
				const repos = extractGithubRepos(p.state);
				const diff = { toDelete: repos, toAdd: [] };
				await manageGithubKeys(github, p.deployKey, diff);
			} catch (error) {
				console.error("Error removing GitHub deploy keys:", error);
			}
		}
		await db.project.update({
			where: {
				id: projectId,
			},
			data: {
				instanceId: null,
				deployKey: 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 {
		const projectId = Number(req.params["projectId"]);
		const { githubToken } = req.body;
		await db.project.update({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			data: { githubToken },
		});
		resp.status(200);
	} catch (e) {
		console.log(e);
		resp.status(500);
	} finally {
		resp.end();
	}
};

const handleEnv: express.Handler = async (req, resp) => {
	const projectId = Number(req.params["projectId"]);
	try {
		const project = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
			select: {
				deployKey: true,
				githubToken: true,
				access: true,
			},
		});
		if (!project) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "Project not found" }));
			return;
		}
		const projectLogs = logs.get(projectId) || new Map();
		const services = Array.from(projectLogs.keys());
		resp.status(200);
		resp.write(
			JSON.stringify({
				// TODO(gio): get from env or command line flags
				managerAddr: "http://10.42.0.95:8081",
				deployKey: project.deployKey,
				access: JSON.parse(project.access ?? "[]"),
				integrations: {
					github: !!project.githubToken,
				},
				networks: [
					{
						name: "Trial",
						domain: "trial.dodoapp.xyz",
					},
				],
				services,
				user: {
					id: resp.locals.userId,
					username: resp.locals.username,
				},
			}),
		);
	} catch (error) {
		console.error("Error checking integrations:", error);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Internal server error" }));
	} finally {
		resp.end();
	}
};

const handleServiceLogs: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const service = req.params["service"];
		const project = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
		});
		if (project == null) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "Project not found" }));
			return;
		}
		const projectLogs = logs.get(projectId);
		if (!projectLogs) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "No logs found for this project" }));
			return;
		}
		const serviceLog = projectLogs.get(service);
		if (!serviceLog) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "No logs found for this service" }));
			return;
		}
		resp.status(200);
		resp.write(JSON.stringify({ logs: serviceLog }));
	} catch (e) {
		console.log(e);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Failed to get service logs" }));
	} finally {
		resp.end();
	}
};

const WorkerSchema = z.object({
	service: z.string(),
	address: z.string().url(),
	logs: z.optional(z.string()),
});

const handleRegisterWorker: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const result = WorkerSchema.safeParse(req.body);
		if (!result.success) {
			resp.status(400);
			resp.write(
				JSON.stringify({
					error: "Invalid request data",
					details: result.error.format(),
				}),
			);
			return;
		}
		const { service, address, logs: log } = result.data;
		const projectWorkers = workers.get(projectId) || [];
		if (!projectWorkers.includes(address)) {
			projectWorkers.push(address);
		}
		workers.set(projectId, projectWorkers);
		if (log) {
			const svcLogs: Map<string, string> = logs.get(projectId) || new Map();
			svcLogs.set(service, log);
			logs.set(projectId, svcLogs);
		}
		resp.status(200);
		resp.write(
			JSON.stringify({
				success: true,
			}),
		);
	} catch (e) {
		console.log(e);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Failed to register worker" }));
	} finally {
		resp.end();
	}
};

const handleReload: express.Handler = async (req, resp) => {
	try {
		const projectId = Number(req.params["projectId"]);
		const projectWorkers = workers.get(projectId) || [];
		const project = await db.project.findUnique({
			where: {
				id: projectId,
				userId: resp.locals.userId,
			},
		});
		if (project == null) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "Project not found" }));
			return;
		}
		if (projectWorkers.length === 0) {
			resp.status(404);
			resp.write(JSON.stringify({ error: "No workers registered for this project" }));
			return;
		}
		await Promise.all(
			projectWorkers.map(async (workerAddress) => {
				try {
					const updateEndpoint = `${workerAddress}/update`;
					await axios.post(updateEndpoint);
					// eslint-disable-next-line @typescript-eslint/no-explicit-any
				} catch (error: any) {
					console.log(`Failed to update worker ${workerAddress}: ${error.message || "Unknown error"}`);
				}
			}),
		);
		resp.status(200);
		resp.write(JSON.stringify({ success: true }));
	} catch (e) {
		console.log(e);
		resp.status(500);
		resp.write(JSON.stringify({ error: "Failed to reload workers" }));
	} finally {
		resp.end();
	}
};

const auth = (req: express.Request, resp: express.Response, next: express.NextFunction) => {
	const userId = req.get("x-forwarded-userid");
	const username = req.get("x-forwarded-user");
	if (userId == null || username == null) {
		resp.status(401);
		resp.write("Unauthorized");
		resp.end();
		return;
	}
	resp.locals.userId = userId;
	resp.locals.username = username;
	next();
};

async function start() {
	await db.$connect();
	const app = express();
	app.use(express.json());
	app.use(auth);
	app.post("/api/project/:projectId/saved", handleSave);
	app.get("/api/project/:projectId/saved/deploy", handleSavedGet("deploy"));
	app.get("/api/project/:projectId/saved/draft", handleSavedGet("draft"));
	app.post("/api/project/:projectId/deploy", handleDeploy);
	app.get("/api/project/:projectId/status", handleStatus);
	app.delete("/api/project/:projectId", handleDelete);
	app.get("/api/project", handleProjectAll);
	app.post("/api/project", handleProjectCreate);
	app.get("/api/project/:projectId/repos/github", handleGithubRepos);
	app.post("/api/project/:projectId/github-token", handleUpdateGithubToken);
	app.get("/api/project/:projectId/env", handleEnv);
	app.post("/api/project/:projectId/reload", handleReload);
	app.get("/api/project/:projectId/logs/:service", handleServiceLogs);
	app.post("/api/project/:projectId/remove-deployment", handleRemoveDeployment);
	app.use("/", express.static("../front/dist"));

	const api = express();
	api.use(express.json());
	api.post("/api/project/:projectId/workers", handleRegisterWorker);

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

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

start();
