import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { z } from "zod";
import { AuthOptions } from "@/app/api/auth/[...nextauth]/authOptions";
import { db } from "@/app/db/db";
import { portfolioCapabilities } from "@/app/db/schema/portfolio";
import { user } from "@/app/db/schema/users";
import { and, eq } from "drizzle-orm";
import { bulkApprove } from "@/app/lib/bulkApprove";

const bodySchema = z.object({
  changes: z
    .array(
      z.object({
        hubspotDealId: z.string().min(1),
        measureName: z.string().min(1),
        approved: z.boolean(),
      }),
    )
    .min(1, "changes must not be empty"),
});

/**
 * POST /api/portfolio/[portfolioId]/bulk-approvals
 *
 * Approver-only. Applies all approve/unapprove changes in a single atomic
 * DB transaction. If any change fails the entire batch is rolled back.
 *
 * Body: { changes: [{ hubspotDealId, measureName, approved }] }
 * Response: 200 { ok: true, hubspotSync: "ok" | "failed" } | 400/401/403
 */
export async function POST(
  req: NextRequest,
  props: { params: Promise<{ portfolioId: string }> },
) {
  const session = await getServerSession(AuthOptions);
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorised" }, { status: 401 });
  }

  const { portfolioId } = await props.params;

  const userRow = await db
    .select({ id: user.id })
    .from(user)
    .where(eq(user.email, session.user.email))
    .limit(1);

  if (!userRow[0]) {
    return NextResponse.json({ error: "User not found" }, { status: 404 });
  }

  const capabilityRows = await db
    .select({ capability: portfolioCapabilities.capability })
    .from(portfolioCapabilities)
    .where(
      and(
        eq(portfolioCapabilities.portfolioId, BigInt(portfolioId)),
        eq(portfolioCapabilities.userId, userRow[0].id),
      ),
    );

  if (!capabilityRows.some((r) => r.capability === "approver")) {
    return NextResponse.json({ error: "Approver capability required" }, { status: 403 });
  }

  let body: z.infer<typeof bodySchema>;
  try {
    body = bodySchema.parse(await req.json());
  } catch {
    return NextResponse.json({ error: "Invalid body" }, { status: 400 });
  }

  const result = await bulkApprove({
    changes: body.changes,
    userId: userRow[0].id,
    actedByEmail: session.user.email,
  });

  if (!result.ok) {
    return NextResponse.json({ ok: false, error: result.error }, { status: 400 });
  }

  return NextResponse.json({ ok: true, hubspotSync: result.hubspotSync, hubspotError: result.hubspotError });
}
