/**
 * Demo Booking Confirmation Endpoint
 *
 * Confirms a demo booking and sends confirmation email to customer
 *
 * Security:
 * - Requires authentication (admin only)
 * - CSRF protection
 * - Rate limiting
 *
 * Database:
 * - Uses Convex as the sole database (demo bookings are created in Convex only)
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { sendDemoConfirmationEmail } from "@/lib/email";
import { logger } from "@/lib/logger";
import { withCSRF } from "@/lib/csrf";
import { withRateLimit, rateLimiters } from "@/lib/rate-limiter";
import { convexQuery, convexMutation } from "@/lib/convex-client";
import { demoConfirmSchema } from "@/lib/validators/api-schemas";

export const dynamic = "force-dynamic";
export const runtime = "nodejs";

async function confirmBookingHandler(request: NextRequest) {
  try {
    // Require authentication (only logged-in users can confirm bookings)
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json(
        { error: "Authentication required" },
        { status: 401 },
      );
    }

    const body = await request.json();
    const parsed = demoConfirmSchema.safeParse(body);

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

    const { bookingId } = parsed.data;

    // ── Convex data-source branch ──────────────────────────────────────
    if (getDataSource("bookings") === "convex") {
      try {
        const { convexQuery, convexMutation } =
          await import("@/lib/convex-client");

        // Look up the demo booking — try Convex ID first, fall back to legacy Prisma ID
        let convexBooking: Record<string, unknown> | null = null;
        let convexDocId: string | null = null;

        // Convex IDs are typically longer and don't look like CUIDs
        try {
          convexBooking = await convexQuery(
            "bookings/queries:getDemoBookingById",
            { id: bookingId },
          );
          if (convexBooking) convexDocId = bookingId;
        } catch {
          // Not a valid Convex ID — try as a legacy Prisma ID
        }

        if (!convexBooking) {
          convexBooking = await convexQuery(
            "bookings/queries:getDemoBookingByLegacyId",
            { legacyId: bookingId },
          );
          if (convexBooking)
            convexDocId = (convexBooking as Record<string, unknown>)
              ._id as string;
        }

        if (!convexBooking) {
          // Fall through to Prisma path below
          logger.info("Convex booking not found, falling through to Prisma", {
            bookingId,
          });
        } else {
          if (convexBooking.status === "confirmed") {
            return NextResponse.json(
              { error: "Booking is already confirmed" },
              { status: 400 },
            );
          }

          // Confirm the booking in Convex
          await convexMutation("bookings/mutations:confirmDemoBooking", {
            id: convexDocId as `${string}`,
          });

          // Format date for email display
          const appointmentDate = new Date(
            convexBooking.appointmentDate as number,
          );
          const language = (convexBooking.language as string) || "en";
          const formattedDate = appointmentDate.toLocaleDateString(
            language === "ar" ? "ar-SA" : "en-US",
            { weekday: "long", year: "numeric", month: "long", day: "numeric" },
          );

          // Send confirmation email
          const emailSent = await sendDemoConfirmationEmail(
            convexBooking.email as string,
            convexBooking.fullName as string,
            formattedDate,
            convexBooking.appointmentTime as string,
            convexBooking.duration as string,
            language as "ar" | "en",
          );

          if (!emailSent) {
            logger.error("Failed to send confirmation email", {
              bookingId,
              email: convexBooking.email,
            });
          }

          logger.info("Demo booking confirmed via Convex and email sent", {
            bookingId,
            convexDocId,
            email: convexBooking.email,
            emailSent,
          });

          return NextResponse.json({
            success: true,
            message: "Booking confirmed successfully",
            emailSent,
          });
        }
      } catch (convexError) {
        logger.warn("Convex confirm failed, falling through to Prisma", {
          bookingId,
          error:
            convexError instanceof Error
              ? convexError.message
              : String(convexError),
        });
        // Fall through to Prisma path
      }
    }

    if (!convexBooking) {
      convexBooking = await convexQuery(
        "bookings/queries:getDemoBookingByLegacyId",
        { legacyId: bookingId },
      );
      if (convexBooking)
        convexDocId = (convexBooking as Record<string, unknown>)._id as string;
    }

    if (!convexBooking || !convexDocId) {
      logger.error("Booking not found in Convex", { bookingId });
      return NextResponse.json({ error: "Booking not found" }, { status: 404 });
    }

    // Check if already confirmed
    if (convexBooking.status === "confirmed") {
      return NextResponse.json(
        { error: "Booking is already confirmed" },
        { status: 400 },
      );
    }

    // Confirm the booking in Convex
    await convexMutation("bookings/mutations:confirmDemoBooking", {
      id: convexDocId as `${string}`,
    });

    // Format date for email display
    const appointmentDate = new Date(convexBooking.appointmentDate as number);
    const language = (convexBooking.language as string) || "en";
    const formattedDate = appointmentDate.toLocaleDateString(
      language === "ar" ? "ar-SA" : "en-US",
      { weekday: "long", year: "numeric", month: "long", day: "numeric" },
    );

    // Send confirmation email
    const emailSent = await sendDemoConfirmationEmail(
      convexBooking.email as string,
      convexBooking.fullName as string,
      formattedDate,
      convexBooking.appointmentTime as string,
      convexBooking.duration as string,
      language as "ar" | "en",
    );

    if (!emailSent) {
      logger.error("Failed to send confirmation email", {
        bookingId,
        email: convexBooking.email,
      });
      // Don't fail the request - booking is still confirmed
    }

    logger.info("Demo booking confirmed via Convex and email sent", {
      bookingId,
      convexDocId,
      email: convexBooking.email,
      emailSent,
    });

    return NextResponse.json({
      success: true,
      message: "Booking confirmed successfully",
      emailSent,
    });
  } catch (error) {
    logger.error("Confirm booking API error", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}

// Apply CSRF protection and rate limiting
export const POST = withCSRF(
  withRateLimit(confirmBookingHandler, rateLimiters.authGeneral),
);
