import { z, createRoute, OpenAPIHono } from "@hono/zod-openapi";
import { registerUser } from "../../controllers/register.js";
import { authMiddleware } from "../../middleware/authMiddleware.js";
import hasCorrectRole from "../../middleware/roleCheck.js";

const app = new OpenAPIHono();

const UserSchema = z.object({
  username: z
    .string()
    .regex(/^[a-zA-Z0-9_]{3,30}$/)
    .openapi({ example: "smith034" }),
  email: z.string().email().openapi({ example: "smith@example.com" }),
  password: z
    .string()
    .min(6, { message: "Passwords must be longer than 3 characters" })
    .regex(/[A-Z]/, {
      message: "Password must contain at least one uppercase letter",
    })
    .regex(/[\W_]/, {
      message: "Password must contain at least one special character",
    })
    .openapi({ example: "Password1!" }),
});

type User = z.infer<typeof UserSchema>;

const responseSchema = z.object({
  success: z.boolean().optional().openapi({ example: true }),
  message: z.string().optional().openapi({ example: "User Created" }),
});

app.openapi(
  createRoute({
    tags: ["Auth:admin"],
    summary: "Creates user",
    method: "post",
    path: "/",
    middleware: [
      authMiddleware,
      hasCorrectRole(["admin", "systemAdmin"], "admin"),
    ],
    request: {
      body: {
        content: {
          "application/json": { schema: UserSchema },
        },
      },
    },
    responses: {
      200: {
        content: { "application/json": { schema: responseSchema } },
        description: "Retrieve the user",
      },
      400: {
        content: {
          "application/json": {
            schema: z.object({
              success: z.boolean().openapi({ example: false }),
              message: z
                .string()
                .openapi({ example: "Invalid credentials passed" }),
            }),
          },
        },
        description: "Retrieve the user",
      },
    },
  }),
  async (c) => {
    // apit hit
    //apiHit(c, {endpoint: "api/auth/register"});
    let { username, email, password } = await c.req.json();

    if (!username || !email || !password) {
      return c.json({ success: false, message: "Credentials missing" }, 400);
    }

    // some usernames that should be ignored
    const badActors = ["admin", "root"];
    if (badActors.includes(username)) {
      return c.json(
        {
          success: false,
          message: `${username} is not a valid name to be registerd please try again`,
        },
        400
      );
    }

    try {
      const register = await registerUser(username, password, email);

      return c.json(
        {
          success: register.success,
          message: register.message,
          user: register?.user,
        },
        200
      );
    } catch (error) {
      console.log(error);
      return c.json(
        {
          success: false,
          message: `${username} already exists please login or reset password, if you feel this is an error please contact your admin.`,
        },
        400
      );
    }
  }
);

export default app;
