/**
 * GET /api/cron/competitor-discovery-queue
 * ─────────────────────────────────────────
 * Processes one pending CompetitorDiscoveryJob location per tick.
 * Runs every minute via Vercel Cron so a 14-location brand completes
 * in ~14 minutes rather than timing out a single sync request.
 *
 * Processing order: oldest job first (createdAt asc), then next
 * unprocessed location index within that job.
 *
 * Auth: Authorization: Bearer ${CRON_SECRET} or ?secret=<secret>.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { discoverCompetitors } from "@/lib/services/competitor-discovery";

export const dynamic = "force-dynamic";
export const maxDuration = 180;

const CRON_SECRET = process.env.CRON_SECRET ?? "";

function authOk(req: Request): boolean {
  if (!CRON_SECRET) return false;
  const header = req.headers.get("authorization") ?? "";
  if (header === `Bearer ${CRON_SECRET}`) return true;
  const url = new URL(req.url);
  return url.searchParams.get("secret") === CRON_SECRET;
}

export async function GET(req: Request) {
  if (!authOk(req)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  // Pick the oldest pending-or-running job.
  const job = await prisma.competitorDiscoveryJob.findFirst({
    where: { status: { in: ["pending", "running"] } },
    orderBy: { createdAt: "asc" },
  });

  if (!job) {
    return NextResponse.json({ message: "No pending jobs" });
  }

  const locations = job.locations as string[];

  // All locations already processed → mark complete.
  if (job.processedLocations >= locations.length) {
    await prisma.competitorDiscoveryJob.update({
      where: { id: job.id },
      data: { status: "completed", completedAt: new Date() },
    });
    return NextResponse.json({ message: "Job completed", jobId: job.id });
  }

  // First tick for this job → mark running.
  if (job.status === "pending") {
    await prisma.competitorDiscoveryJob.update({
      where: { id: job.id },
      data: { status: "running", startedAt: new Date() },
    });
  }

  const nextIndex = job.processedLocations;
  const location = locations[nextIndex];

  try {
    const result = await discoverCompetitors(job.brandId, {
      focus: job.focus as "local" | "national",
      locations: [location],
      limit: job.limit,
    });

    await prisma.competitorDiscoveryJob.update({
      where: { id: job.id },
      data: {
        processedLocations: nextIndex + 1,
        competitorsFound: { increment: result.candidates.length },
        // Mark completed if this was the last location.
        ...(nextIndex + 1 >= locations.length
          ? { status: "completed", completedAt: new Date() }
          : {}),
      },
    });

    return NextResponse.json({
      message: "Location processed",
      jobId: job.id,
      location,
      found: result.candidates.length,
      processedLocations: nextIndex + 1,
      totalLocations: locations.length,
    });
  } catch (err) {
    const error = err instanceof Error ? err.message : String(err);
    await prisma.competitorDiscoveryJob.update({
      where: { id: job.id },
      data: { status: "failed", error },
    });
    console.error("[competitor-discovery-queue] Job failed", { jobId: job.id, location, error });
    return NextResponse.json({ error: "Job failed", jobId: job.id }, { status: 500 });
  }
}
