const mongoose = require('mongoose');
const HomepageSection = require('../models/HomepageSection');
const Item = require('../models/Item');
const Category = require('../models/Category');
const ApiError = require('../utils/ApiError');
const catchAsync = require('../middleware/async');
const httpStatus = require('../utils/httpStatus');

/**
 * Create a new homepage section
 * @route POST /api/v1/homepage-sections
 * @access Private/Admin
 */
exports.createHomepageSection = catchAsync(async (req, res, next) => {
  // Ensure only admin can create sections
  if (req.user.role !== 'admin') {
    return next(new ApiError('Only admins can create homepage sections', httpStatus.FORBIDDEN));
  }

  const { 
    productType, 
    categoryIds, 
    products: customProducts 
  } = req.body;

  // Validate and prepare products based on product type
  let products = [];
  if (productType === 'custom_products' && customProducts) {
    // For custom products, verify each one is active (status = 1)
    const ItemModel = mongoose.model('Item');
    const activeProducts = await ItemModel.find({
      _id: { $in: customProducts },
      status: 1 // 1 = active, 0 = inactive
    }).select('_id').lean().exec();
    
    products = activeProducts.map(p => p._id);
  } else {
    // Dynamic product selection based on type and categories
    const query = {
      status: 1 // Only include active products (1 = active, 0 = inactive)
    };

    // Filter by categories if provided
    if (categoryIds && categoryIds.length > 0) {
      query.category_id = { $in: categoryIds };
    }

    // Apply product type filters
    switch (productType) {
      case 'new_added_products':
        // Products added in the last 30 days
        query.createdAt = { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) };
        break;
      case 'products_on_sale':
        // Products with a discount
        query.discount = { $exists: true, $ne: null };
        break;
      case 'most_selling_products':
        // Sort by sales count (assuming you have a sales count field)
        query.salesCount = { $exists: true };
        break;
      // 'all_products' doesn't need additional filtering
    }

    // Get the model directly from mongoose
    const ItemModel = mongoose.model('Item');
    let fetchedProducts;
    
    // Build the query
    const findQuery = ItemModel.find(query);
    
    // Apply sorting based on product type
    if (productType === 'most_selling_products') {
      findQuery.sort('-salesCount');
    } else {
      findQuery.sort('-createdAt');
    }
    
    // Execute the query
    // For 'all_products', don't apply limit to get all active products
    if (productType === 'all_products') {
      findQuery.select('_id');
    } else {
      findQuery.limit(20).select('_id');
    }
    
    fetchedProducts = await findQuery.lean().exec();

    products = fetchedProducts.map(p => p._id);
  }

  // Create the section with prepared products
  const sectionData = {
    ...req.body,
    products
  };

  const section = await HomepageSection.create(sectionData);

  res.status(httpStatus.CREATED).json({
    success: true,
    data: section
  });
});

/**
 * Get homepage section by ID
 * @route GET /api/v1/homepage-sections/:id
 * @access Private/Admin
 */
exports.getHomepageSectionById = catchAsync(async (req, res, next) => {
  const section = await HomepageSection.findById(req.params.id)
    .populate([
      {
        path: 'products',
        select: '_id name price images status',
        match: { status: 1 } // Only include active products
      },
      {
        path: 'categoryIds',
        select: 'name'
      }
    ]);

  if (!section) {
    return next(new ApiError(`No homepage section found with id of ${req.params.id}`, httpStatus.NOT_FOUND));
  }

  res.status(httpStatus.OK).json({
    success: true,
    data: section
  });
});

/**
 * Get all homepage sections
 * @route GET /api/v1/homepage-sections
 * @access Public
 */
exports.getHomepageSections = catchAsync(async (req, res, next) => {
  // Get only active sections, sorted by sortOrder
  const sections = await HomepageSection.find()
    .sort('sortOrder')
    .populate([
      {
        path: 'products',
        select: 'name price'
      },
      {
        path: 'categoryIds',
        select: 'name'
      }
    ]);

  res.status(httpStatus.OK).json({
    success: true,
    count: sections.length,
    data: sections
  });
});

/**
 * Update a homepage section
 * @route PUT /api/v1/homepage-sections/:id
 * @access Private/Admin
 */
