import { z } from "zod";

const USERNAME = z
  .string()
  .min(1, "Username is too short.")
  .regex(/^[a-z0-9]+$/, "Username must be lowercase alphanumeric.");
const DISPLAY_NAME = z.string().min(1, "Display name is too short.");
const EMAIL = z.string().email("Not an email.");
const PASSWORD = z
  .string()
  .min(12, "Password must be at least 12 characters long.");
const AVATAR = z.string().refine(
  (val) => {
    const parts = val.split(",");
    const data = parts.length === 2 ? parts[1] : parts[0];

    try {
      const buf = Buffer.from(data, "base64");
      return buf.length <= 2_000_000;
    } catch (e) {
      return false;
    }
  },
  {
    message: "File is bigger than 2 MB.",
    path: ["avatar"]
  }
);

export const loginSchema = z.object({
  username: USERNAME,
  password: PASSWORD
});
export type LoginSchema = z.infer<typeof loginSchema>;

export const registerSchema = z
  .object({
    username: USERNAME,
    displayName: DISPLAY_NAME,
    email: EMAIL,
    password: PASSWORD,
    confirmPassword: PASSWORD,
    avatar: AVATAR.optional()
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords do not match.",
    path: ["confirmPassword"]
  });

export type RegisterSchema = z.infer<typeof registerSchema>;

export const aboutMeSchema = z.object({
  username: USERNAME,
  displayName: DISPLAY_NAME,
  email: EMAIL,
  avatar: AVATAR.optional()
});
export type AboutMeSchema = z.infer<typeof aboutMeSchema>;

export const passwordUpdateSchema = z
  .object({
    password: PASSWORD,
    newPassword: PASSWORD,
    confirmPassword: PASSWORD
  })
  .refine((data) => data.newPassword === data.confirmPassword, {
    message: "Passwords do not match.",
    path: ["confirmPassword"]
  });

export type PasswordUpdateSchema = z.infer<typeof passwordUpdateSchema>;
