/**
 * Manual Reminder Trigger API
 *
 * Allows staff to manually send reminder for a specific demo booking.
 * Useful for:
 * - Resending a reminder that failed
 * - Sending reminder before the 24-hour window
 * - Testing the reminder system
 *
 * Security:
 * - Requires staff authentication
 * - Validates booking exists and has a meeting link
 */

import { NextResponse } from "next/server";
import { validateStaffSession } from "@/lib/staff-session";
import { sendReminderForBooking } from "@/lib/services/demo-reminder.service";
import { prisma } from "@/lib/db";
import { logger } from "@/lib/logger";
import { getDataSource } from "@/lib/data-source";

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

export async function POST(request: Request, context: RouteContext) {
  try {
    // Validate staff session
    const staffValidation = await validateStaffSession(request);
    if (!staffValidation.isValid) {
      return NextResponse.json(
        { error: "Unauthorized", message: "Staff authentication required" },
        { status: 401 },
      );
    }

    const { id } = await context.params;

    if (!id) {
      return NextResponse.json(
        { error: "Missing booking ID" },
        { status: 400 },
      );
    }

    // ── Convex data-source branch ──────────────────────────────────────
    if (getDataSource("bookings") === "convex") {
      try {
        const { convexQuery } = 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;

        try {
          convexBooking = await convexQuery(
            "bookings/queries:getDemoBookingById",
            { id },
          );
        } catch {
          // Not a valid Convex ID — try as a legacy Prisma ID
        }

        if (!convexBooking) {
          convexBooking = await convexQuery(
            "bookings/queries:getDemoBookingByLegacyId",
            { legacyId: id },
          );
        }

        if (convexBooking) {
          // Validate booking state
          if (!convexBooking.googleJoinUrl) {
            return NextResponse.json(
              {
                error: "No meeting link",
                message:
                  "This booking does not have a Google Meet link. Cannot send reminder.",
              },
              { status: 400 },
            );
          }

          if (convexBooking.status === "cancelled") {
            return NextResponse.json(
              {
                error: "Booking cancelled",
                message: "Cannot send reminder for a cancelled booking.",
              },
              { status: 400 },
            );
          }

          const convexAppointmentDate = new Date(
            convexBooking.appointmentDate as number,
          );
          if (convexAppointmentDate < new Date()) {
            return NextResponse.json(
              {
                error: "Past appointment",
                message: "Cannot send reminder for a past appointment.",
              },
              { status: 400 },
            );
          }

          // The sendReminderForBooking service uses Prisma internally,
          // so pass the Prisma ID (or fall through if only Convex ID available)
          const prismaId = (convexBooking.prismaId as string) || id;

          logger.info("Staff manually triggering reminder (Convex lookup)", {
            staffId: staffValidation.staffId,
            bookingId: id,
            prismaId,
          });

          // Send the reminder using the Prisma-based service
          const result = await sendReminderForBooking(prismaId);

          if (result.emailSent || result.whatsAppSent) {
            return NextResponse.json({
              success: true,
              message: "Reminder sent successfully",
              bookingId: id,
              emailSent: result.emailSent,
              whatsAppSent: result.whatsAppSent,
              previouslySent: convexBooking.reminderSentAt ? true : false,
            });
          } else {
            return NextResponse.json(
              {
                success: false,
                error: result.error || "Failed to send reminder",
                emailSent: result.emailSent,
                whatsAppSent: result.whatsAppSent,
              },
              { status: 500 },
            );
          }
        } else {
          logger.info("Convex booking not found, falling through to Prisma", {
            bookingId: id,
          });
        }
      } catch (convexError) {
        logger.warn(
          "Convex reminder lookup failed, falling through to Prisma",
          {
            bookingId: id,
            error:
              convexError instanceof Error
                ? convexError.message
                : String(convexError),
          },
        );
        // Fall through to Prisma path
      }
    }

    // ── Prisma path (primary) ──────────────────────────────────────

    // Verify booking exists
    const booking = await prisma.demo_bookings.findUnique({
      where: { id },
      select: {
        id: true,
        fullName: true,
        email: true,
        googleJoinUrl: true,
        status: true,
        appointmentDate: true,
        reminderSentAt: true,
      },
    });

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

    // Check if booking has a meeting link
    if (!booking.googleJoinUrl) {
      return NextResponse.json(
        {
          error: "No meeting link",
          message:
            "This booking does not have a Google Meet link. Cannot send reminder.",
        },
        { status: 400 },
      );
    }

    // Check if booking is cancelled
    if (booking.status === "cancelled") {
      return NextResponse.json(
        {
          error: "Booking cancelled",
          message: "Cannot send reminder for a cancelled booking.",
        },
        { status: 400 },
      );
    }

    // Check if appointment is in the past
    const appointmentDate = new Date(booking.appointmentDate);
    if (appointmentDate < new Date()) {
      return NextResponse.json(
        {
          error: "Past appointment",
          message: "Cannot send reminder for a past appointment.",
        },
        { status: 400 },
      );
    }

    logger.info("Staff manually triggering reminder", {
      staffId: staffValidation.staffId,
      bookingId: id,
    });

    // Send the reminder
    const result = await sendReminderForBooking(id);

    if (result.emailSent || result.whatsAppSent) {
      return NextResponse.json({
        success: true,
        message: "Reminder sent successfully",
        bookingId: id,
        emailSent: result.emailSent,
        whatsAppSent: result.whatsAppSent,
        previouslySent: booking.reminderSentAt ? true : false,
      });
    } else {
      return NextResponse.json(
        {
          success: false,
          error: result.error || "Failed to send reminder",
          emailSent: result.emailSent,
          whatsAppSent: result.whatsAppSent,
        },
        { status: 500 },
      );
    }
  } catch (error) {
    logger.error("Error in manual reminder trigger", error);
    return NextResponse.json(
      {
        error: "Internal server error",
        message: error instanceof Error ? error.message : "Unknown error",
      },
      { status: 500 },
    );
  }
}

