/**
 * POST /api/projects/[projectId]/dev-server/ensure
 *
 * Lightweight endpoint called by the preview pane when it loads and finds
 * no running dev server. Checks for a previous server config and restarts
 * it in the background, returning immediately so the UI isn't blocked.
 *
 * Response shapes:
 *   { status: 'running',    previewUrl }   — already up, nothing to do
 *   { status: 'starting',   previewUrl }   — was down, restart fired
 *   { status: 'no_history'              }  — never started before, AI needs to do it
 *   { status: 'no_container'            }  — dev container doesn't exist yet
 */

import { NextResponse } from "next/server";
import { authSession } from "@/lib/auth/session-server";
import { query, queryOne } from "@/lib/db-postgres";
import { getWorkspaceById } from "@/lib/workspaces";
import {
  ensureDevContainer,
  startDevServer,
  probeDevServerReadiness,
} from "@/lib/dev-container";

export async function POST(
  request: Request,
  { params }: { params: Promise<{ projectId: string }> },
) {
  const { projectId } = await params;

  const session = await authSession();
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  // Load project — verify ownership
  const projectRows = await query<{
    id: string;
    vibn_workspace_id: string | null;
    data: Record<string, unknown>;
  }>(
    `SELECT p.id, p.vibn_workspace_id, p.data
       FROM fs_projects p
       JOIN fs_users u ON u.id = p.user_id
      WHERE p.id = $1 AND u.data->>'email' = $2
      LIMIT 1`,
    [projectId, session.user.email],
  );

  if (projectRows.length === 0) {
    return NextResponse.json({ error: "Project not found" }, { status: 404 });
  }

  const project = projectRows[0];
  const projectSlug = (project.data?.slug as string) || project.id;
  const projectName = (project.data?.name as string) || "Project";

  // 1. Is a dev server already running or starting on the primary port?
  const running = await queryOne<{
    id: string;
    state: string;
    preview_url: string;
    command: string;
    port: number;
  }>(
    `SELECT id, state, preview_url, command, port
       FROM fs_dev_servers
      WHERE project_id = $1
        AND port = 3000
        AND (
          state = 'running' OR
          (state = 'starting' AND started_at > NOW() - INTERVAL '15 minutes')
        )
      ORDER BY started_at DESC LIMIT 1`,
    [projectId],
  );

  if (running) {
    return NextResponse.json({
      status: running.state === "running" ? "running" : "starting",
      previewUrl: running.preview_url,
      command: running.command,
      port: running.port,
    });
  }

  // 2. Do we have a previous config to restart from?
  //    (Limit to port 3000 since that's what the preview pane embeds)
  const last = await queryOne<{
    command: string;
    port: number;
    preview_url: string;
  }>(
    `SELECT command, port, preview_url
       FROM fs_dev_servers
      WHERE project_id = $1 AND port = 3000
      ORDER BY started_at DESC LIMIT 1`,
    [projectId],
  );

  const forceStart =
    new URL(request.url).searchParams.get("forceStart") === "true";

  // If there's no history, we STILL want to auto-start! We just assume it's a standard
  // Next.js app on port 3000. Forcing the user to hit "Start Preview" on a new project
  // is unnecessary friction.
  const commandToRun = last?.command || "npx next dev -H 0.0.0.0 --webpack";
  const portToRun = last?.port || 3000;
  const previewUrlToUse = last?.preview_url ?? null;

  // 3. Load workspace
  if (!project.vibn_workspace_id) {
    return NextResponse.json({ status: "no_container" });
  }

  const workspace = await getWorkspaceById(project.vibn_workspace_id);
  if (!workspace) {
    return NextResponse.json({ status: "no_container" });
  }

  // 4. Fire restart in background — don't block the response.
  const restartOpts = {
    projectId: project.id,
    projectSlug,
    command: commandToRun,
    port: portToRun,
    workspace,
  };

  void (async () => {
    try {
      await ensureDevContainer({
        projectId: project.id,
        projectSlug,
        projectName,
        workspace,
      });
      const row = await startDevServer(restartOpts);

      // We immediately set it to running instead of waiting for the probe.
      // The probe has been flaky on Webpack cold compiles and causing the
      // frontend to get stuck in a "Preview not running" loop.
      await query(`UPDATE fs_dev_servers SET state = 'running' WHERE id = $1`, [
        row.id,
      ]);

      // Still run the probe in the background just to log any catastrophic failures,
      // but the UI won't be blocked by it.
      probeDevServerReadiness(project.id, row.id, row.port).catch((err) => {
        console.error("[dev-server/ensure] probe failed:", err?.message);
      });
    } catch (err) {
      console.error("[dev-server/ensure] restart failed:", err);
    }
  })();

  return NextResponse.json({
    status: "starting",
    previewUrl: previewUrlToUse,
    command: restartOpts.command,
    port: restartOpts.port,
  });
}
