import { NextRequest, NextResponse } from "next/server";
import bcrypt from "bcryptjs";
import crypto from "crypto";
import { db } from "@/lib/db";
import { sendVerificationEmail } from "@/lib/email/send";
import { checkRateLimit, getClientIp, AUTH_RATE_LIMITS } from "@/lib/rate-limit";
import { logger } from "@/lib/logger";

export async function POST(req: NextRequest) {
  try {
    // Rate limit
    const ip = getClientIp(req.headers);
    const limit = checkRateLimit(`register:${ip}`, AUTH_RATE_LIMITS.register);
    if (!limit.allowed) {
      return NextResponse.json(
        { error: "Too many registration attempts. Please try again later." },
        { status: 429, headers: { "Retry-After": String(Math.ceil((limit.resetAt - Date.now()) / 1000)) } }
      );
    }

    // Signup allowlist — if ALLOWED_SIGNUP_EMAILS is set, only those emails can register
    const allowedEmails = process.env.ALLOWED_SIGNUP_EMAILS;

    const body = await req.json();
    const { password, name } = body;
    const email = (body.email as string)?.toLowerCase().trim();

    if (allowedEmails) {
      const allowlist = allowedEmails.split(",").map((e) => e.trim().toLowerCase());
      if (!allowlist.includes(email)) {
        logger.info({ email_domain: email.split("@")[1], action: "register_blocked" }, "Signup blocked by allowlist");
        return NextResponse.json(
          { error: "Signups are currently closed. Please check back later." },
          { status: 403 }
        );
      }
    }

    // Validate required fields
    if (!email || !password || !name) {
      return NextResponse.json(
        { error: "Email, password, and name are required" },
        { status: 400 }
      );
    }

    // Validate email format
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      return NextResponse.json(
        { error: "Invalid email format" },
        { status: 400 }
      );
    }

    // Validate password length
    if (password.length < 8) {
      return NextResponse.json(
        { error: "Password must be at least 8 characters" },
        { status: 400 }
      );
    }

    // Check if user already exists — return generic error to prevent enumeration
    const existingUser = await db.user.findUnique({
      where: { email },
    });

    if (existingUser) {
      return NextResponse.json(
        { error: "Unable to create account. Please try a different email or sign in." },
        { status: 400 }
      );
    }

    // Hash password
    const passwordHash = await bcrypt.hash(password, 12);

    // Create user
    const user = await db.user.create({
      data: {
        email,
        name,
        passwordHash,
      },
      select: {
        id: true,
        email: true,
        name: true,
        plan: true,
        createdAt: true,
      },
    });

    // Create verification token
    const token = crypto.randomBytes(32).toString("hex");
    const expires = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours

    await db.verificationToken.create({
      data: {
        identifier: email,
        token,
        expires,
      },
    });

    // Send verification email
    const verifyUrl = `${process.env.NEXTAUTH_URL || "http://localhost:3000"}/auth/verify-email?token=${token}&email=${encodeURIComponent(email)}`;

    try {
      await sendVerificationEmail({
        email,
        url: verifyUrl,
        expires,
      });
    } catch (emailError) {
      logger.error({ err: emailError, action: 'send_verification_email' }, 'Failed to send verification email');
    }

    return NextResponse.json(
      {
        message: "Account created successfully. Please check your email to verify your account.",
        requiresVerification: true,
        user,
      },
      { status: 201 }
    );
  } catch {
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}
