// 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";
import ProductSKU from "@/models/ProductSKU";
import ProductColorImage from "@/models/ProductColorImage";

// 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 productprice = parseFloat(formData.get("productprice") 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,
      productprice,
      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 productprice = parseFloat(formData.get("productprice") 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,
        productprice,
        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);
    await ProductSKU.deleteMany({ product: id });
    await ProductColorImage.deleteMany({ product: 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 },
    );
  }
}
