import axios from "axios";
import { type DrizzleError, sql } from "drizzle-orm";
import type { Request, Response } from "express";
import { Router } from "express";
import https from "https";
import { db } from "../../../../pkg/db/db.js";
import {
	insertServerDataSchema,
	serverData,
} from "../../../../pkg/db/schema/servers.js";
import { createLogger } from "../../../../pkg/logger/logger.js";
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";

const router = Router();

router.post("/", async (req: Request, res: Response) => {
	// when a new server is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there
	//res.status(200).json({ message: "Server added", ip: req.hostname });
	const log = createLogger({ module: "admin", subModule: "add server" });
	const parsed = insertServerDataSchema.safeParse(req.body);

	if (!parsed.success) {
		return res.status(400).json({ errors: parsed.error.flatten() });
	}

	const { data, error } = await tryCatch(
		db
			.insert(serverData)
			.values({
				...parsed.data,
				add_user: req.user?.username,
				add_date: sql`NOW()`,
				upd_user: req.user?.username,
				upd_date: sql`NOW()`,
			})
			//.onConflictDoNothing()
			.returning({
				name: serverData.name,
				plantToken: serverData.plantToken,
			}),
	);

	if (error) {
		const err: DrizzleError = error;
		return res.status(400).json({
			message: `Error adding the server`,
			error: err.cause,
		});
	}

	if (req.hostname === "localhost" && process.env.MAIN_SERVER) {
		log.info({}, "Running in dev server about to add in a new server");
		const axiosInstance = axios.create({
			httpsAgent: new https.Agent({ rejectUnauthorized: false }),
			baseURL: process.env.MAIN_SERVER, // e.g. "https://example.com"
			withCredentials: true,
		});

		const loginRes = (await axiosInstance.post(
			`${process.env.MAIN_SERVER}/lst/api/auth/sign-in/username`,
			{
				username: process.env.MAIN_SERVER_USERNAME,
				password: process.env.MAIN_SERVER_PASSWORD,
			},
			{
				headers: { "Content-Type": "application/json" },
			},
		)) as any;
		const setCookie = loginRes.headers["set-cookie"][0];

		if (!setCookie) {
			throw new Error("Did not receive a Set-Cookie header from login");
		}

		const { data, error } = await tryCatch(
			axios.post(
				`${process.env.MAIN_SERVER}/lst/api/admin/server`,
				parsed.data,
				{
					headers: {
						"Content-Type": "application/json",
						Cookie: setCookie.split(";")[0],
					},
					withCredentials: true,
				},
			),
		);

		if (error) {
			log.error(
				{ stack: error },
				"There was an error adding the server to Main Server",
			);
		}
		log.info(
			{ stack: data?.data },
			"A new Server was just added to the server.",
		);
	}

	return res
		.status(201)
		.json({ message: `Server ${data[0]?.name} added`, data: data });
});

export default router;
