import { Hono } from "hono";
import { apiResponse } from "../modules/api-utils/apiResponse";
import { ZodError } from "zod";
import { cors } from "hono/cors";
import GenericError from "../Errors/GenericError";
import teapot from "./teapot";
import authRouter from "./routers/authRouter";
import userRouter from "./routers/user";
import companyRouter from "./routers/companyRouter";
import credentialRouter from "./routers/credentialRouter";
import credentialTypeRouter from "./routers/credentialTypeRouter";
import roleRouter from "./routers/roleRouter";
import permissionRouter from "./routers/permissionRouter";
import unifiRouter from "./routers/unifiRouter";
import procurementRouter from "./routers/procurementRouter";
import salesRouter from "./routers/salesRouter";
import cwRouter from "./routers/cwRouter";
import scheduleRouter from "./routers/scheduleRouter";
import timeEntryRouter from "./routers/timeEntryRouter";

const app = new Hono();
const v1 = new Hono();

app.onError((err, ctx) => {
  const errClassName = err.constructor.name;

  if (
    errClassName.toLowerCase().includes("prisma") ||
    err.message.toLowerCase().includes("prisma") ||
    err.name.toLowerCase().includes("prisma")
  ) {
    console.trace(err);
    return ctx.json(apiResponse.internalError(), 500);
  }

  if (err instanceof ZodError) {
    return ctx.json(
      apiResponse.zodError(err),
      //@ts-ignore
      apiResponse.zodError(err).status
    );
  }

  const response = apiResponse.error(err);
  return ctx.json(response, response.status);
});

app.use("*", cors());

app.get("/healthz", (c) => c.json({ status: "ok" }));

app.notFound((c) => {
  const response = apiResponse.error(
    new GenericError({
      name: "NotFound",
      message: `Cannot ${c.req.method.toUpperCase()} ${c.req.path}`,
      status: 404,
      cause: "Unknown",
    })
  );
  return c.json(response, response.status);
});

v1.route("/teapot", teapot);
v1.route("/auth", authRouter);
v1.route("/user", userRouter);
v1.route("/company", companyRouter);
v1.route("/credential", credentialRouter);
v1.route("/credential-type", credentialTypeRouter);
v1.route("/role", roleRouter);
v1.route("/permissions", permissionRouter);
v1.route("/unifi", unifiRouter);
v1.route("/procurement", procurementRouter);
v1.route("/sales", salesRouter);
v1.route("/cw", cwRouter);
v1.route("/schedule", scheduleRouter);
v1.route("/time-entry", timeEntryRouter);
app.route("/v1", v1);

export default app;
