import { NextResponse } from "next/server";
import { randomUUID } from "crypto";
import { query, queryOne } from "@/lib/db-postgres";
import { ensureWorkspaceForUser } from "@/lib/workspaces";
import {
  hashPassword,
  createDbSession,
  SESSION_COOKIE_NAME,
  sessionCookieOptions,
} from "@/lib/auth/password";

// POST /api/auth/register  { email, password, name? }
// Creates an email/password account: a NextAuth `users` row, the custom
// `fs_users` row (with the scrypt password hash + workspace metadata, mirroring
// the Google signIn callback), a Vibn workspace, and a database session — then
// sets the session cookie so the user is signed in immediately.
export async function POST(request: Request) {
  let body: { email?: unknown; password?: unknown; name?: unknown };
  try {
    body = await request.json();
  } catch {
    return NextResponse.json(
      { error: "Invalid request body." },
      { status: 400 },
    );
  }

  const email = String(body.email ?? "")
    .trim()
    .toLowerCase();
  const password = String(body.password ?? "");
  const name = body.name ? String(body.name).trim() : "";

  if (!name) {
    return NextResponse.json(
      { error: "Enter your name to set up your workspace." },
      { status: 400 },
    );
  }
  if (!/^\S+@\S+\.\S+$/.test(email)) {
    return NextResponse.json(
      { error: "Enter a valid email address." },
      { status: 400 },
    );
  }
  if (password.length < 8) {
    return NextResponse.json(
      { error: "Password must be at least 8 characters." },
      { status: 400 },
    );
  }

  try {
    const existing = await queryOne<{ id: string }>(
      `SELECT id FROM users WHERE lower(email) = $1 LIMIT 1`,
      [email],
    );
    if (existing) {
      return NextResponse.json(
        { error: "An account with this email already exists. Try signing in." },
        { status: 409 },
      );
    }

    // 1. NextAuth user row (id is normally a cuid; any unique string works).
    const userId = randomUUID();
    await query(
      `INSERT INTO users (id, name, email, email_verified)
       VALUES ($1, $2, $3, NOW())`,
      [userId, name, email],
    );

    // 2. Custom fs_users row — same shape the Google signIn callback writes,
    //    plus the password hash.
    const workspace =
      email.split("@")[0].replace(/[^a-z0-9]+/g, "-") + "-account";
    const passwordHash = await hashPassword(password);
    const data = JSON.stringify({
      email,
      name,
      image: null,
      workspace,
      passwordHash,
    });
    const fsRows = await query<{ id: string }>(
      `INSERT INTO fs_users (id, user_id, data)
       VALUES (gen_random_uuid()::text, $1, $2::jsonb)
       RETURNING id`,
      [userId, data],
    );
    const fsUserId = fsRows[0].id;

    // 3. Ensure a Vibn workspace (no Coolify/Gitea provisioning yet — happens
    //    lazily on first project create, same as the OAuth path).
    try {
      await ensureWorkspaceForUser({
        userId: fsUserId,
        email,
        displayName: name,
      });
    } catch (wsErr) {
      console.error("[register] ensureWorkspaceForUser failed:", wsErr);
    }

    // 4. Sign them in: create a DB session + set the cookie.
    const { token, expires } = await createDbSession(userId);
    const res = NextResponse.json({ ok: true });
    res.cookies.set(SESSION_COOKIE_NAME, token, sessionCookieOptions(expires));
    return res;
  } catch (err) {
    console.error("[register] exception:", err);
    return NextResponse.json(
      { error: "Could not create your account. Please try again." },
      { status: 500 },
    );
  }
}
