import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { AuthOptions } from "@/app/api/auth/[...nextauth]/authOptions";
import { z } from "zod";
import { triggerBulkDocumentDownload } from "@/lib/bulkDocumentDownload/server";

// The document service resolves the selection and creates its sub_task
// synchronously before returning 202, which can outrun the default function
// budget on large projects. Give the round-trip headroom so the browser gets
// our JSON (202 / mapped error) rather than a platform 504.
export const maxDuration = 60;

const scopeSchema = z.union([
  z.object({ kind: z.literal("project"), projectCode: z.string().min(1) }),
  z.object({
    kind: z.literal("all-projects"),
    projectCodes: z.array(z.string().min(1)),
  }),
]);

const bodySchema = z.object({
  scope: scopeSchema,
  includeAll: z.boolean(),
  landlordPropertyIds: z.array(z.string().min(1)).default([]),
});

function sessionToken(request: NextRequest): string | undefined {
  return (
    request.cookies.get("__Secure-next-auth.session-token")?.value ??
    request.cookies.get("next-auth.session-token")?.value
  );
}

// POST — record + dispatch a bulk document download (ADR-0008 convention)
export async function POST(
  request: 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;
  if (!/^\d+$/.test(portfolioId)) {
    return NextResponse.json({ error: "Invalid portfolio id" }, { status: 400 });
  }

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

  try {
    const outcome = await triggerBulkDocumentDownload({
      selection: {
        scope: body.scope,
        includeAll: body.includeAll,
        landlordPropertyIds: body.landlordPropertyIds,
        portfolioId: Number(portfolioId),
      },
      sessionToken: sessionToken(request),
    });
    switch (outcome.kind) {
      case "ok":
        return NextResponse.json({ taskId: outcome.taskId }, { status: 202 });
      case "invalid_selection":
        return NextResponse.json({ error: outcome.message }, { status: 400 });
      case "backend_error":
        // Pass the backend's status (400 over-cap / 409 already-started / 5xx)
        // and its detail message straight through.
        return NextResponse.json(
          { error: outcome.message },
          { status: outcome.status },
        );
    }
  } catch (err) {
    console.error("POST /bulk-document-download error:", err);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}
