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

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

function makeSlug(text: string) {
  return text
    .toString()
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, '')
    .replace(/\s+/g, '-')
    .replace(/--+/g, '-');
}

// Helper function to upload image to external server
async function uploadToExternalServer(file: File): Promise<string> {
  try {
    const formData = new FormData();
    formData.append('file', file);
    
    const response = await fetch(UPLOAD_ENDPOINT, {
      method: 'POST',
      body: formData,
    });
    
    if (!response.ok) {
      const errorText = await response.text();
      console.error('Upload failed:', response.status, errorText);
      throw new Error(`Upload failed: ${response.statusText}`);
    }
    
    const result = await response.json();
    
    if (result.success && result.url) {
      console.log('Image uploaded successfully:', result.url);
      const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
      return imageUrl;
    } else if (result.success && result.filename) {
      // Construct URL if only filename is returned
      const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
      return imageUrl;
    } else {
      throw new Error(result.error || 'Invalid response from upload server');
    }
  } catch (error) {
    console.error('Error uploading to external server:', error);
    throw new Error('Failed to upload image to external server');
  }
}

// Helper function to delete image from external server
async function deleteFromExternalServer(imageUrl: string): Promise<void> {
  try {
    // Extract filename from URL
    const filename = imageUrl.split('/').pop();
    if (!filename) return;
    
    const response = await fetch(DELETE_ENDPOINT, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ filename }),
    });
    
    if (!response.ok) {
      console.error('Failed to delete image from external server');
    } else {
      console.log('Image deleted successfully:', filename);
    }
  } catch (error) {
    console.error('Error deleting from external server:', error);
  }
}

// In your API route (app/api/products/route.ts)
// export async function GET(request: NextRequest) {
//   try {
//     await dbConnect();

//     const { searchParams } = new URL(request.url);
//     const page = parseInt(searchParams.get('page') || '1');
//     const limit = parseInt(searchParams.get('limit') || '10');
//     const category = searchParams.get('category');
//     const isActive = searchParams.get('isActive');
//     const search = searchParams.get('search');
//     const sort = searchParams.get('sort') || 'createdAt';
//     const order = searchParams.get('order') || 'asc';

//     let query: any = {};

//     if (category) query.category = category;
//     if (isActive !== null && isActive !== undefined) {
//       query.isActive = isActive === 'true';
//     }
//     if (search) {
//       query.$or = [
//         { name: { $regex: search, $options: 'i' } },
//         { description: { $regex: search, $options: 'i' } }
//       ];
//     }

//     const skip = (page - 1) * limit;

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

//     const products = await Product.find(query)
//       .populate('category', 'name slug')
//       .populate('subcategory', 'name slug')
//       .sort(sortOptions)
//       .skip(skip)
//       .limit(limit);

//     const total = await Product.countDocuments(query);

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

