import { NextRequest, NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth-utils";
import prisma from "@/lib/db";
import { sendReviewNotificationEmail } from "@/lib/email";

/**
 * POST /api/reviews
 * Create a new review for a tour
 */
export async function POST(request: NextRequest) {
  try {
    const user = await getCurrentUser();

    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const body = await request.json();
    const { tourId, rating, comment } = body;

    // Validate required fields
    if (!tourId || !rating) {
      return NextResponse.json(
        { error: "Missing required fields" },
        { status: 400 }
      );
    }

    // Validate rating is between 1 and 5
    if (rating < 1 || rating > 5 || !Number.isInteger(rating)) {
      return NextResponse.json(
        { error: "Rating must be an integer between 1 and 5" },
        { status: 400 }
      );
    }

    // Get tour details
    const tour = await prisma.tour.findUnique({
      where: { id: tourId },
      select: {
        id: true,
        title: true,
        slug: true,
        createdById: true,
        createdBy: {
          select: {
            name: true,
            email: true,
          },
        },
      },
    });

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

    // Prevent guide from reviewing their own tour
    if (tour.createdById === user.id) {
      return NextResponse.json(
        { error: "You cannot review your own tour" },
        { status: 400 }
      );
    }

    // Check if user has already reviewed this tour
    const existingReview = await prisma.review.findUnique({
      where: {
        tourId_userId: {
          tourId,
          userId: user.id,
        },
      },
    });

    if (existingReview) {
      return NextResponse.json(
        { error: "You have already reviewed this tour" },
        { status: 400 }
      );
    }

    // Check if user has a COMPLETED booking for this tour
    // Reviews can only be submitted after the tour is marked as completed
    const booking = await prisma.booking.findFirst({
      where: {
        userId: user.id,
        tourId,
        status: "COMPLETED",
      },
    });

    if (!booking) {
      return NextResponse.json(
        {
          error:
            "You can only review tours that have been marked as completed. Please wait for your guide to mark the tour as completed, or it will be automatically completed 24 hours after the tour date.",
        },
        { status: 400 }
      );
    }

    // Create the review
    const review = await prisma.review.create({
      data: {
        tourId,
        userId: user.id,
        rating,
        comment: comment || null,
      },
      include: {
        user: {
          select: {
            name: true,
            image: true,
          },
        },
      },
    });

    // Update tour average rating and review count
    const reviews = await prisma.review.findMany({
      where: { tourId },
      select: { rating: true },
    });

    const avgRating =
      reviews.reduce((sum, r) => sum + r.rating, 0) / reviews.length;

    await prisma.tour.update({
      where: { id: tourId },
      data: {
        avgRating,
        reviewCount: reviews.length,
      },
    });

    // Send email notification to guide
    await sendReviewNotificationEmail({
      guideName: tour.createdBy.name || "Guide",
      guideEmail: tour.createdBy.email,
      explorerName: user.name || "An explorer",
      tourTitle: tour.title,
      rating,
      comment,
      tourSlug: tour.slug,
    });

    return NextResponse.json(
      {
        review,
        message: "Review submitted successfully",
      },
      { status: 201 }
    );
  } catch (error) {
    console.error("Error creating review:", error);
    return NextResponse.json(
      { error: "Failed to create review" },
      { status: 500 }
    );
  }
}

/**
 * GET /api/reviews?tourId=xxx
 * Get all reviews for a tour
 */
export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const tourId = searchParams.get("tourId");

    if (!tourId) {
      return NextResponse.json(
        { error: "Tour ID is required" },
        { status: 400 }
      );
    }

    const reviews = await prisma.review.findMany({
      where: { tourId },
      include: {
        user: {
          select: {
            name: true,
            image: true,
          },
        },
      },
      orderBy: { createdAt: "desc" },
    });

    return NextResponse.json({ reviews });
  } catch (error) {
    console.error("Error fetching reviews:", error);
    return NextResponse.json(
      { error: "Failed to fetch reviews" },
      { status: 500 }
    );
  }
}
