import { createError, readBody, setResponseStatus } from "h3"
import { Prisma } from "@prisma/client"
import { getSessionPayload, setAuthSession } from "~/server/utils/auth"
import { hashPassword } from "~/server/utils/password"
import { prisma } from "~/server/utils/prisma"

interface RegisterBody {
  email?: string
  password?: string
  name?: string
}

const normalizeEmail = (value: string) => value.trim().toLowerCase()

const ensureValidEmail = (email: string) => {
  if (!/^\S+@\S+\.\S+$/.test(email)) {
    throw createError({
      statusCode: 400,
      statusMessage: "Correo invalido"
    })
  }
}

export default defineEventHandler(async (event) => {
  if (event.method !== "POST") {
    setResponseStatus(event, 405)
    return {
      error: true,
      message: "Metodo no permitido"
    }
  }

  const body = await readBody<RegisterBody>(event)
  const email = normalizeEmail(body.email || "")
  const password = body.password || ""
  const name = body.name?.trim() || ""

  if (!name || !email || !password) {
    throw createError({
      statusCode: 400,
      statusMessage: "Debes completar nombre, correo y contrasena"
    })
  }

  if (name.length > 80) {
    throw createError({
      statusCode: 400,
      statusMessage: "El nombre es demasiado largo"
    })
  }

  ensureValidEmail(email)

  let passwordHash: string

  try {
    passwordHash = hashPassword(password)
  } catch (error) {
    throw createError({
      statusCode: 400,
      statusMessage: error instanceof Error ? error.message : "Contrasena invalida"
    })
  }

  const usersCount = await prisma.user.count()
  const role = usersCount === 0 ? "ADMIN" : "USER"

  try {
    const user = await prisma.user.create({
      data: {
        email,
        name,
        passwordHash,
        role
      }
    })

    await setAuthSession(event, user.id)

    return await getSessionPayload(event)
  } catch (error) {
    if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") {
      throw createError({
        statusCode: 409,
        statusMessage: "Ese correo ya existe"
      })
    }

    throw error
  }
})
