import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { getProvider } from "@/lib/integrations/registry";
import { flattenCardFieldData } from "@/lib/integrations";
import type { CardData } from "@/lib/integrations/types";
import {
  requireApiAuthWithPermission,
  handleApiError,
} from "@/lib/api-auth";

export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await requireApiAuthWithPermission("integrations.manage");

    const { id } = await params;
    const integration = await prisma.integration.findFirst({
      where: { id, organizationId: session.user.orgId },
    });

    if (!integration) {
      return NextResponse.json(
        { error: "Integration not found" },
        { status: 404 }
      );
    }

    const provider = getProvider(integration.provider);
    if (!provider) {
      return NextResponse.json(
        { error: "Unknown provider" },
        { status: 400 }
      );
    }

    const body = await req.json().catch(() => ({}));
    const cardIds = body.cardIds as string[] | undefined;

    const where: Record<string, unknown> = {
      organizationId: session.user.orgId,
    };
    if (cardIds?.length) {
      where.id = { in: cardIds };
    } else {
      where.reviewStatus = "reviewed";
    }

    const cards = await prisma.responseCard.findMany({
      where,
      take: 100,
    });

    let successCount = 0;
    let failCount = 0;

    const configWithId = {
      ...(integration.config as Record<string, unknown>),
      _integrationId: integration.id,
    };

    for (const card of cards) {
      const flat = flattenCardFieldData(card as unknown as Record<string, unknown>);
      const result = await provider.pushCard(
        flat as unknown as CardData,
        configWithId,
        integration.fieldMapping
      );
      if (result.success) {
        successCount++;
      } else {
        failCount++;
      }
    }

    await prisma.integration.update({
      where: { id },
      data: {
        lastSyncAt: new Date(),
        lastSyncStatus: failCount === 0 ? "success" : "partial",
      },
    });

    return NextResponse.json({
      synced: successCount,
      failed: failCount,
      total: cards.length,
    });
  } catch (error) {
    return handleApiError(error);
  }
}
