/**
 * 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 { 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 project = await queryOne<{
    id: string;
    slug: string;
    name: string;
    vibn_workspace_id: string | null;
    data: Record<string, unknown>;
  }>(
    `SELECT p.id, p.slug, p.name, 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 (!project) {
    return NextResponse.json({ error: "Project not found" }, { status: 404 });
  }

  // 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 (!last && !forceStart) {
    return NextResponse.json({ status: "no_history" });
  }

  // 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.
  //    If forceStart is true but we have no history, default to Next.js start command.
  const restartOpts = {
    projectId: project.id,
    projectSlug: project.slug,
    command: last?.command || "next dev -H 0.0.0.0 --no-turbopack",
    port: last?.port || 3000,
    workspace,
  };

  void (async () => {
    try {
      await ensureDevContainer({
        projectId: project.id,
        projectSlug: project.slug,
        projectName: project.name,
        workspace,
      });
      const row = await startDevServer(restartOpts);
      // Run the readiness probe in background so state transitions
      // from 'starting' → 'running' (or 'failed') in the DB.
      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: last.preview_url,
    command: last.command,
    port: last.port,
  });
}
