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 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();
  }
};

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", handleProjectAll);
  app.post("/api/project", handleProjectCreate);
  app.use("/", express.static("../front/dist"));
  app.listen(env.DODO_PORT_WEB, () => {
    console.log("started");
  });
}

start();
