/**
 * Staff Interview Bookings API
 * GET: List all interview bookings with filtering
 */

import { NextRequest, NextResponse } from "next/server";
import { getStaffSession } from "@/lib/staff-session";
import { prisma } from "@/lib/db";
import { getDataSource } from "@/lib/data-source";
import { convexQuery } from "@/lib/convex-client";

export async function GET(req: NextRequest) {
  try {
    // Verify staff authentication
    const session = await getStaffSession();
    if (!session) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { searchParams } = new URL(req.url);
    const status = searchParams.get("status");
    const jobId = searchParams.get("jobId");
    const startDate = searchParams.get("startDate");
    const endDate = searchParams.get("endDate");
    const page = parseInt(searchParams.get("page") || "1");
    const limit = parseInt(searchParams.get("limit") || "20");
    const exportFormat = searchParams.get("export");

    // --- Convex path (non-export only; CSV export stays Prisma) ---
    if (getDataSource("careers") === "convex" && exportFormat !== "csv") {
      try {
        const bookings = (await convexQuery(
          "careers/queries:getInterviewBookings",
          {
            status: status && status !== "all" ? status : undefined,
            limit: 500, // Fetch more to filter/paginate in memory
          },
        )) as any[];

        let filtered = bookings || [];

        // Apply filters
        if (jobId) {
          filtered = filtered.filter((b: any) => b.jobId === jobId);
        }
        if (startDate) {
          const startMs = new Date(startDate).getTime();
          filtered = filtered.filter((b: any) => b.preferredDate >= startMs);
        }
        if (endDate) {
          const endMs = new Date(endDate).getTime();
          filtered = filtered.filter((b: any) => b.preferredDate <= endMs);
        }

        const total = filtered.length;
        const skip = (page - 1) * limit;
        const paged = filtered.slice(skip, skip + limit);

        const enrichedBookings = paged.map((b: any) => ({
          id: b._id ?? b.id,
          applicationId: b.applicationId,
          jobId: b.jobId,
          applicantName: b.applicantName,
          applicantEmail: b.applicantEmail,
          applicantPhone: b.applicantPhone,
          preferredDate: b.preferredDate
            ? new Date(b.preferredDate).toISOString()
            : null,
          preferredTime: b.preferredTime
            ? new Date(b.preferredTime).toISOString()
            : null,
          timezone: b.timezone,
          durationMinutes: b.durationMinutes,
          confirmedDate: b.confirmedDate
            ? new Date(b.confirmedDate).toISOString()
            : null,
          confirmedTime: b.confirmedTime
            ? new Date(b.confirmedTime).toISOString()
            : null,
          meetingLink: b.meetingLink,
          meetingPlatform: b.meetingPlatform,
          meetingId: b.meetingId,
          meetingPassword: b.meetingPassword,
          status: b.status,
          applicantNotes: b.applicantNotes,
          staffNotes: b.staffNotes,
          assignedTo: b.assignedTo,
          confirmedAt: b.confirmedAt
            ? new Date(b.confirmedAt).toISOString()
            : null,
          confirmedBy: b.confirmedBy,
          cancelledAt: b.cancelledAt
            ? new Date(b.cancelledAt).toISOString()
            : null,
          cancelledBy: b.cancelledBy,
          cancellationReason: b.cancellationReason,
          createdAt: b.createdAt ? new Date(b.createdAt).toISOString() : null,
          updatedAt: b.updatedAt ? new Date(b.updatedAt).toISOString() : null,
          jobTitle: null,
          jobTitleAr: null,
          applicantCvPath: null,
          applicationStatus: null,
          submittedAt: null,
        }));

        // Stats
        const stats = {
          total,
          pending: filtered.filter((b: any) => b.status === "PENDING").length,
          confirmed: filtered.filter((b: any) => b.status === "CONFIRMED")
            .length,
          newBookings: filtered.filter((b: any) => {
            const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
            return b.createdAt >= oneDayAgo;
          }).length,
        };

        return NextResponse.json({
          success: true,
          bookings: enrichedBookings,
          total,
          page,
          limit,
          totalPages: Math.ceil(total / limit),
          stats,
        });
      } catch (convexErr) {
        console.error(
          "Convex interview bookings list failed, falling back to Prisma:",
          convexErr,
        );
      }
    }

    // Build filter conditions
    const where: any = {};

    if (status && status !== "all") {
      where.status = status;
    }

    if (jobId) {
      where.job_id = jobId;
    }

    if (startDate) {
      where.preferred_date = {
        ...where.preferred_date,
        gte: new Date(startDate),
      };
    }

    if (endDate) {
      where.preferred_date = {
        ...where.preferred_date,
        lte: new Date(endDate),
      };
    }

    // Handle CSV export
    if (exportFormat === "csv") {
      const allBookings = await prisma.interview_bookings.findMany({
        where,
        orderBy: { created_at: "desc" },
      });

      // Generate CSV
      const csvHeaders = [
        "Applicant Name",
        "Applicant Email",
        "Job Title",
        "Preferred Date",
        "Preferred Time",
        "Timezone",
        "Status",
        "Meeting Link",
        "Created At",
      ];

      const csvRows = allBookings.map((booking) => [
        booking.applicant_name,
        booking.applicant_email,
        booking.job_id || "N/A", // You'd need to join jobs table for title
        new Date(booking.preferred_date).toISOString().split("T")[0],
        booking.preferred_time,
        booking.timezone,
        booking.status,
        booking.meeting_link || "Not added",
        new Date(booking.created_at).toISOString(),
      ]);

      const csvContent = [
        csvHeaders.join(","),
        ...csvRows.map((row) => row.map((cell) => `"${cell}"`).join(",")),
      ].join("\n");

      return new NextResponse(csvContent, {
        headers: {
          "Content-Type": "text/csv",
          "Content-Disposition": `attachment; filename="interview-bookings-${new Date().toISOString().split("T")[0]}.csv"`,
        },
      });
    }

    // Get total count for pagination
    const total = await prisma.interview_bookings.count({ where });

    // Fetch bookings with pagination
    const skip = (page - 1) * limit;
    const bookings = await prisma.interview_bookings.findMany({
      where,
      orderBy: { created_at: "desc" },
      skip,
      take: limit,
    });

    // Enrich with job and application data from Prisma
    const enrichedBookings = await Promise.all(
      bookings.map(async (booking) => {
        let jobTitle = null;
        let jobTitleAr = null;
        let applicantCvPath = null;
        let applicationStatus = null;
        let submittedAt = null;

        // Fetch job details
        if (booking.job_id) {
          try {
            const job = await prisma.jobs.findUnique({
              where: { id: booking.job_id },
              select: { title_translations: true },
            });

            if (job && job.title_translations) {
              const translations = job.title_translations as Record<
                string,
                string
              >;
              jobTitle = translations.en ?? null;
              jobTitleAr = translations.ar ?? null;
            }
          } catch {
            // Job may not exist in Prisma yet
          }
        }

        // Fetch application details
        if (booking.application_id) {
          try {
            const application = await prisma.job_applications.findUnique({
              where: { id: booking.application_id },
              select: {
                status: true,
                submitted_at: true,
                applicant_cv_path: true,
              },
            });

            if (application) {
              applicationStatus = application.status;
              submittedAt = application.submitted_at;
              applicantCvPath = application.applicant_cv_path;
            }
          } catch {
            // Application may not exist in Prisma yet
          }
        }

        return {
          id: booking.id,
          applicationId: booking.application_id,
          jobId: booking.job_id,
          applicantName: booking.applicant_name,
          applicantEmail: booking.applicant_email,
          applicantPhone: booking.applicant_phone,
          preferredDate: booking.preferred_date,
          preferredTime: booking.preferred_time,
          timezone: booking.timezone,
          durationMinutes: booking.duration_minutes,
          confirmedDate: booking.confirmed_date,
          confirmedTime: booking.confirmed_time,
          meetingLink: booking.meeting_link,
          meetingPlatform: booking.meeting_platform,
          meetingId: booking.meeting_id,
          meetingPassword: booking.meeting_password,
          status: booking.status,
          applicantNotes: booking.applicant_notes,
          staffNotes: booking.staff_notes,
          assignedTo: booking.assigned_to,
          confirmedAt: booking.confirmed_at,
          confirmedBy: booking.confirmed_by,
          cancelledAt: booking.cancelled_at,
          cancelledBy: booking.cancelled_by,
          cancellationReason: booking.cancellation_reason,
          createdAt: booking.created_at,
          updatedAt: booking.updated_at,
          // Enriched data
          jobTitle,
          jobTitleAr,
          applicantCvPath,
          applicationStatus,
          submittedAt,
        };
      }),
    );

    // Calculate statistics
    const stats = {
      total,
      pending: await prisma.interview_bookings.count({
        where: { ...where, status: "pending" },
      }),
      confirmed: await prisma.interview_bookings.count({
        where: { ...where, status: "confirmed" },
      }),
      newBookings: await prisma.interview_bookings.count({
        where: {
          ...where,
          created_at: {
            gte: new Date(Date.now() - 24 * 60 * 60 * 1000), // Last 24 hours
          },
        },
      }),
    };

    return NextResponse.json({
      success: true,
      bookings: enrichedBookings,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
      stats,
    });
  } catch (error: any) {
    console.error("Error fetching interview bookings:", error);
    return NextResponse.json(
      { error: "Failed to fetch interview bookings", details: error.message },
      { status: 500 },
    );
  }
}
