import { PrismaClient } from "@prisma/client";
import express from "express";
import { env } from "node:process";
import axios from "axios";

const db = new PrismaClient();

const handleProjectCreate: express.Handler = async (req, resp) => {
    try {
        const { id } = await db.project.create({
            data: {
                userId: "gio", // req.get("x-forwarded-userid")!,
                name: req.body.name,
            },
        });
        resp.status(200);
        resp.header("Content-Type", "application/json");
        resp.write(
            JSON.stringify({
                id,
            }),
        );
    } 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: "gio", // req.get("x-forwarded-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"]),
            },
            data: {
                draft: Buffer.from(JSON.stringify(req.body)),
            },
        });
        resp.status(200);
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

const handleSavedGet: express.Handler = async (req, resp) => {
    try {
        const r = await db.project.findUnique({
            where: {
                id: Number(req.params["projectId"]),
            },
            select: {
                state: true,
                draft: true,
            },
        });
        if (r == null) {
            resp.status(404);
        } else {
            resp.status(200);
            resp.header("content-type", "application/json");
            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,
            },
            select: {
                instanceId: true,
            },
        });
        if (p === null) {
            resp.status(404);
            return;
        }
        const r = await axios.request({
            url: `http://appmanager.hgrz-appmanager.svc.cluster.local/api/instance/${p.instanceId}/remove`,
            method: "post",
        });
        if (r.status === 200) {
            await db.project.delete({
                where: {
                    id: projectId,
                },
            });    
        }
        resp.status(200);
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

const handleDeploy: express.Handler = async (req, resp) => {
    try {
        const projectId = Number(req.params["projectId"]);
        const state = Buffer.from(JSON.stringify(req.body.state));
        const p = await db.project.findUnique({
            where: {
                id: projectId,
            },
            select: {
                instanceId: true,
            },
        });
        if (p === null) {
            resp.status(404);
            return;
        }
        await db.project.update({
            where: {
                id: projectId,
            },
            data: {
                draft: state,
            },
        });
        let r: { status: number; data: { id: string; deployKey: string } };
        if (p.instanceId == null) {
            r = await axios.request({
                url: "http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app",
                method: "post",
                data: {
                    config: req.body.config,
                },
            });
            if (r.status === 200) {
                await db.project.update({
                    where: {
                        id: projectId,
                    },
                    data: {
                        state,
                        draft: null,
                        instanceId: r.data.id,
                        deployKey: r.data.deployKey,
                    },
                });
            }
        } else {
            r = await axios.request({
                url: `http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app/${p.instanceId}`,
                method: "put",
                data: {
                    config: req.body.config,
                },
            });
            if (r.status === 200) {
                await db.project.update({
                    where: {
                        id: projectId,
                    },
                    data: {
                        state,
                        draft: null,
                    },
                });
            }
        }
    } 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,
            },
            select: {
                instanceId: true,
            },
        });
        console.log(projectId, p);
        if (p === null) {
            resp.status(404);
            return;
        }
        if (p.instanceId == null) {
            resp.status(404);
            return;
        }
        const r = await axios.request({
            url: `http://appmanager.hgrz-appmanager.svc.cluster.local/api/instance/${p.instanceId}/status`,
            method: "get",
        });
        resp.status(r.status);
        if (r.status === 200) {
            resp.write(JSON.stringify(r.data));
        }
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

async function start() {
    await db.$connect();
    const app = express();
    app.use(express.json());
    app.post("/api/project/:projectId/saved", handleSave);
    app.get("/api/project/:projectId/saved", handleSavedGet);
    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.use("/", express.static("../front/dist"));
    app.listen(env.DODO_PORT_WEB, () => {
        console.log("started");
    });
}

start();
