import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { stripe } from "@/lib/stripe";
import { logger } from "@/lib/logger";
import {
  getPendingPayout,
  markEventsPaidOut,
  MIN_PAYOUT_CENTS,
} from "@/lib/marketplace-billing";

/**
 * POST /api/stripe/connect/payout
 *
 * Triggers a Stripe Transfer from the platform account to the operator's
 * Connect Express account for all unpaid MarketplaceBillingEvent records.
 *
 * Requirements:
 *   - Authenticated user with a completed Stripe Connect account
 *   - Minimum pending balance of $1.00 (100 cents)
 */
export async function POST() {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    if (!stripe) {
      return NextResponse.json(
        { error: "Stripe is not configured" },
        { status: 503 },
      );
    }

    // Verify user has a completed Connect account
    const user = await db.user.findUnique({
      where: { id: session.user.id },
      select: {
        id: true,
        stripeConnectAccountId: true,
        stripeConnectOnboardingComplete: true,
      },
    });

    if (!user?.stripeConnectAccountId) {
      return NextResponse.json(
        { error: "No Stripe Connect account linked. Complete onboarding first." },
        { status: 400 },
      );
    }

    if (!user.stripeConnectOnboardingComplete) {
      return NextResponse.json(
        { error: "Stripe Connect onboarding is not complete." },
        { status: 400 },
      );
    }

    // Get pending payout amount
    const pending = await getPendingPayout(session.user.id);

    if (pending.pendingCents < MIN_PAYOUT_CENTS) {
      return NextResponse.json(
        {
          error: `Minimum payout is $${(MIN_PAYOUT_CENTS / 100).toFixed(2)}. Current pending: $${(pending.pendingCents / 100).toFixed(2)}.`,
          pendingCents: pending.pendingCents,
          minimumCents: MIN_PAYOUT_CENTS,
        },
        { status: 400 },
      );
    }

    // Create Stripe Transfer from platform to connected account
    const transfer = await stripe.transfers.create({
      amount: pending.pendingCents,
      currency: "usd",
      destination: user.stripeConnectAccountId,
      metadata: {
        userId: session.user.id,
        eventCount: String(pending.eventCount),
      },
    });

    // Mark billing events as paid out
    const markedCount = await markEventsPaidOut(
      pending.eventIds,
      transfer.id,
    );

    logger.info(
      {
        action: "stripe_connect_payout",
        userId: session.user.id,
        transferId: transfer.id,
        amountCents: pending.pendingCents,
        eventCount: markedCount,
      },
      "Payout transfer created for operator",
    );

    return NextResponse.json({
      transferId: transfer.id,
      amountCents: pending.pendingCents,
      amountDollars: pending.pendingCents / 100,
      eventCount: markedCount,
    });
  } catch (error) {
    logger.error(
      { err: error, action: "stripe_connect_payout" },
      "Failed to create payout transfer",
    );
    return NextResponse.json(
      { error: "Failed to create payout" },
      { status: 500 },
    );
  }
}
