const asyncHandler = require('../middleware/async');
const ErrorResponse = require('../utils/errorResponse');
const Order = require('../models/Order');

/**
 * @desc    Get sales report
 * @route   GET /api/v1/reports/sales
 * @access  Private/Admin
 */
exports.getSalesReport = asyncHandler(async (req, res, next) => {
  const { startDate, endDate, period = 'daily' } = req.query;

  // Validate required parameters
  if (!startDate || !endDate) {
    return next(
      new ErrorResponse('Please provide startDate and endDate parameters', 400)
    );
  }

  // Validate period
  const validPeriods = ['daily', 'weekly', 'monthly', 'yearly'];
  if (!validPeriods.includes(period)) {
    return next(
      new ErrorResponse(
        `Invalid period. Must be one of: ${validPeriods.join(', ')}`,
        400
      )
    );
  }

  try {
    // Convert dates to start and end of day for the query
    const startOfDay = new Date(startDate);
    startOfDay.setHours(0, 0, 0, 0);
    
    const endOfDay = new Date(endDate);
    endOfDay.setHours(23, 59, 59, 999);

    // Build match conditions
    const matchConditions = {
      createdAt: { $gte: startOfDay, $lte: endOfDay },
      status: { $nin: ['cancelled', 'failed'] } // Exclude cancelled/failed orders
    };

    // If user is a customer, only show their orders
    if (req.user.role === 'customer') {
      matchConditions.user = req.user.id;
    }

    // Group orders by date and calculate metrics
    const salesByDate = await Order.aggregate([
      {
        $match: matchConditions
      },
      {
        $group: {
          _id: {
            $dateToString: {
              format: '%Y-%m-%d',
              date: '$createdAt',
              timezone: 'Asia/Kolkata' // Adjust timezone as needed
            }
          },
          date: { $first: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } } },
          sales: { $sum: { $size: '$items' } },
          revenue: { $sum: '$totalAmount' },
          orders: { $sum: 1 },
          customerCount: { $addToSet: '$user' }
        }
      },
      {
        $project: {
          _id: 0,
          date: 1,
          sales: 1,
          revenue: 1,
          orders: 1,
          customers: { $size: '$customerCount' }
        }
      },
      { $sort: { date: 1 } }
    ]);

    // Get top selling products
    const topProducts = await Order.aggregate([
      {
        $match: {
          createdAt: { $gte: startOfDay, $lte: endOfDay },
          status: { $nin: ['cancelled', 'failed'] }
        }
      },
      { $unwind: '$items' },
      {
        $group: {
          _id: '$items.item',
          name: { $first: '$items.name' },
          sales: { $sum: '$items.quantity' },
          revenue: { $sum: { $multiply: ['$items.quantity', '$items.price'] } }
        }
      },
      { $sort: { sales: -1 } },
      { $limit: 5 },
      {
        $project: {
          _id: 0,
          id: '$_id',
          name: 1,
          revenue: 1
        }
      }
    ]);

    // Calculate summary metrics
    const summary = await Order.aggregate([
      {
        $match: {
          createdAt: { $gte: startOfDay, $lte: endOfDay },
          status: { $nin: ['cancelled', 'failed'] }
        }
      },
      {
        $group: {
          _id: null,
          totalSales: { $sum: { $size: '$items' } },
          totalRevenue: { $sum: '$totalAmount' },
          totalOrders: { $sum: 1 },
          uniqueCustomers: { $addToSet: '$user' },
          orderValues: { $push: '$totalAmount' }
        }
      },
      {
        $project: {
          _id: 0,
          totalSales: 1,
          totalRevenue: 1,
          totalOrders: 1,
          totalCustomers: { $size: '$uniqueCustomers' },
          averageOrderValue: { $divide: ['$totalRevenue', '$totalOrders'] },
          conversionRate: { $literal: null } // Set to null as we don't have session data
        }
      }
    ]);

    // Format the response to match frontend expectations
    const result = {
      success: true,
      data: {
        salesData: [], // Empty array as we're not using this yet
        topProducts: topProducts || [],
        summary: {
          ...(summary[0] || {}),
          startDate,
          endDate,
          period
        }
      }
    };

    console.log('Sales report generated:', result);
    res.status(200).json(result);
  } catch (err) {
    next(err);
  }
});

/**
 * @desc    Export sales report
 * @route   GET /api/v1/reports/sales/export
 * @access  Private/Admin
 */
exports.exportSalesReport = asyncHandler(async (req, res, next) => {
  // TODO: Implement export functionality
  res.status(200).json({
    success: true,
    data: {
      message: 'Export functionality will be implemented here',
      query: req.query
    }
  });
});

/**
 * @desc    Get available report periods
 * @route   GET /api/v1/reports/periods
 * @access  Private/Admin
 */
exports.getReportPeriods = asyncHandler(async (req, res, next) => {
  res.status(200).json({
    success: true,
    data: [
      { value: 'daily', label: 'Daily' },
      { value: 'weekly', label: 'Weekly' },
      { value: 'monthly', label: 'Monthly' },
      { value: 'yearly', label: 'Yearly' }
    ]
  });
});
