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

export async function POST(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

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

    const user = session.user as any;
    
    if (user.role !== 'CLIENT') {
      return NextResponse.json(
        { error: 'Only clients can submit reviews' },
        { status: 403 }
      );
    }

    const body = await request.json();
    const { projectId, freelancerId, rating, review } = body;

    // Validate required fields
    if (!projectId || !freelancerId || !rating || !review) {
      return NextResponse.json(
        { error: 'Project ID, freelancer ID, rating, and review are required' },
        { status: 400 }
      );
    }

    // Validate rating range
    if (typeof rating !== 'number' || rating < 1 || rating > 5) {
      return NextResponse.json(
        { error: 'Rating must be a number between 1 and 5' },
        { status: 400 }
      );
    }

    // Validate review length
    if (typeof review !== 'string' || review.trim().length < 10) {
      return NextResponse.json(
        { error: 'Review must be at least 10 characters long' },
        { status: 400 }
      );
    }

    // Check if project exists and user is the client
    const project = await prisma.project.findUnique({
      where: { id: projectId },
      select: {
        id: true,
        clientId: true,
        status: true,
        title: true
      }
    });

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

    if (project.clientId !== user.id) {
      return NextResponse.json(
        { error: 'You can only review projects you own' },
        { status: 403 }
      );
    }

    if (project.status !== 'COMPLETED') {
      return NextResponse.json(
        { error: 'You can only review completed projects' },
        { status: 400 }
      );
    }

    // Check if the freelancer worked on this project
    const projectBid = await prisma.bid.findFirst({
      where: {
        projectId: projectId,
        freelancerId: freelancerId,
        status: 'ACCEPTED'
      }
    });

    if (!projectBid) {
      return NextResponse.json(
        { error: 'Freelancer did not work on this project' },
        { status: 400 }
      );
    }

    // Check if review already exists
    const existingReview = await prisma.review.findFirst({
      where: {
        projectId: projectId,
        authorId: user.id,
        recipientId: freelancerId
      }
    });

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

    // Create the review
    const newReview = await prisma.review.create({
      data: {
        rating: parseFloat(rating.toString()),
        comment: review.trim(),
        projectId: projectId,
        authorId: user.id,
        recipientId: freelancerId,
      },
      include: {
        author: {
          include: {
            profile: true
          }
        },
        recipient: {
          include: {
            profile: true
          }
        },
        project: {
          select: {
            title: true
          }
        }
      }
    });

    // Create notification for freelancer
    try {
      await prisma.notification.create({
        data: {
          userId: freelancerId,
          type: 'NEW_REVIEW',
          title: 'New Review Received',
          message: `${newReview.author.profile?.firstName || 'A client'} left you a ${rating}-star review for "${project.title}".`,
          data: JSON.stringify({
            projectId: projectId,
            reviewId: newReview.id,
            rating: rating
          }),
          isRead: false,
        }
      });
    } catch (notificationError) {
      // Log error but don't fail the review creation
      console.log('Could not create notification:', notificationError);
    }

    return NextResponse.json({
      success: true,
      message: 'Review submitted successfully',
      review: {
        id: newReview.id,
        rating: newReview.rating,
        comment: newReview.comment,
        createdAt: newReview.createdAt.toISOString(),
      }
    });

  } catch (error) {
    console.error('Error creating review:', error);
    return NextResponse.json(
      { 
        success: false,
        error: 'Internal server error',
        message: error instanceof Error ? error.message : 'Unknown error'
      },
      { status: 500 }
    );
  }
}

export async function GET(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

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

    const { searchParams } = new URL(request.url);
    const freelancerId = searchParams.get('freelancerId');
    const clientId = searchParams.get('clientId');
    const page = parseInt(searchParams.get('page') || '1');
    const limit = parseInt(searchParams.get('limit') || '10');
    const skip = (page - 1) * limit;

    if (!freelancerId && !clientId) {
      return NextResponse.json(
        { error: 'Either freelancer ID or client ID is required' },
        { status: 400 }
      );
    }

    // Determine the target user ID
    const targetUserId = freelancerId || clientId;
    
    if (!targetUserId) {
      return NextResponse.json(
        { error: 'Invalid user ID' },
        { status: 400 }
      );
    }

    // Get total count
    const total = await prisma.review.count({
      where: { recipientId: targetUserId }
    });

    // Get reviews with reviewer details
    const reviews = await prisma.review.findMany({
      where: { recipientId: targetUserId },
      orderBy: {
        createdAt: 'desc'
      },
      skip,
      take: limit,
      include: {
        author: {
          include: {
            profile: true
          }
        },
        project: {
          select: {
            title: true
          }
        }
      }
    });

    // Transform reviews data
    const transformedReviews = reviews.map(review => ({
      id: review.id,
      rating: review.rating,
      review: review.comment,
      createdAt: review.createdAt.toISOString(),
      project: {
        title: review.project.title
      },
      reviewer: {
        id: review.author.id,
        name: review.author.profile 
          ? `${review.author.profile.firstName || ''} ${review.author.profile.lastName || ''}`.trim() || 'Anonymous'
          : 'Anonymous',
        profileImage: review.author.profile?.profileImage || '/assets/image/user.png'
      }
    }));

    // Calculate average rating
    const averageRating = reviews.length > 0 
      ? reviews.reduce((sum, review) => sum + review.rating, 0) / reviews.length 
      : 0;

    const totalPages = Math.ceil(total / limit);
    const hasNextPage = page < totalPages;
    const hasPrevPage = page > 1;

    return NextResponse.json({
      success: true,
      data: {
        reviews: transformedReviews,
        stats: {
          totalReviews: total,
          averageRating: parseFloat(averageRating.toFixed(1))
        },
        pagination: {
          currentPage: page,
          totalPages,
          totalItems: total,
          itemsPerPage: limit,
          hasNextPage,
          hasPrevPage
        }
      }
    });

  } catch (error) {
    console.error('Error fetching reviews:', error);
    return NextResponse.json(
      { 
        success: false, 
        error: 'Failed to fetch reviews',
        message: error instanceof Error ? error.message : 'Unknown error'
      },
      { status: 500 }
    );
  }
}