import { NextRequest, NextResponse } from 'next/server';
import dbConnect from '../../src/lib/mongodb';
import Review from '../../src/models/Review';
import '../../src/models/User';
import '../../src/models/Product'

const UPLOAD_SERVER_URL = 'http://167.71.224.75:8700';
const UPLOAD_ENDPOINT = `${UPLOAD_SERVER_URL}/upload`;
const DELETE_ENDPOINT = `${UPLOAD_SERVER_URL}/delete`;

async function uploadToExternalServer(file: File): Promise<string> {
  const formData = new FormData();
  formData.append('file', file);
  const response = await fetch(UPLOAD_ENDPOINT, { method: 'POST', body: formData });
  if (!response.ok) throw new Error(`Upload failed: ${response.statusText}`);
  const result = await response.json();
  if (result.success && result.filename) {
    return `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
  }
  throw new Error(result.error || 'Invalid response from upload server');
}

async function deleteFromExternalServer(imageUrl: string): Promise<void> {
  try {
    const filename = imageUrl.split('/').pop();
    if (!filename) return;
    await fetch(DELETE_ENDPOINT, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ filename }),
    });
  } catch (error) {
    console.error('Error deleting from external server:', error);
  }
}

// GET — fetch reviews with pagination + search + status filter
// In your API route (app/api/reviews/route.ts)
export async function GET(request: NextRequest, context?: { params: Promise<any> }) {
  try {
    await dbConnect();

    const { searchParams } = new URL(request.url);
    const page = parseInt(searchParams.get('page')   || '1');
    const limit = parseInt(searchParams.get('limit')  || '10');
    const search = searchParams.get('search');
    const status = searchParams.get('status');
    const product = searchParams.get('product');
    const rating = searchParams.get('rating');
    const sort = searchParams.get('sort') || 'createdAt';
    const order = searchParams.get('order') || 'desc';

    let query: any = {};

    if (status)  query.status = status;
    if (product) query.product = product;
    if (rating)  query.rating = parseInt(rating);

    if (search) {
      query.$or = [
        { authorName: { $regex: search, $options: 'i' } },
        { reviewTitle: { $regex: search, $options: 'i' } },
        { reviewDescription: { $regex: search, $options: 'i' } },
      ];
    }

    const skip = (page - 1) * limit;

    // Create sort object
    const sortOptions: any = {};
    if (search) {
      // Always sort alphabetically when searching
      sortOptions.authorName = 1;
    }
    else if (sort === 'createdAt') {
      sortOptions.createdAt = order === 'asc' ? 1 : -1;
    } else if (sort === 'product') {
      sortOptions['product.name'] = order === 'asc' ? 1 : -1;
    } else if (sort === 'authorName') {
      sortOptions.authorName = order === 'asc' ? 1 : -1;
    } else if (sort === 'rating') {
      sortOptions.rating = order === 'asc' ? 1 : -1;
    } else if (sort === 'status') {
      sortOptions.status = order === 'asc' ? 1 : -1;
    } else {
      sortOptions.createdAt = -1;
    }

    const reviews = await Review.find(query)
      .populate('product', 'name slug')
      // .populate('customer', '_id name email')
      .sort(sortOptions)
      .skip(skip)
      .limit(limit);

    const total = await Review.countDocuments(query);

    return NextResponse.json({
      success: true,
      data: reviews,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit),
      },
    });

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

// POST — create review
export async function POST(request: NextRequest) {
  try {
    await dbConnect();

    const formData = await request.formData();

    const product = formData.get('product') as string;
    const customer = formData.get('customer') as string;
    const authorName = formData.get('authorName') as string;
    const authorEmail = formData.get('authorEmail') as string;
    const reviewTitle = formData.get('reviewTitle') as string;
    const reviewDescription = formData.get('reviewDescription') as string;
    const rating = parseInt(formData.get('rating') as string);
    const files = formData.getAll('images') as File[];

    if (!product) return NextResponse.json({ success: false, error: 'Product is required' },     { status: 400 });
    if (!customer) return NextResponse.json({ success: false, error: 'Customer is required' },    { status: 400 });
    if (!authorName) return NextResponse.json({ success: false, error: 'Author name is required' }, { status: 400 });
    if (!authorEmail) return NextResponse.json({ success: false, error: 'Author email is required'}, { status: 400 });
    if (!reviewTitle) return NextResponse.json({ success: false, error: 'Review title is required'}, { status: 400 });
    if (!rating || rating < 1 || rating > 5) {
      return NextResponse.json({ success: false, error: 'Rating must be between 1 and 5' }, { status: 400 });
    }

    // Upload images
    const imageUrls: string[] = [];
    for (const file of files) {
      if (file && file.size > 0) {
        if (file.size > 2 * 1024 * 1024) {
          return NextResponse.json({ success: false, error: 'Each image must be under 2MB' }, { status: 400 });
        }
        const url = await uploadToExternalServer(file);
        imageUrls.push(url);
      }
    }

    const review = await Review.create({
      product,
      customer,
      authorName: authorName.trim(),
      authorEmail: authorEmail.trim().toLowerCase(),
      reviewTitle: reviewTitle.trim(),
      reviewDescription: reviewDescription?.trim() || '',
      rating,
      images: imageUrls,
      status: 'not-approved',
    });

    const populated = await Review.findById(review._id)
      .populate('product', 'name slug')
      // .populate('customer', 'name email');

    return NextResponse.json({ success: true, data: populated }, { status: 201 });

  } catch (error: any) {
    console.error('Error creating review:', error);
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to create review' },
      { status: 500 }
    );
  }
}

// PUT — update review (status change + edit)
export async function PUT(request: NextRequest, context?: { params: Promise<any> }) {
  try {
    await dbConnect();

    const url = new URL(request.url);
    const id  = url.pathname.split('/').pop();

    if (!id) {
      return NextResponse.json({ success: false, error: 'Review ID is required' }, { status: 400 });
    }

    const existing = await Review.findById(id);
    if (!existing) {
      return NextResponse.json({ success: false, error: 'Review not found' }, { status: 404 });
    }

    const formData = await request.formData();

    const reviewTitle = formData.get('reviewTitle') as string;
    const reviewDescription = formData.get('reviewDescription') as string;
    const rating = formData.get('rating') ? parseInt(formData.get('rating') as string) : undefined;
    const status = formData.get('status') as string;
    const files = formData.getAll('images') as File[];
    const removeImages = formData.get('removeImages') as string; // JSON array of URLs to remove

    // Handle image removals
    let currentImages = [...existing.images];
    if (removeImages) {
      const toRemove: string[] = JSON.parse(removeImages);
      for (const imgUrl of toRemove) {
        await deleteFromExternalServer(imgUrl);
        currentImages = currentImages.filter((img: string) => img !== imgUrl);
      }
    }

    // Upload new images
    for (const file of files) {
      if (file && file.size > 0) {
        if (file.size > 2 * 1024 * 1024) {
          return NextResponse.json({ success: false, error: 'Each image must be under 2MB' }, { status: 400 });
        }
        const url = await uploadToExternalServer(file);
        currentImages.push(url);
      }
    }

    const updateData: any = { images: currentImages };
    if (reviewTitle) updateData.reviewTitle = reviewTitle.trim();
    if (reviewDescription !== null) updateData.reviewDescription = reviewDescription?.trim() || '';
    if (rating) updateData.rating = rating;
    if (status) updateData.status = status;

    const updated = await Review.findByIdAndUpdate(
      id,
      { $set: updateData },
      { new: true, runValidators: true }
    )
      .populate('product',  'name slug')
      // .populate('customer', '_id name email');

    return NextResponse.json({ success: true, data: updated });

  } catch (error: any) {
    console.error('Error updating review:', error);
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to update review' },
      { status: 500 }
    );
  }
}

// DELETE — delete review
export async function DELETE(request: NextRequest, context?: { params: Promise<any> }) {
  try {
    await dbConnect();

    const url = new URL(request.url);
    const id  = url.pathname.split('/').pop();

    if (!id) {
      return NextResponse.json({ success: false, error: 'Review ID is required' }, { status: 400 });
    }

    const review = await Review.findById(id);
    if (!review) {
      return NextResponse.json({ success: false, error: 'Review not found' }, { status: 404 });
    }

    // Delete all images from external server
    for (const imgUrl of review.images) {
      await deleteFromExternalServer(imgUrl);
    }

    await Review.findByIdAndDelete(id);

    return NextResponse.json({ success: true, message: 'Review deleted successfully' });

  } catch (error: any) {
    console.error('Error deleting review:', error);
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to delete review' },
      { status: 500 }
    );
  }
}