// GET endpoint to check reminder status
export async function GET(request: Request, context: RouteContext) {
  try {
    // Validate staff session
    const staffValidation = await validateStaffSession(request);
    if (!staffValidation.isValid) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await context.params;

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

        let convexBooking: Record<string, unknown> | null = null;

        try {
          convexBooking = await convexQuery(
            "bookings/queries:getDemoBookingById",
            { id },
          );
        } catch {
          // Not a valid Convex ID — try as a legacy Prisma ID
        }

        if (!convexBooking) {
          convexBooking = await convexQuery(
            "bookings/queries:getDemoBookingByLegacyId",
            { legacyId: id },
          );
        }

        if (convexBooking) {
          return NextResponse.json({
            bookingId: (convexBooking._id as string) || id,
            customerName: convexBooking.fullName,
            customerEmail: convexBooking.email,
            appointmentDate:
              typeof convexBooking.appointmentDate === "number"
                ? new Date(
                    convexBooking.appointmentDate as number,
                  ).toISOString()
                : convexBooking.appointmentDate,
            appointmentTime: convexBooking.appointmentTime,
            hasMeetingLink: !!convexBooking.googleJoinUrl,
            meetingLink: convexBooking.googleJoinUrl ?? null,
            status: convexBooking.status,
            reminder: {
              status: convexBooking.reminderStatus ?? null,
              sentAt:
                typeof convexBooking.reminderSentAt === "number"
                  ? new Date(
                      convexBooking.reminderSentAt as number,
                    ).toISOString()
                  : (convexBooking.reminderSentAt ?? null),
              emailSent: convexBooking.reminderEmailSent ?? false,
              whatsAppSent: convexBooking.reminderWhatsAppSent ?? false,
              error: convexBooking.reminderError ?? null,
            },
          });
        } else {
          logger.info(
            "Convex booking not found for reminder status, falling through to Prisma",
            { bookingId: id },
          );
        }
      } catch (convexError) {
        logger.warn(
          "Convex reminder status lookup failed, falling through to Prisma",
          {
            bookingId: id,
            error:
              convexError instanceof Error
                ? convexError.message
                : String(convexError),
          },
        );
        // Fall through to Prisma path
      }
    }

    // ── Prisma path (primary) ──────────────────────────────────────

    const booking = await prisma.demo_bookings.findUnique({
      where: { id },
      select: {
        id: true,
        fullName: true,
        email: true,
        telephone: true,
        appointmentDate: true,
        appointmentTime: true,
        googleJoinUrl: true,
        status: true,
        reminderStatus: true,
        reminderSentAt: true,
        reminderEmailSent: true,
        reminderWhatsAppSent: true,
        reminderError: true,
      },
    });

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

    return NextResponse.json({
      bookingId: booking.id,
      customerName: booking.fullName,
      customerEmail: booking.email,
      appointmentDate: booking.appointmentDate,
      appointmentTime: booking.appointmentTime,
      hasMeetingLink: !!booking.googleJoinUrl,
      meetingLink: booking.googleJoinUrl,
      status: booking.status,
      reminder: {
        status: booking.reminderStatus,
        sentAt: booking.reminderSentAt,
        emailSent: booking.reminderEmailSent,
        whatsAppSent: booking.reminderWhatsAppSent,
        error: booking.reminderError,
      },
    });
  } catch (error) {
    logger.error("Error fetching reminder status", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}
