/**
 * Mark Booking as Paid API
 * POST /api/bookings/[id]/mark-paid
 *
 * Manually marks a booking deposit as paid.
 * Useful for:
 * - Cash/bank transfer payments
 * - Manual reconciliation
 * - Testing in development (when Stripe webhooks aren't active)
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/db";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import { logger } from "@/lib/logger";
import { markBookingPaidSchema } from "@/lib/validators/api-schemas";

export const dynamic = "force-dynamic";

interface RouteParams {
  params: Promise<{ id: string }>;
}

export async function POST(request: NextRequest, { params }: RouteParams) {
  try {
    const { id: bookingId } = await params;

    // Authenticate user
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      logger.warn("Unauthorized mark-paid attempt");
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // Get user
    const user = await prisma.users.findUnique({
      where: { email: userEmail },
      select: { id: true },
    });

    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    // Get effective owner ID (for org members, this returns the org owner's ID)
    // This allows staff to mark payments for organization bookings
    const effectiveUserId = await getEffectiveOwnerId(user.id);

    // Verify booking belongs to user or their organization
    const booking = await prisma.bookings.findFirst({
      where: {
        id: bookingId,
        userId: effectiveUserId,
      },
    });

    if (!booking) {
      return NextResponse.json(
        { success: false, error: "Booking not found" },
        { status: 404 },
      );
    }

    // Check if already paid
    if (booking.depositPaid) {
      return NextResponse.json({
        success: true,
        message: "Booking already marked as paid",
        booking,
      });
    }

    // Parse optional payment details from request body
    let paymentMethod = "manual";
    let paymentNote = "";
    try {
      const body = await request.json();
      const parsed = markBookingPaidSchema.safeParse(body);
      if (parsed.success) {
        paymentMethod = parsed.data.paymentMethod;
        paymentNote = parsed.data.note;
      }
    } catch {
      // No body provided, use defaults
    }

    // Update booking as paid
    const updatedBooking = await prisma.bookings.update({
      where: { id: bookingId },
      data: {
        depositPaid: true,
        depositPaidAt: new Date(),
        depositPaymentId: `manual_${Date.now()}`,
        status: "confirmed",
        notes: booking.notes
          ? `${booking.notes}\n[Manual payment: ${paymentMethod}${paymentNote ? ` - ${paymentNote}` : ""}]`
          : `[Manual payment: ${paymentMethod}${paymentNote ? ` - ${paymentNote}` : ""}]`,
        updatedAt: new Date(),
      },
    });

    logger.info("Booking manually marked as paid", {
      bookingId,
      userEmail,
      paymentMethod,
    });

    return NextResponse.json({
      success: true,
      message: "Booking marked as paid",
      booking: updatedBooking,
    });
  } catch (error) {
    logger.error("Failed to mark booking as paid", {
      error: error instanceof Error ? error.message : "Unknown error",
    });

    return NextResponse.json(
      { success: false, error: "Failed to mark booking as paid" },
      { status: 500 },
    );
  }
}
