import { hash } from 'bcryptjs'
import { NextResponse } from 'next/server'
import { z } from 'zod'
import { createUser, emailExists } from '@/lib/users'

const registerSchema = z.object({
  email: z.string().trim().email('Podaj poprawny adres e-mail'),
  password: z
    .string()
    .min(8, 'Hasło musi mieć co najmniej 8 znaków')
    .max(72, 'Hasło może mieć co najwyżej 72 znaki'),
  name: z.string().trim().max(120).optional().or(z.literal('')),
  termsAccepted: z.literal(true, {
    errorMap: () => ({ message: 'Musisz zaakceptować regulamin i politykę prywatności' }),
  }),
})

export async function POST(req: Request) {
  try {
    const body = await req.json()
    const parsed = registerSchema.safeParse(body)
    if (!parsed.success) {
      const first = parsed.error.flatten().fieldErrors
      const msg =
        first.email?.[0] ?? first.password?.[0] ?? first.termsAccepted?.[0] ?? 'Niepoprawne dane'
      return NextResponse.json({ error: msg }, { status: 400 })
    }

    const { email, password, name, termsAccepted } = parsed.data
    const emailNorm = email.toLowerCase()

    if (await emailExists(emailNorm)) {
      return NextResponse.json({ error: 'Konto z tym adresem e-mail już istnieje' }, { status: 409 })
    }

    const passwordHash = await hash(password, 12)
    const displayName = name && name.length > 0 ? name : null
    const acceptedAt = termsAccepted ? new Date() : new Date()

    try {
      await createUser({
        email: emailNorm,
        passwordHash,
        name: displayName,
        termsAcceptedAt: acceptedAt,
      })
    } catch (e: unknown) {
      const err = e as { code?: string }
      if (err.code === 'ER_DUP_ENTRY') {
        return NextResponse.json({ error: 'Konto z tym adresem e-mail już istnieje' }, { status: 409 })
      }
      throw e
    }

    return NextResponse.json({ ok: true })
  } catch (e) {
    console.error('register', e)
    return NextResponse.json({ error: 'Błąd serwera. Spróbuj ponownie później.' }, { status: 500 })
  }
}