//   } catch (error: any) {
//     console.error('Error fetching products:', error);
//     return NextResponse.json(
//       { success: false, error: error.message || 'Failed to fetch products' },
//       { status: 500 }
//     ); 
//   }
// }
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 category = searchParams.get('category');
    const isActive = searchParams.get('isActive');
    const search = searchParams.get('search');
    const sort = searchParams.get('sort') || 'createdAt';
    const order = searchParams.get('order') || 'asc';
 
    let query: any = {};
 
    // if (category) query.category = category;
    if (isActive !== null && isActive !== undefined) {
      query.isActive = isActive === 'true';
    }
    if (search) {
      // lookup filter
      const categoryMatch = await Category.find({
        name: { $regex: search, $options: "i" }
      });
 
      const categoryIds = categoryMatch.map(c => c._id);
 
      query.$or = [
        { name: { $regex: search, $options: "i" } },
        { category: { $in: categoryIds } }
      ];
    }
 
    const skip = (page - 1) * limit;
 
    // Create sort object
    const sortOptions: any = {};
    if (search) {
      // Always sort alphabetically when searching
      sortOptions.name = 1;
    }
    else if (sort === 'createdAt') {
      sortOptions.createdAt = order === 'asc' ? 1 : -1;
    }
    //else if (sort === 'category') {
    //   sortOptions['category.name'] = order === 'asc' ? 1 : -1;
    // }
    else {
      sortOptions.name = order === 'asc' ? 1 : -1;
    }
 
    const products = await Product.find(query)
      .populate('category', 'name slug')
      .populate('subcategory', 'name slug')
      .sort(sortOptions)
      .skip(skip)
      .limit(limit);
 
    const total = await Product.countDocuments(query);
 
    return NextResponse.json({
      success: true,
      data: products,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit)
      }
    });
 
  } catch (error: any) {
    console.error('Error fetching products:', error);
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to fetch products' },
      { status: 500 }
    );
  }
}
export async function POST(request: NextRequest) {
  try {
    await dbConnect();

    const formData = await request.formData();

    const name = formData.get('name') as string;
    const description = formData.get('description') as string;
    const shortDescription = formData.get('shortDescription') as string;
    const category = formData.get('category') as string;
    const subcategory = formData.get('subcategory') as string;
    const price = parseFloat(formData.get('price') as string);
    const weight = parseFloat(formData.get('weight') as string);
    const length = parseFloat(formData.get('length') as string);
    const width = parseFloat(formData.get('width') as string);
    const height = parseFloat(formData.get('height') as string);
    const isActive = formData.get('isActive') === 'true';
    const isFeatured = formData.get('isFeatured') === 'true';
    const file = formData.get('defaultImage') as File;

    // Validation
    if(weight <= 0) {
      return NextResponse.json({ success: false, error: 'Weight must be greater than 0' }, { status: 400 });
    }
    if (!name?.trim()) {
      return NextResponse.json({ success: false, error: 'Product name is required' }, { status: 400 });
    }
    if (!description?.trim()) {
      return NextResponse.json({ success: false, error: 'Product description is required' }, { status: 400 });
    }
    if (!category) {
      return NextResponse.json({ success: false, error: 'Category is required' }, { status: 400 });
    }

    const categoryExists = await Category.findById(category);
    if (!categoryExists) {
      return NextResponse.json({ success: false, error: 'Invalid category' }, { status: 400 });
    }

    if (subcategory) {
      const subExists = await Category.findById(subcategory);
      if (!subExists) {
        return NextResponse.json({ success: false, error: 'Invalid subcategory' }, { status: 400 });
      }
    }

    // Handle default image upload to external server
    let defaultImageUrl = '';
    if (file && file.size > 0) {
      defaultImageUrl = await uploadToExternalServer(file);
    }

    const slug = makeSlug(name);

    const product = await Product.create({
      name: name.trim(),
      slug,
      description: description.trim(),
      shortDescription: shortDescription?.trim(),
      category,
      subcategory: subcategory || undefined,
      price,
      defaultImage: defaultImageUrl || null,
      weight,
      dimensions: { length, width, height },
      isActive,
      isFeatured
    });

    const populated = await Product.findById(product._id)
      .populate('category', 'name slug')
      .populate('subcategory', 'name slug');

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

  } catch (error: any) {
    console.error('Error creating product:', error);
    if (error.code === 11000) {
      return NextResponse.json({ success: false, error: 'Product slug already exists' }, { status: 400 });
    }
    return NextResponse.json({ success: false, error: error.message || 'Failed to create product' }, { status: 500 });
  }
}

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: 'Product ID is required' }, { status: 400 });
    }

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

    const name = formData.get('name') as string;
    const description = formData.get('description') as string;
    const shortDescription = formData.get('shortDescription') as string;
    const category = formData.get('category') as string;
    const subcategory = formData.get('subcategory') as string;
    const price = parseFloat(formData.get('price') as string);
    const weight = parseFloat(formData.get('weight') as string);
    const length = parseFloat(formData.get('length') as string);
    const width = parseFloat(formData.get('width') as string);
    const height = parseFloat(formData.get('height') as string);
    const isActive = formData.get('isActive') === 'true';
    const isFeatured = formData.get('isFeatured') === 'true';
    const file = formData.get('defaultImage') as File;
    const removeImage = formData.get('removeImage');
        if(weight <= 0) {
      return NextResponse.json({ success: false, error: 'Weight must be greater than 0' }, { status: 400 });
    }
    // Handle image update
    let defaultImageUrl = existingProduct.defaultImage;
    if (file && file.size > 0) {
      // Delete old image from external server if exists
      if (existingProduct.defaultImage && existingProduct.defaultImage.includes('quality-web-developer.com/dulhe_sahebimages')) {
        await deleteFromExternalServer(existingProduct.defaultImage);
      }
      
      // Upload new image to external server
      defaultImageUrl = await uploadToExternalServer(file);
    } else if(!file && removeImage) {
      await deleteFromExternalServer(existingProduct.defaultImage);
    }

    const slug = makeSlug(name);

    const updatedProduct = await Product.findByIdAndUpdate(
      id,
      {
        name: name.trim(),
        slug,
        description: description.trim(),
        shortDescription: shortDescription?.trim(),
        category,
        subcategory: subcategory || undefined,
        defaultImage: defaultImageUrl,
        weight,
        price,
        dimensions: { length, width, height },
        isActive,
        isFeatured
      },
      { new: true, runValidators: true }
    ).populate('category', 'name slug')
     .populate('subcategory', 'name slug');

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

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

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: 'Product ID is required' }, { status: 400 });
    }

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

    // Prevent deletion if product has reviews
    const hasReviews = await Review.exists({ product: id });
    if (hasReviews) {
      return NextResponse.json(
        { success: false, error: 'Cannot delete product because it has one or more reviews' },
        { status: 400 }
      );
    }

    // Delete image from external server if exists
    if (product.defaultImage && product.defaultImage.includes('quality-web-developer.com/dulhe_sahebimages')) {
      await deleteFromExternalServer(product.defaultImage);
    }

    await Product.findByIdAndDelete(id);

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

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