import { UserRole } from "@prisma/client";
import { NextResponse } from "next/server";
import { isConfiguredAdminEmail } from "@/lib/auth/admin";
import { hashPassword } from "@/lib/auth/password";
import { prisma } from "@/lib/prisma";
import { issueEmailVerificationToken, sendEmailVerificationLink } from "@/lib/auth/verification";
import { buildAppUrl } from "@/lib/http/url";

function redirectTo(request: Request, path: string, params: Record<string, string>) {
  return NextResponse.redirect(buildAppUrl(request, path, params));
}

export async function POST(request: Request) {
  const formData = await request.formData();

  const name = typeof formData.get("name") === "string" ? formData.get("name")!.toString().trim() : "";
  const email = typeof formData.get("email") === "string" ? formData.get("email")!.toString().trim().toLowerCase() : "";
  const password = typeof formData.get("password") === "string" ? formData.get("password")!.toString() : "";

  if (!email || !password || password.length < 8) {
    return redirectTo(request, "/register", { error: "invalid_input" });
  }

  try {
    const existingUser = await prisma.user.findUnique({ where: { email } });

    if (existingUser) {
      if (!existingUser.emailVerifiedAt) {
        const { token } = await issueEmailVerificationToken(existingUser.id);
        const sendResult = await sendEmailVerificationLink(request, email, token);

        const verifyParams: Record<string, string> = {
          email,
          sent: sendResult.sent ? "1" : "0",
          unverified: "1",
        };

        if (!sendResult.sent) {
          verifyParams.error = "email_delivery_failed";
        }

        return redirectTo(request, "/verify", verifyParams);
      }

      return redirectTo(request, "/register", { error: "email_in_use" });
    }

    const passwordHash = await hashPassword(password);

    const user = await prisma.user.create({
      data: {
        name: name || null,
        email,
        passwordHash,
        role: isConfiguredAdminEmail(email) ? UserRole.ADMIN : UserRole.USER,
      },
    });

    const { token } = await issueEmailVerificationToken(user.id);
    const sendResult = await sendEmailVerificationLink(request, email, token);

    const verifyParams: Record<string, string> = {
      email,
      sent: sendResult.sent ? "1" : "0",
    };

    if (!sendResult.sent) {
      verifyParams.error = "email_delivery_failed";
    }

    return redirectTo(request, "/verify", verifyParams);
  } catch {
    return redirectTo(request, "/register", { error: "server_error" });
  }
}
