import { NextResponse } from "next/server";
import { authSession } from "../../../lib/auth/session-server";
import { query, queryOne } from "../../../lib/db-postgres";
import {
  ensureWorkspaceProvisioned,
  getWorkspaceByOwner,
  type VibnWorkspace,
} from "../../../lib/workspaces";

// URL-safe, unique slug from a name. Optionally exclude a workspace id so a
// workspace can keep/rename to a slug it already owns.
async function generateUniqueSlug(
  name: string,
  excludeWorkspaceId?: string,
): Promise<string> {
  const base =
    name
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, "-")
      .replace(/^-+|-+$/g, "") || "workspace";

  let slug = base;
  let count = 0;
  while (true) {
    const existing = excludeWorkspaceId
      ? await queryOne(
          "SELECT id FROM vibn_workspaces WHERE slug = $1 AND id <> $2 LIMIT 1",
          [slug, excludeWorkspaceId],
        )
      : await queryOne(
          "SELECT id FROM vibn_workspaces WHERE slug = $1 LIMIT 1",
          [slug],
        );
    if (!existing) return slug;
    count++;
    slug = `${base}-${count}`;
  }
}

// POST /api/onboarding
// Finalises onboarding. Every signed-in user already has a workspace (created
// lazily at sign-in by ensureWorkspaceForUser), so this RENAMES that workspace
// to the name chosen in onboarding rather than creating a second one. Onboarding
// answers are stashed on the user's fs_users row. Returns the workspace slug so
// the client can redirect straight into it.
export async function POST(request: Request) {
  const session = await authSession();
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const payload = await request.json();
    const { isAgency, profile, expertise, tools, data, workspaceName } =
      payload;

    // 1. Resolve the user (fs_users.id is the workspace owner id).
    const userRow = await queryOne<{ id: string }>(
      "SELECT id FROM fs_users WHERE data->>'email' = $1 LIMIT 1",
      [session.user.email],
    );
    if (!userRow) {
      return NextResponse.json({ error: "User not found" }, { status: 404 });
    }
    const userId = userRow.id;

    // 2. Determine the workspace name. An explicit name from the
    //    "Name your workspace" step wins; otherwise fall back to what the flow
    //    already collected.
    const explicitName =
      typeof workspaceName === "string" ? workspaceName.trim() : "";
    const businessName =
      explicitName ||
      (isAgency ? profile?.name : data?.bizName) ||
      "My Workspace";

    // 3. Stash onboarding answers on the user (vibn_workspaces has no `data`
    //    column; fs_users does). Non-fatal.
    // Persist EVERYTHING the flow collected (the full raw payload), not a
    // curated subset, so nothing the user chose is lost.
    const onboardingMetadata = {
      isAgency: !!isAgency,
      workspaceName: businessName,
      completedAt: new Date().toISOString(),
      ...(isAgency
        ? {
            profile: profile ?? null,
            expertise: expertise ?? null,
            tools: tools ?? null,
          }
        : { data: data ?? null }),
    };
    try {
      await query(
        "UPDATE fs_users SET data = data || $2::jsonb, updated_at = NOW() WHERE id = $1",
        [
          userId,
          JSON.stringify({
            onboardingComplete: true,
            onboarding: onboardingMetadata,
          }),
        ],
      );
    } catch (metaErr) {
      console.error("Onboarding metadata save failed (non-fatal):", metaErr);
    }

    // 4. Rename the user's existing workspace, or create one if (unexpectedly)
    //    none exists yet.
    let workspace: VibnWorkspace | undefined;
    const existing = await getWorkspaceByOwner(userId);

    if (existing) {
      const slug = await generateUniqueSlug(businessName, existing.id);
      const rows = await query<VibnWorkspace>(
        `UPDATE vibn_workspaces
         SET name = $2, slug = $3, updated_at = NOW()
         WHERE id = $1
         RETURNING *`,
        [existing.id, businessName, slug],
      );
      workspace = rows[0];
    } else {
      const slug = await generateUniqueSlug(businessName);
      const rows = await query<VibnWorkspace>(
        `INSERT INTO vibn_workspaces (slug, name, owner_user_id)
         VALUES ($1, $2, $3)
         RETURNING *`,
        [slug, businessName, userId],
      );
      workspace = rows[0];
      await query(
        `INSERT INTO vibn_workspace_members (workspace_id, user_id, role)
         VALUES ($1, $2, 'owner')
         ON CONFLICT (workspace_id, user_id) DO NOTHING`,
        [workspace.id, userId],
      );
    }

    if (!workspace) {
      return NextResponse.json(
        { error: "Failed to create workspace" },
        { status: 500 },
      );
    }

    // 5. Kick off provisioning in the background (Coolify project + Gitea org).
    try {
      ensureWorkspaceProvisioned(workspace).catch((err: unknown) => {
        console.error("Background workspace provisioning failed:", err);
      });
    } catch (e) {
      console.error("Failed to kick off provisioning:", e);
    }

    return NextResponse.json({ success: true, slug: workspace.slug });
  } catch (err) {
    console.error("Onboarding GTM save exception:", err);
    return NextResponse.json(
      { error: "Internal GTM server error" },
      { status: 500 },
    );
  }
}
