/**
 * POST /api/projects/[projectId]/agent/sessions/[sessionId]/approve
 *
 * Called by the frontend when the user clicks "Approve & commit".
 * Verifies ownership, then asks the agent runner to git commit + push
 * the changes it made in the workspace, and triggers a Coolify deploy.
 *
 * Body: { commitMessage: string }
 */
import { 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";
const COOLIFY_API_URL  = process.env.COOLIFY_API_URL  ?? "";
const COOLIFY_API_TOKEN = process.env.COOLIFY_API_TOKEN ?? "";

interface AppEntry {
  name: string;
  path: string;
  coolifyServiceUuid?: string | null;
  domain?: string | null;
}

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

    const body = await req.json() as { commitMessage?: string };
    const commitMessage = body.commitMessage?.trim();
    if (!commitMessage) {
      return NextResponse.json({ error: "commitMessage is required" }, { status: 400 });
    }

    // Verify ownership + fetch project data (giteaRepo, apps list)
    const rows = await query<{ data: Record<string, unknown> }>(
      `SELECT p.data FROM fs_projects p
       JOIN fs_users u ON u.id = p.user_id
       WHERE p.id::text = $1 AND u.data->>'email' = $2 LIMIT 1`,
      [projectId, session.user.email]
    );
    if (rows.length === 0) {
      return NextResponse.json({ error: "Project not found" }, { status: 404 });
    }

    const projectData = rows[0].data;
    const giteaRepo = projectData?.giteaRepo as string | undefined;
    if (!giteaRepo) {
      return NextResponse.json({ error: "No Gitea repo linked to this project" }, { status: 400 });
    }

    // Find the session to get the appName (so we can find the right Coolify UUID)
    const sessionRows = await query<{ app_name: string; status: string }>(
      `SELECT app_name, status FROM agent_sessions WHERE id = $1::uuid AND project_id::text = $2 LIMIT 1`,
      [sessionId, projectId]
    );
    if (sessionRows.length === 0) {
      return NextResponse.json({ error: "Session not found" }, { status: 404 });
    }
    if (sessionRows[0].status !== "done") {
      return NextResponse.json({ error: "Session must be in 'done' state to approve" }, { status: 400 });
    }

    const appName = sessionRows[0].app_name;

    // Find the matching Coolify UUID from project.data.apps[]
    const apps: AppEntry[] = (projectData?.apps ?? []) as AppEntry[];
    const matchedApp = apps.find(a => a.name === appName);
    const coolifyAppUuid = matchedApp?.coolifyServiceUuid ?? undefined;

    // Call agent runner to commit + push
    const approveRes = await fetch(`${AGENT_RUNNER_URL}/agent/approve`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        giteaRepo,
        commitMessage,
        coolifyApiUrl: COOLIFY_API_URL,
        coolifyApiToken: COOLIFY_API_TOKEN,
        coolifyAppUuid,
      }),
    });

    const approveData = await approveRes.json() as {
      ok: boolean;
      committed?: boolean;
      deployed?: boolean;
      message?: string;
      error?: string;
    };

    if (!approveRes.ok || !approveData.ok) {
      return NextResponse.json(
        { error: approveData.error ?? "Agent runner returned an error" },
        { status: 500 }
      );
    }

    // Mark session as approved in DB
    await query(
      `UPDATE agent_sessions
       SET status = 'approved', completed_at = COALESCE(completed_at, now()), updated_at = now(),
           output = output || $1::jsonb
       WHERE id = $2::uuid`,
      [
        JSON.stringify([{
          ts: new Date().toISOString(),
          type: "done",
          text: `✓ ${approveData.message ?? "Committed and pushed."}${approveData.deployed ? " Deployment triggered." : ""}`,
        }]),
        sessionId,
      ]
    );

    return NextResponse.json({
      ok: true,
      committed: approveData.committed,
      deployed: approveData.deployed,
      message: approveData.message,
    });
  } catch (err) {
    console.error("[agent/approve]", err);
    return NextResponse.json({ error: "Failed to approve session" }, { status: 500 });
  }
}
