
import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/db';

// GET: Fetch reviews for a contractor
export async function GET(request: NextRequest) {
  try {
    const searchParams = request.nextUrl.searchParams;
    const contractorId = searchParams.get('contractorId');
    const published = searchParams.get('published') === 'true';
    const limit = parseInt(searchParams.get('limit') || '10');
    const featured = searchParams.get('featured') === 'true';

    const where: any = {};
    if (contractorId) where.contractorId = contractorId;
    if (published) where.isPublished = true;
    if (featured) where.isFeatured = true;

    const reviews = await prisma.contractorReview.findMany({
      where,
      take: limit,
      orderBy: [
        { isFeatured: 'desc' },
        { createdAt: 'desc' },
      ],
    });

    // Calculate average ratings
    if (contractorId && reviews.length > 0) {
      const avgRating = reviews.reduce((sum: number, r: any) => sum + r.overallRating, 0) / reviews.length;
      const ratingDistribution = {
        5: reviews.filter((r: any) => r.overallRating === 5).length,
        4: reviews.filter((r: any) => r.overallRating >= 4 && r.overallRating < 5).length,
        3: reviews.filter((r: any) => r.overallRating >= 3 && r.overallRating < 4).length,
        2: reviews.filter((r: any) => r.overallRating >= 2 && r.overallRating < 3).length,
        1: reviews.filter((r: any) => r.overallRating < 2).length,
      };

      return NextResponse.json({
        reviews,
        stats: {
          averageRating: avgRating,
          totalReviews: reviews.length,
          ratingDistribution,
        },
      });
    }

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

// POST: Create a new review
export async function POST(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const body = await request.json();
    const {
      contractId,
      contractorId,
      overallRating,
      qualityRating,
      timelinessRating,
      communicationRating,
      valueRating,
      title,
      comment,
    } = body;

    // Validate ratings
    if (overallRating < 1 || overallRating > 5) {
      return NextResponse.json(
        { error: 'Overall rating must be between 1 and 5' },
        { status: 400 }
      );
    }

    // Check if user already reviewed this contractor for this contract
    const existingReview = await prisma.contractorReview.findFirst({
      where: {
        contractId,
        customerId: session.user.id,
      },
    });

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

    const review = await prisma.contractorReview.create({
      data: {
        contractId,
        contractorId,
        customerId: session.user.id,
        overallRating,
        qualityRating,
        timelinessRating,
        communicationRating,
        valueRating,
        title,
        comment,
        isVerified: true,
      },
    });

    // Update contractor performance metrics
    await updateContractorPerformance(contractorId);

    return NextResponse.json({ review }, { status: 201 });
  } catch (error) {
    console.error('Error creating review:', error);
    return NextResponse.json(
      { error: 'Failed to create review' },
      { status: 500 }
    );
  }
}

// PUT: Update review (respond to review, mark as featured, etc.)
export async function PUT(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const body = await request.json();
    const { reviewId, contractorResponse, isFeatured, isPublished } = body;

    const review = await prisma.contractorReview.findUnique({
      where: { id: reviewId },
    });

    if (!review) {
      return NextResponse.json({ error: 'Review not found' }, { status: 404 });
    }

    // Check permissions
    const isContractor = review.contractorId === session.user.id;
    const isAdmin = session.user.role === 'ADMIN';

    if (!isContractor && !isAdmin) {
      return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
    }

    const updateData: any = {};
    if (contractorResponse) {
      updateData.contractorResponse = contractorResponse;
      updateData.respondedAt = new Date();
    }
    if (isAdmin) {
      if (typeof isFeatured === 'boolean') updateData.isFeatured = isFeatured;
      if (typeof isPublished === 'boolean') updateData.isPublished = isPublished;
    }

    const updatedReview = await prisma.contractorReview.update({
      where: { id: reviewId },
      data: updateData,
    });

    return NextResponse.json({ review: updatedReview });
  } catch (error) {
    console.error('Error updating review:', error);
    return NextResponse.json(
      { error: 'Failed to update review' },
      { status: 500 }
    );
  }
}

// Helper function to update contractor performance
async function updateContractorPerformance(contractorId: string) {
  const reviews = await prisma.contractorReview.findMany({
    where: { contractorId, isPublished: true },
  });

  if (reviews.length === 0) return;

  const avgRating =
    reviews.reduce((sum: number, r: any) => sum + r.overallRating, 0) / reviews.length;

  const period = new Date().toISOString().slice(0, 7); // YYYY-MM format

  await prisma.contractorPerformance.upsert({
    where: {
      userId_partnerId_period: {
        userId: contractorId,
        partnerId: contractorId,
        period,
      },
    },
    update: {
      averageRating: avgRating,
      customerSatisfaction: avgRating,
    },
    create: {
      userId: contractorId,
      partnerId: contractorId,
      period,
      averageRating: avgRating,
      customerSatisfaction: avgRating,
    },
  });
}