exports.updateHomepageSection = catchAsync(async (req, res, next) => {
  // Ensure only admin can update sections
  if (req.user.role !== 'admin') {
    return next(new ApiError('Only admins can update homepage sections', httpStatus.FORBIDDEN));
  }

  const { 
    productType, 
    categoryIds, 
    products: customProducts 
  } = req.body;

  // Prepare products similar to create method
  let products = [];
  if (productType === 'custom_products' && customProducts) {
    // For custom products, verify each one is active (status = 1)
    const activeProducts = await Item.model.find({
      _id: { $in: customProducts },
      status: 1 // 1 = active, 0 = inactive
    }).select('_id').lean().exec();
    
    products = activeProducts.map(p => p._id);
  } else {
    const query = {
      status: 1 // Only include active products (1 = active, 0 = inactive)
    };

    if (categoryIds && categoryIds.length > 0) {
      query.category_id = { $in: categoryIds };
    }

    switch (productType) {
      case 'new_added_products':
        query.createdAt = { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) };
        break;
      case 'products_on_sale':
        query.discount = { $exists: true, $ne: null };
        break;
      case 'most_selling_products':
        query.salesCount = { $exists: true };
        break;
    }

    // Build the query
    const findQuery = Item.model.find(query);
    
    // Apply sorting
    if (productType === 'most_selling_products') {
      findQuery.sort({ salesCount: -1 });
    } else {
      findQuery.sort({ createdAt: -1 });
    }
    
    // For 'all_products', don't apply limit to get all active products
    if (productType === 'all_products') {
      findQuery.select('_id');
    } else {
      findQuery.limit(20).select('_id');
    }
    
    const fetchedProducts = await findQuery.lean().exec();

    products = fetchedProducts.map(p => p._id);
  }

  // Update the section with prepared products
  const sectionData = {
    ...req.body,
    products,
    updatedAt: Date.now()
  };

  const section = await HomepageSection.findByIdAndUpdate(
    req.params.id, 
    sectionData, 
    { 
      new: true, 
      runValidators: true 
    }
  );

  if (!section) {
    return next(new ApiError(`No section found with id ${req.params.id}`, httpStatus.NOT_FOUND));
  }

  res.status(httpStatus.OK).json({
    success: true,
    data: section
  });
});

/**
 * Delete a homepage section
 * @route DELETE /api/v1/homepage-sections/:id
 * @access Private/Admin
 */
exports.deleteHomepageSection = catchAsync(async (req, res, next) => {
  // Ensure only admin can delete sections
  if (req.user.role !== 'admin') {
    return next(new ApiError('Only admins can delete homepage sections', httpStatus.FORBIDDEN));
  }

  const section = await HomepageSection.findByIdAndDelete(req.params.id);

  if (!section) {
    return next(new ApiError(`No section found with id ${req.params.id}`, httpStatus.NOT_FOUND));
  }

  res.status(httpStatus.NO_CONTENT).json({
    success: true,
    data: {}
  });
});

/**
 * Reorder homepage sections
 * @route PUT /api/v1/homepage-sections/reorder
 * @access Private/Admin
 */
exports.reorderHomepageSections = catchAsync(async (req, res, next) => {
  // Ensure only admin can reorder sections
  if (req.user.role !== 'admin') {
    return next(new ApiError('Only admins can reorder homepage sections', httpStatus.FORBIDDEN));
  }

  const { sections } = req.body;

  // Validate input
  if (!Array.isArray(sections)) {
    return next(new ApiError('Invalid sections data', httpStatus.BAD_REQUEST));
  }

  // Bulk update sections with their new order
  const bulkOps = sections.map((section, index) => ({
    updateOne: {
      filter: { _id: section._id },
      update: { sortOrder: index + 1 }
    }
  }));

  await HomepageSection.bulkWrite(bulkOps);

  res.status(httpStatus.OK).json({
    success: true,
    message: 'Sections reordered successfully'
  });
});

/**
 * Get homepage sections for frontend display
 * @route GET /api/v1/homepage-sections/display
 * @access Public
 */
exports.getDisplayHomepageSections = catchAsync(async (req, res, next) => {
  // Get active sections with their products, sorted by sortOrder
  const sections = await HomepageSection.find({
    $or: [
      { isActive: true },
      { status: 'active' }
    ]
  })
    .sort('sortOrder')
    .populate([
      {
        path: 'products',
        select: 'name price image description discount originalPrice category_id brand_id'
      },
      {
        path: 'categoryIds',
        select: 'name'
      }
    ])
    .lean();

  res.status(httpStatus.OK).json({
    success: true,
    count: sections.length,
    data: sections
  });
});

