import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { pushCardToMonday } from "@/lib/integrations";
import { createNotification } from "@/lib/notifications";
import { requireApiAuth, handleApiError } from "@/lib/api-auth";

export async function POST(req: NextRequest) {
  try {
    await requireApiAuth();
    const settings = await prisma.appSettings.findUnique({
      where: { id: "singleton" },
    });
    if (!settings?.mondayEnabled || !settings?.mondayApiToken || !settings?.mondayBoardId) {
      return NextResponse.json(
        { error: "Monday.com integration is not configured or enabled" },
        { status: 400 }
      );
    }

    const body = await req.json().catch(() => ({}));
    const mode: "push" | "update" | "all" = body.mode || "all";
    const cardIds: string[] | undefined = body.cardIds;

    const where: Record<string, unknown> = { ocrStatus: "complete" };
    if (mode === "push") where.mondayItemId = null;
    else if (mode === "update") where.mondayItemId = { not: null };
    if (cardIds?.length) where.id = { in: cardIds };

    const cards = await prisma.responseCard.findMany({
      where,
      select: { id: true, name: true, mondayItemId: true },
    });

    if (cards.length === 0) {
      const label = mode === "push" ? "push" : mode === "update" ? "update" : "sync";
      return NextResponse.json({ ok: true, synced: 0, failed: 0, created: 0, updated: 0, message: `No cards to ${label}` });
    }

    let created = 0;
    let updated = 0;
    let failed = 0;
    const errors: string[] = [];

    const BATCH_SIZE = 5;
    const BATCH_DELAY_MS = 1000;

    for (let i = 0; i < cards.length; i += BATCH_SIZE) {
      const batch = cards.slice(i, i + BATCH_SIZE);
      const results = await Promise.allSettled(
        batch.map((card) => pushCardToMonday(card.id, settings))
      );

      for (let j = 0; j < results.length; j++) {
        const result = results[j];
        if (result.status === "fulfilled") {
          if (result.value.action === "created") created++;
          else updated++;
        } else {
          failed++;
          const msg = result.reason instanceof Error ? result.reason.message : "Unknown error";
          errors.push(`${batch[j].name || batch[j].id}: ${msg}`);
          console.error(`[sync-all] Failed to sync card ${batch[j].id}:`, result.reason);
        }
      }

      if (i + BATCH_SIZE < cards.length) {
        await new Promise((r) => setTimeout(r, BATCH_DELAY_MS));
      }
    }

    const synced = created + updated;
    const parts: string[] = [];
    if (created > 0) parts.push(`${created} pushed`);
    if (updated > 0) parts.push(`${updated} updated`);
    if (failed > 0) parts.push(`${failed} failed`);

    await createNotification({
      type: failed > 0 ? "monday_error" : "monday_sync",
      title: "Monday.com Sync Complete",
      message: parts.join(", "),
    });

    return NextResponse.json({ ok: true, synced, created, updated, failed, total: cards.length, errors: errors.slice(0, 10) });
  } catch (error) {
    return handleApiError(error);
  }
}
