import { NextRequest, NextResponse } from "next/server";
import { authSession } from "@/lib/auth/session-server";
import { query } from "@/lib/db-postgres";

const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333";

// ---------------------------------------------------------------------------
// GET — return saved architecture (if it exists)
// ---------------------------------------------------------------------------

export async function GET(
  _req: NextRequest,
  { params }: { params: Promise<{ projectId: string }> }
) {
  const session = await authSession();
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { projectId } = await params;

  try {
    const rows = await query<{ data: any }>(
      `SELECT data FROM fs_projects WHERE id = $1 LIMIT 1`,
      [projectId]
    );
    const data = rows[0]?.data ?? {};
    return NextResponse.json({
      architecture: data.architecture ?? null,
      prd: data.prd ?? null,
    });
  } catch {
    return NextResponse.json({ architecture: null, prd: null });
  }
}

// ---------------------------------------------------------------------------
// POST — generate architecture recommendation from PRD using AI
// ---------------------------------------------------------------------------

export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ projectId: string }> }
) {
  const session = await authSession();
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { projectId } = await params;
  const body = await req.json().catch(() => ({}));
  const forceRegenerate = body.forceRegenerate === true;

  // Load project PRD + phases
  let prd: string | null = null;
  let phases: any[] = [];

  try {
    const rows = await query<{ data: any }>(
      `SELECT data FROM fs_projects WHERE id = $1 LIMIT 1`,
      [projectId]
    );
    const data = rows[0]?.data ?? {};
    prd = data.prd ?? null;

    // Return cached architecture if it exists and not forcing regenerate
    if (data.architecture && !forceRegenerate) {
      return NextResponse.json({ architecture: data.architecture, cached: true });
    }
  } catch {
    return NextResponse.json({ error: "Project not found" }, { status: 404 });
  }

  if (!prd) {
    return NextResponse.json({ error: "No PRD found — complete discovery first" }, { status: 400 });
  }

  try {
    const phaseRows = await query<{ phase: string; title: string; summary: string; data: any }>(
      `SELECT phase, title, summary, data FROM atlas_phases WHERE project_id = $1 ORDER BY saved_at ASC`,
      [projectId]
    );
    phases = phaseRows;
  } catch { /* phases optional */ }

  // Build a concise context string from phases
  const phaseContext = phases.map(p =>
    `## ${p.title}\n${p.summary}\n${JSON.stringify(p.data, null, 2)}`
  ).join("\n\n");

  const prompt = `You are a senior software architect. Analyse the following Product Requirements Document and recommend a technical architecture for a Turborepo monorepo.

Return ONLY a valid JSON object (no markdown, no explanation) with this exact structure:
{
  "productName": "string",
  "productType": "string (e.g. PWA Game, SaaS, Marketplace, Internal Tool)",
  "summary": "2-3 sentence plain-English summary of the recommended architecture",
  "apps": [
    {
      "name": "string (e.g. web, api, simulator)",
      "type": "string (e.g. Next.js 15, Express API, Node.js service)",
      "description": "string — what this app does",
      "tech": ["string array of key technologies"],
      "screens": ["string array — key screens/routes if applicable, else empty"]
    }
  ],
  "packages": [
    {
      "name": "string (e.g. db, types, ui)",
      "description": "string — what this shared package contains"
    }
  ],
  "infrastructure": [
    {
      "name": "string (e.g. PostgreSQL, Redis, Background Jobs)",
      "reason": "string — why this is needed based on the PRD"
    }
  ],
  "integrations": [
    {
      "name": "string (e.g. Ad Network SDK)",
      "required": true,
      "notes": "string"
    }
  ],
  "designSurfaces": ["string array — e.g. Web App, Mobile PWA, Admin"],
  "riskNotes": ["string array — 1-2 key architectural risks from the PRD"]
}

Be specific to this product. Do not use generic boilerplate — base your decisions on the PRD content.

--- DISCOVERY PHASES ---
${phaseContext}

--- PRD ---
${prd}`;

  try {
    const res = await fetch(`${AGENT_RUNNER_URL}/generate`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ prompt }),
      signal: AbortSignal.timeout(120_000),
    });

    if (!res.ok) {
      throw new Error(`Agent runner responded ${res.status}`);
    }

    const data = await res.json();
    const raw = data.reply ?? "";

    // Extract JSON from response (strip any accidental markdown)
    const jsonMatch = raw.match(/\{[\s\S]*\}/);
    if (!jsonMatch) throw new Error("No JSON in response");

    const architecture = JSON.parse(jsonMatch[0]);

    // Persist to project data
    await query(
      `UPDATE fs_projects
         SET data = jsonb_set(COALESCE(data, '{}'::jsonb), '{architecture}', $2::jsonb, true),
             updated_at = NOW()
       WHERE id = $1`,
      [projectId, JSON.stringify(architecture)]
    );

    return NextResponse.json({ architecture, cached: false });
  } catch (err) {
    console.error("[architecture] Generation failed:", err);
    return NextResponse.json(
      { error: "Architecture generation failed. Please try again." },
      { status: 500 }
    );
  }
}

// ---------------------------------------------------------------------------
// PATCH — confirm architecture (sets architectureConfirmed flag)
// ---------------------------------------------------------------------------

export async function PATCH(
  _req: NextRequest,
  { params }: { params: Promise<{ projectId: string }> }
) {
  const session = await authSession();
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { projectId } = await params;

  try {
    await query(
      `UPDATE fs_projects
         SET data = jsonb_set(COALESCE(data, '{}'::jsonb), '{architectureConfirmed}', 'true'::jsonb, true),
             updated_at = NOW()
       WHERE id = $1`,
      [projectId]
    );
    return NextResponse.json({ confirmed: true });
  } catch {
    return NextResponse.json({ error: "Failed to confirm" }, { status: 500 });
  }
}
