/**
 * Update Booking Status API
 * PATCH /api/bookings/[id]/status
 *
 * Updates the status of a booking (pending, confirmed, completed, cancelled, no_show)
 */

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 { withCSRF } from "@/lib/csrf";
import type { Id } from "@/convex/_generated/dataModel";
import { convexMutation } from "@/lib/convex-client";
import { updateBookingStatusSchema } from "@/lib/validators/api-schemas";

export const dynamic = "force-dynamic";

/** Extract booking ID from /api/bookings/[id]/status URL */
function extractBookingId(request: NextRequest): string {
  const segments = request.nextUrl.pathname.split("/");
  // /api/bookings/[id]/status  => segments = ["", "api", "bookings", "<id>", "status"]
  return segments[3] ?? "";
}

export const PATCH = withCSRF(async (request: NextRequest) => {
  try {
    const bookingId = extractBookingId(request);

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

    if (!userEmail) {
      logger.warn("Unauthorized status update 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) {
      logger.warn("User not found for status update", { userEmail });
      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)
    const effectiveUserId = await getEffectiveOwnerId(user.id);

    logger.debug("Booking status update attempt", {
      bookingId,
      userEmail,
      userId: user.id,
      effectiveUserId,
    });

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

    if (!booking) {
      // Log more details for debugging
      const bookingExists = await prisma.bookings.findUnique({
        where: { id: bookingId },
        select: { id: true, userId: true },
      });
      logger.warn("Booking not found for user", {
        bookingId,
        effectiveUserId,
        bookingExists: !!bookingExists,
        actualUserId: bookingExists?.userId,
      });
      return NextResponse.json(
        { success: false, error: "Booking not found" },
        { status: 404 },
      );
    }

    // Parse and validate request body
    const body = await request.json();
    const parsed = updateBookingStatusSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        {
          success: false,
          error: parsed.error.errors.map(e => e.message).join(", "),
        },
        { status: 400 },
      );
    }

    const { status } = parsed.data;

    // --- Convex data-source routing (strangler fig) ---
    if (getDataSource("bookings") === "convex") {
      const { convexMutation } = await import("@/lib/convex-client");
      const updated = await convexMutation("bookings/mutations:updateStatus", {
        id: bookingId as Id<"bookings">,
        status,
      });
      return NextResponse.json({ booking: updated });
    }
    // --- End Convex routing ---

    // Update booking status
    const updatedBooking = await prisma.bookings.update({
      where: { id: bookingId },
      data: {
        status,
        updatedAt: new Date(),
      },
    });

    logger.info("Booking status updated", {
      bookingId,
      previousStatus: booking.status,
      newStatus: status,
      userEmail,
    });

    // Auto-send review request when appointment is completed
    let reviewSent = false;
    let reviewChannel: string | undefined;
    if (status === "completed") {
      const reviewResult = await triggerReviewForBooking(
        bookingId,
        effectiveUserId,
      );
      reviewSent = reviewResult.sent;
      if (reviewSent) {
        reviewChannel = reviewResult.emailSent ? "email" : "whatsapp";
      }
    }

    return NextResponse.json({
      success: true,
      message: "Status updated successfully",
      booking: updatedBooking,
      reviewSent,
      reviewChannel,
    });
    return NextResponse.json({ booking: updated });
  } catch (error) {
    logger.error("Failed to update booking status", {
      error: error instanceof Error ? error.message : "Unknown error",
    });

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