// controllers/customerController.js
'use strict';

const { Op } = require('sequelize');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { 
  Customer, 
  Transaction, 
  CustomerAddress, 
  Order,
  User,
  OrderItem,
  OrderStatus,
  Product,
  Review,
  Wishlist,
  Payment,
  sequelize
} = require('../models');

// ============================================
// 📊 DASHBOARD & ANALYTICS
// ============================================


// ============================================
// 📊 DASHBOARD & ANALYTICS
// ============================================

/**
 * Get customer dashboard statistics
 * @route GET /api/customers/:id/dashboard
 */
exports.getCustomerDashboard = async (req, res) => {
  try {
    const customerId = req.params.id;

    // Verify customer exists
    const customer = await Customer.findByPk(customerId);
    if (!customer) {
      return res.status(404).json({ 
        success: false, 
        message: 'Customer not found' 
      });
    }

    // Get all orders with their latest status
    const orders = await Order.findAll({
      where: { customerId },
      include: [
        { 
          model: OrderItem, 
          as: 'items',
          include: [{ model: Product, as: 'product' }]
        },
        {
          model: OrderStatus,
          as: 'statuses',
          separate: true,
          order: [['createdAt', 'DESC']],
          limit: 1
        }
      ],
      order: [['orderDate', 'DESC']]
    });

    // Calculate statistics
    const totalOrders = orders.length;
    const activeOrders = orders.filter(o => {
      const latestStatus = o.statuses && o.statuses[0];
      return latestStatus && ['pending', 'confirmed', 'processing', 'shipped'].includes(latestStatus.status);
    }).length;
    
    const paidOrders = orders.filter(o => o.paymentStatus === 'paid');
    const totalSpent = paidOrders.reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);
    const avgOrderValue = totalOrders > 0 ? totalSpent / totalOrders : 0;
    
    // Calculate loyalty points (0.5 points per KSh spent)
    const rewardPoints = Math.floor(totalSpent * 0.5);
    
    // Get trends (compare with previous month)
    const currentMonth = new Date();
    const lastMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1);
    
    const currentMonthOrders = orders.filter(o => 
      new Date(o.orderDate) >= lastMonth
    );
    const lastMonthOrders = orders.filter(o => {
      const orderDate = new Date(o.orderDate);
      return orderDate >= new Date(lastMonth.getFullYear(), lastMonth.getMonth() - 1, 1) &&
             orderDate < lastMonth;
    });
    
    const ordersChange = lastMonthOrders.length > 0 
      ? ((currentMonthOrders.length - lastMonthOrders.length) / lastMonthOrders.length * 100)
      : currentMonthOrders.length > 0 ? 100 : 0;
    
    const currentMonthSpent = currentMonthOrders
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);
    
    const lastMonthSpent = lastMonthOrders
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);
    
    const spendingChange = lastMonthSpent > 0 
      ? ((currentMonthSpent - lastMonthSpent) / lastMonthSpent * 100)
      : currentMonthSpent > 0 ? 100 : 0;

    // Get wishlist count
    const wishlistCount = await Wishlist.count({ where: { customerId } });
    
    // Get reviews count
    const reviewsCount = await Review.count({ where: { customerId } });
    
    // Calculate savings (assuming 10% average discount)
    const savingsTotal = totalSpent * 0.1;

    res.json({
      success: true,
      stats: {
        totalOrders,
        activeOrders,
        totalSpent,
        rewardPoints,
        avgOrderValue,
        savingsTotal,
        wishlistCount,
        reviewsCount,
        trends: {
          ordersChange: Math.round(ordersChange),
          spendingChange: Math.round(spendingChange),
          pointsEarned: Math.floor(currentMonthSpent * 0.5)
        }
      }
    });
  } catch (error) {
    console.error('Dashboard error:', error);
    res.status(500).json({ 
      success: false, 
      message: 'Error fetching dashboard data', 
      error: error.message 
    });
  }
};

/**
 * Get customer shopping insights
 * @route GET /api/customers/:id/insights
 */
exports.getCustomerInsights = async (req, res) => {
  try {
    const customerId = req.params.id;

    const orders = await Order.findAll({
      where: { customerId },
      include: [{
        model: OrderItem,
        as: 'items',
        include: [{ model: Product, as: 'product' }]
      }]
    });

    // Most purchased categories
    const categoryPurchases = {};
    orders.forEach(order => {
      order.items?.forEach(item => {
        const category = item.product?.category || 'Other';
        categoryPurchases[category] = (categoryPurchases[category] || 0) + item.quantity;
      });
    });

    const topCategories = Object.entries(categoryPurchases)
      .sort(([, a], [, b]) => b - a)
      .slice(0, 5)
      .map(([category, count]) => ({ category, count }));

    // Shopping patterns
    const ordersByDay = {};
    orders.forEach(order => {
      const day = new Date(order.orderDate).getDay();
      const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
      const dayName = days[day];
      ordersByDay[dayName] = (ordersByDay[dayName] || 0) + 1;
    });

    // Average basket size
    const totalItems = orders.reduce((sum, order) => 
      sum + (order.items?.reduce((s, i) => s + i.quantity, 0) || 0), 0
    );
    const avgBasketSize = orders.length > 0 ? totalItems / orders.length : 0;

    res.json({
      success: true,
      insights: {
        topCategories,
        ordersByDay,
        avgBasketSize: Math.round(avgBasketSize * 10) / 10,
        totalItemsPurchased: totalItems
      }
    });
  } catch (error) {
    console.error('Insights error:', error);
    res.status(500).json({ 
      success: false, 
      message: 'Error fetching insights', 
      error: error.message 
    });
  }
};




/**
 * @route   GET /api/customers/by-user/:userId
 * @desc    Get customer by user ID
 */
exports.getCustomerByUserId = async (req, res) => {
  try {
    const customer = await Customer.findOne({
      where: { userId: req.params.userId }
    });

    if (!customer) {
      return res.status(404).json({ 
        success: false, 
        message: 'Customer record not found' 
      });
    }

    res.json({ success: true, customer });
  } catch (error) {
    res.status(500).json({ 
      success: false, 
      message: 'Error fetching customer', 
      error: error.message 
    });
  }
};

// ============================================
// 📦 ORDER MANAGEMENT WITH ORDERSTATUS MODEL
// ============================================

/**
 * Get all orders for a customer
 * @route GET /api/customers/:id/orders
 */
exports.getCustomerOrders = async (req, res) => {
  try {
    const customerId = req.params.id;
    const { 
      page = 1, 
      limit = 20, 
      status, 
      paymentStatus,
      sortBy = 'orderDate',
      sortOrder = 'DESC',
      startDate,
      endDate
    } = req.query;

    const offset = (page - 1) * limit;

    // Build where clause
    const where = { customerId };
    
    if (paymentStatus) {
      where.paymentStatus = paymentStatus;
    }

    if (startDate && endDate) {
      where.orderDate = {
        [Op.between]: [new Date(startDate), new Date(endDate)]
      };
    }

    // Get all orders first
    let orders = await Order.findAll({
      where,
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'productName', 'category', 'imageUrl']
            }
          ]
        },
        {
          model: CustomerAddress,
          as: 'shippingAddress'
        },
        {
          model: Payment,
          as: 'payments'
        },
        {
          model: OrderStatus,
          as: 'statuses',
          separate: true,
          order: [['createdAt', 'DESC']],
          limit: 1
        }
      ],
      order: [[sortBy, sortOrder.toUpperCase()]]
    });

    // Filter by status if provided
    if (status) {
      orders = orders.filter(order => {
        const latestStatus = order.statuses && order.statuses[0];
        return latestStatus && latestStatus.status === status;
      });
    }

    // Manual pagination after filtering
    const count = orders.length;
    const rows = orders.slice(offset, offset + parseInt(limit));

    // Add current status to each order for easier access
    const ordersWithStatus = rows.map(order => {
      const orderJson = order.toJSON();
      orderJson.currentStatus = orderJson.statuses && orderJson.statuses[0] 
        ? orderJson.statuses[0].status 
        : 'pending';
      return orderJson;
    });

    // Calculate summary statistics
    const totalSpent = rows
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);

    const statusBreakdown = rows.reduce((acc, order) => {
      const currentStatus = order.statuses && order.statuses[0] 
        ? order.statuses[0].status 
        : 'pending';
      acc[currentStatus] = (acc[currentStatus] || 0) + 1;
      return acc;
    }, {});

    res.json({
      success: true,
      orders: ordersWithStatus,
      summary: {
        totalOrders: count,
        totalSpent,
        statusBreakdown
      },
      pagination: {
        total: count,
        totalPages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get customer orders error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching customer orders',
      error: error.message
    });
  }
};

/**
 * Get a specific order for a customer
 * @route GET /api/customers/:id/orders/:orderId
 */
exports.getCustomerOrderById = async (req, res) => {
  try {
    const { id: customerId, orderId } = req.params;

    const order = await Order.findOne({
      where: { 
        id: orderId,
        customerId 
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product'
            }
          ]
        },
        {
          model: CustomerAddress,
          as: 'shippingAddress'
        },
        {
          model: CustomerAddress,
          as: 'billingAddress'
        },
        {
          model: Payment,
          as: 'payments',
          order: [['processedAt', 'DESC']]
        },
        {
          model: Transaction,
          as: 'transaction'
        },
        {
          model: OrderStatus,
          as: 'statuses',
          order: [['createdAt', 'DESC']]
        }
      ]
    });

    if (!order) {
      return res.status(404).json({
        success: false,
        message: 'Order not found or does not belong to this customer'
      });
    }

    const orderJson = order.toJSON();
    orderJson.currentStatus = orderJson.statuses && orderJson.statuses[0] 
      ? orderJson.statuses[0].status 
      : 'pending';

    res.json({
      success: true,
      order: orderJson
    });
  } catch (error) {
    console.error('Get order by ID error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching order details',
      error: error.message
    });
  }
};

/**
 * Get active orders (pending, confirmed, processing, shipped)
 * @route GET /api/customers/:id/orders/active
 */
exports.getActiveOrders = async (req, res) => {
  try {
    const customerId = req.params.id;

    const orders = await Order.findAll({
      where: { customerId },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'productName', 'imageUrl']
            }
          ]
        },
        {
          model: OrderStatus,
          as: 'statuses',
          separate: true,
          order: [['createdAt', 'DESC']],
          limit: 1
        }
      ],
      order: [['orderDate', 'DESC']]
    });

    // Filter active orders
    const activeOrders = orders.filter(order => {
      const latestStatus = order.statuses && order.statuses[0];
      return latestStatus && ['pending', 'confirmed', 'processing', 'shipped'].includes(latestStatus.status);
    }).map(order => {
      const orderJson = order.toJSON();
      orderJson.currentStatus = orderJson.statuses[0].status;
      return orderJson;
    });

    res.json({
      success: true,
      activeOrders,
      count: activeOrders.length
    });
  } catch (error) {
    console.error('Get active orders error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching active orders',
      error: error.message
    });
  }
};

/**
 * Get order history (completed/delivered orders)
 * @route GET /api/customers/:id/orders/history
 */
exports.getOrderHistory = async (req, res) => {
  try {
    const customerId = req.params.id;
    const { page = 1, limit = 20 } = req.query;
    const offset = (page - 1) * limit;

    const orders = await Order.findAll({
      where: { customerId },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'productName', 'category', 'imageUrl']
            }
          ]
        },
        {
          model: OrderStatus,
          as: 'statuses',
          separate: true,
          order: [['createdAt', 'DESC']],
          limit: 1
        }
      ],
      order: [['orderDate', 'DESC']]
    });

    // Filter delivered orders
    const deliveredOrders = orders.filter(order => {
      const latestStatus = order.statuses && order.statuses[0];
      return latestStatus && latestStatus.status === 'delivered';
    });

    const count = deliveredOrders.length;
    const rows = deliveredOrders.slice(offset, offset + parseInt(limit));

    // Get items eligible for review
    const itemsToReview = [];
    for (const order of rows) {
      for (const item of order.items || []) {
        const existingReview = await Review.findOne({
          where: {
            customerId,
            productId: item.productId
          }
        });
        
        if (!existingReview) {
          const deliveredStatus = await OrderStatus.findOne({
            where: { 
              orderId: order.id,
              status: 'delivered'
            },
            order: [['createdAt', 'DESC']]
          });

          itemsToReview.push({
            orderId: order.id,
            orderNumber: order.orderId,
            productId: item.productId,
            productName: item.product?.productName,
            deliveredAt: deliveredStatus?.createdAt
          });
        }
      }
    }

    const ordersWithStatus = rows.map(order => {
      const orderJson = order.toJSON();
      orderJson.currentStatus = orderJson.statuses[0].status;
      return orderJson;
    });

    res.json({
      success: true,
      orderHistory: ordersWithStatus,
      itemsToReview,
      pagination: {
        total: count,
        totalPages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get order history error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching order history',
      error: error.message
    });
  }
};

/**
 * Get recent orders (last 10)
 * @route GET /api/customers/:id/orders/recent
 */
exports.getRecentOrders = async (req, res) => {
  try {
    const identifier = req.params.id; // Could be customerId or userId
    const { limit = 10 } = req.query;

    // ✅ Default to byUser=true unless explicitly set to 'false'
    const byUser = req.query.byUser !== 'false';

    let userId = null;
    let customerId = identifier;

    if (byUser) {
      console.log(`🔍 Looking up customer for user ${identifier}`);
      const customer = await Customer.findOne({
        where: { userId: identifier },
        attributes: ['id', 'userId']
      });

      if (!customer) {
        console.error(`❌ No customer found for userId ${identifier}`);
        return res.status(404).json({ success: false, message: 'Customer record not found for this user' });
      }

      customerId = customer.id;
      userId = customer.userId;
      console.log(`✅ Found customer ${customerId} for user ${identifier}`);
    } else {
      console.log(`🔍 Looking up customer by customerId ${identifier}`);
      const customer = await Customer.findByPk(identifier, { attributes: ['id', 'userId'] });

      if (!customer) {
        console.error(`❌ No customer found for customerId ${identifier}`);
        return res.status(404).json({ success: false, message: 'Customer not found' });
      }

      customerId = customer.id;
      userId = customer.userId;
      console.log(`✅ Found userId ${userId} for customer ${customerId}`);
    }

    // ✅ Query Orders using userId
    const recentOrders = await Order.findAll({
      where: { userId },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'name', 'imageUrl', 'description','categoryId', 'unitPrice']
            }
          ]
        },
        {
          model: OrderStatus,
          as: 'statuses',
          separate: true,
          order: [['createdAt', 'DESC']],
          limit: 1
        }
      ],
      order: [['createdAt', 'DESC']],
      limit: parseInt(limit)
    });

    const ordersWithStatus = recentOrders.map(order => {
      const orderJson = order.toJSON();
      orderJson.currentStatus = orderJson.statuses?.[0]?.status || 'pending';
      return orderJson;
    });

    res.json({
      success: true,
      recentOrders: ordersWithStatus,
      count: ordersWithStatus.length,
      customerId,
      userId,
      lookupMethod: byUser ? 'userId' : 'customerId'
    });
  } catch (error) {
    console.error('❌ Get recent orders error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching recent orders',
      error: error.message
    });
  }
};


/**
 * Cancel an order
 * @route PUT /api/customers/:id/orders/:orderId/cancel
 */
exports.cancelOrder = async (req, res) => {
  try {
    const { id: customerId, orderId } = req.params;
    const { reason, updatedBy } = req.body;

    const order = await Order.findOne({
      where: {
        id: orderId,
        customerId
      },
      include: [{
        model: OrderStatus,
        as: 'statuses',
        separate: true,
        order: [['createdAt', 'DESC']],
        limit: 1
      }]
    });

    if (!order) {
      return res.status(404).json({
        success: false,
        message: 'Order not found or does not belong to this customer'
      });
    }

    const currentStatus = order.statuses && order.statuses[0] 
      ? order.statuses[0].status 
      : 'pending';

    // Can only cancel pending or confirmed orders
    if (!['pending', 'confirmed'].includes(currentStatus)) {
      return res.status(400).json({
        success: false,
        message: 'Order cannot be cancelled. Only pending or confirmed orders can be cancelled.',
        currentStatus
      });
    }

    // Create new cancelled status
    await OrderStatus.create({
      orderId: order.id,
      status: 'cancelled',
      description: reason || 'Customer requested cancellation',
      updatedBy: updatedBy || customerId
    });

    // If payment was made, initiate refund
    if (order.paymentStatus === 'paid') {
      const payment = await Payment.findOne({
        where: {
          transactionId: order.transactionId,
          status: 'completed'
        }
      });

      if (payment) {
        await Payment.create({
          transactionId: order.transactionId,
          paymentMethod: payment.paymentMethod,
          amount: -order.totalAmount,
          status: 'pending',
          referenceNumber: `REF-${payment.referenceNumber}`,
          processedAt: new Date()
        });
      }
    }

    res.json({
      success: true,
      message: 'Order cancelled successfully',
      order: {
        id: order.id,
        orderId: order.orderId,
        status: 'cancelled'
      }
    });
  } catch (error) {
    console.error('Cancel order error:', error);
    res.status(500).json({
      success: false,
      message: 'Error cancelling order',
      error: error.message
    });
  }
};

/**
 * Track order shipment
 * @route GET /api/customers/:id/orders/:orderId/track
 */
exports.trackOrder = async (req, res) => {
  try {
    const { id: customerId, orderId } = req.params;

    const order = await Order.findOne({
      where: {
        id: orderId,
        customerId
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [{ model: Product, as: 'product' }]
        },
        {
          model: OrderStatus,
          as: 'statuses',
          order: [['createdAt', 'ASC']]
        }
      ]
    });

    if (!order) {
      return res.status(404).json({
        success: false,
        message: 'Order not found'
      });
    }

    // Build timeline from status history
    const timeline = order.statuses.map(status => ({
      status: status.status,
      timestamp: status.createdAt,
      completed: true,
      description: status.description || getStatusDescription(status.status)
    }));

    const currentStatus = order.statuses[order.statuses.length - 1];

    const trackingInfo = {
      orderId: order.orderId,
      currentStatus: currentStatus?.status || 'pending',
      orderDate: order.orderDate,
      estimatedDelivery: order.estimatedDelivery,
      timeline
    };

    res.json({
      success: true,
      tracking: trackingInfo
    });
  } catch (error) {
    console.error('Track order error:', error);
    res.status(500).json({
      success: false,
      message: 'Error tracking order',
      error: error.message
    });
  }
};

/**
 * Get order statistics
 * @route GET /api/customers/:id/orders/statistics
 */
exports.getOrderStatistics = async (req, res) => {
  try {
    const customerId = req.params.id;

    const orders = await Order.findAll({
      where: { customerId },
      include: [
        {
          model: OrderItem,
          as: 'items'
        },
        {
          model: OrderStatus,
          as: 'statuses',
          separate: true,
          order: [['createdAt', 'DESC']],
          limit: 1
        }
      ]
    });

    const stats = {
      totalOrders: orders.length,
      completedOrders: 0,
      activeOrders: 0,
      cancelledOrders: 0,
      totalSpent: orders
        .filter(o => o.paymentStatus === 'paid')
        .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0),
      avgOrderValue: 0,
      totalItems: orders.reduce((sum, o) => 
        sum + (o.items?.reduce((s, i) => s + i.quantity, 0) || 0), 0
      ),
      byStatus: {},
      byMonth: {}
    };

    // Count orders by status
    orders.forEach(order => {
      const currentStatus = order.statuses && order.statuses[0] 
        ? order.statuses[0].status 
        : 'pending';
      
      stats.byStatus[currentStatus] = (stats.byStatus[currentStatus] || 0) + 1;

      if (currentStatus === 'delivered') stats.completedOrders++;
      if (['pending', 'confirmed', 'processing', 'shipped'].includes(currentStatus)) stats.activeOrders++;
      if (currentStatus === 'cancelled') stats.cancelledOrders++;
    });

    stats.avgOrderValue = stats.totalOrders > 0 
      ? stats.totalSpent / stats.totalOrders 
      : 0;

    // Group by month
    orders.forEach(order => {
      const monthKey = new Date(order.orderDate).toISOString().substr(0, 7);
      if (!stats.byMonth[monthKey]) {
        stats.byMonth[monthKey] = { count: 0, total: 0 };
      }
      stats.byMonth[monthKey].count++;
      if (order.paymentStatus === 'paid') {
        stats.byMonth[monthKey].total += Number(order.totalAmount || 0);
      }
    });

    res.json({
      success: true,
      statistics: stats
    });
  } catch (error) {
    console.error('Order statistics error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching order statistics',
      error: error.message
    });
  }
};

// ============================================
// 🎖️ HELPER FUNCTIONS
// ============================================

/**
 * Get status description
 */
function getStatusDescription(status) {
  const descriptions = {
    'pending': 'Order placed successfully',
    'confirmed': 'Order confirmed and being prepared',
    'processing': 'Order is being processed',
    'shipped': 'Order has been shipped',
    'delivered': 'Order delivered successfully',
    'cancelled': 'Order has been cancelled',
    'refunded': 'Order has been refunded',
    'failed': 'Order processing failed'
  };
  return descriptions[status] || status;
}

/**
 * Get customer dashboard statistics
 * @route GET /api/customers/:id/dashboard
 */
exports.getCustomerDashboard = async (req, res) => {
  try {
    const customerId = req.params.id;

    // Verify customer exists
    const customer = await Customer.findByPk(customerId);
    if (!customer) {
      return res.status(404).json({ 
        success: false, 
        message: 'Customer not found' 
      });
    }

    // Get all orders
    const orders = await Order.findAll({
      where: { customerId },
      include: [
        { 
          model: OrderItem, 
          as: 'items',
          include: [{ model: Product, as: 'product' }]
        }
      ],
      order: [['orderDate', 'DESC']]
    });

    // Calculate statistics
    const totalOrders = orders.length;
    const activeOrders = orders.filter(o => 
      ['pending', 'confirmed', 'processing', 'shipped'].includes(o.orderStatus)
    ).length;
    
    const paidOrders = orders.filter(o => o.paymentStatus === 'paid');
    const totalSpent = paidOrders.reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);
    const avgOrderValue = totalOrders > 0 ? totalSpent / totalOrders : 0;
    
    // Calculate loyalty points (0.5 points per KSh spent)
    const rewardPoints = Math.floor(totalSpent * 0.5);
    
    // Get trends (compare with previous month)
    const currentMonth = new Date();
    const lastMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1);
    
    const currentMonthOrders = orders.filter(o => 
      new Date(o.orderDate) >= lastMonth
    );
    const lastMonthOrders = orders.filter(o => {
      const orderDate = new Date(o.orderDate);
      return orderDate >= new Date(lastMonth.getFullYear(), lastMonth.getMonth() - 1, 1) &&
             orderDate < lastMonth;
    });
    
    const ordersChange = lastMonthOrders.length > 0 
      ? ((currentMonthOrders.length - lastMonthOrders.length) / lastMonthOrders.length * 100)
      : currentMonthOrders.length > 0 ? 100 : 0;
    
    const currentMonthSpent = currentMonthOrders
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);
    
    const lastMonthSpent = lastMonthOrders
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);
    
    const spendingChange = lastMonthSpent > 0 
      ? ((currentMonthSpent - lastMonthSpent) / lastMonthSpent * 100)
      : currentMonthSpent > 0 ? 100 : 0;

    // Get wishlist count
    const wishlistCount = await Wishlist.count({ where: { customerId } });
    
    // Get reviews count
    const reviewsCount = await Review.count({ where: { customerId } });
    
    // Calculate savings (assuming 10% average discount)
    const savingsTotal = totalSpent * 0.1;

    res.json({
      success: true,
      stats: {
        totalOrders,
        activeOrders,
        totalSpent,
        rewardPoints,
        avgOrderValue,
        savingsTotal,
        wishlistCount,
        reviewsCount,
        trends: {
          ordersChange: Math.round(ordersChange),
          spendingChange: Math.round(spendingChange),
          pointsEarned: Math.floor(currentMonthSpent * 0.5)
        }
      }
    });
  } catch (error) {
    console.error('Dashboard error:', error);
    res.status(500).json({ 
      success: false, 
      message: 'Error fetching dashboard data', 
      error: error.message 
    });
  }
};

/**
 * Get customer shopping insights
 * @route GET /api/customers/:id/insights
 */
exports.getCustomerInsights = async (req, res) => {
  try {
    const customerId = req.params.id;

    const orders = await Order.findAll({
      where: { customerId },
      include: [{
        model: OrderItem,
        as: 'items',
        include: [{ model: Product, as: 'product' }]
      }]
    });

    // Most purchased categories
    const categoryPurchases = {};
    orders.forEach(order => {
      order.items?.forEach(item => {
        const category = item.product?.category || 'Other';
        categoryPurchases[category] = (categoryPurchases[category] || 0) + item.quantity;
      });
    });

    const topCategories = Object.entries(categoryPurchases)
      .sort(([, a], [, b]) => b - a)
      .slice(0, 5)
      .map(([category, count]) => ({ category, count }));

    // Shopping patterns
    const ordersByDay = {};
    orders.forEach(order => {
      const day = new Date(order.orderDate).getDay();
      const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
      const dayName = days[day];
      ordersByDay[dayName] = (ordersByDay[dayName] || 0) + 1;
    });

    // Average basket size
    const totalItems = orders.reduce((sum, order) => 
      sum + (order.items?.reduce((s, i) => s + i.quantity, 0) || 0), 0
    );
    const avgBasketSize = orders.length > 0 ? totalItems / orders.length : 0;

    res.json({
      success: true,
      insights: {
        topCategories,
        ordersByDay,
        avgBasketSize: Math.round(avgBasketSize * 10) / 10,
        totalItemsPurchased: totalItems
      }
    });
  } catch (error) {
    console.error('Insights error:', error);
    res.status(500).json({ 
      success: false, 
      message: 'Error fetching insights', 
      error: error.message 
    });
  }
};

// ============================================
// 👤 CUSTOMER MANAGEMENT
// ============================================

/**
 * Get all customers with advanced filtering
 * @route GET /api/customers
 */
// exports.getAllCustomers = async (req, res) => {
//   try {
//     const { 
//       page = 1, 
//       limit = 20, 
//       search, 
//       sortBy = 'createdAt',
//       sortOrder = 'DESC',
//       tier,
//       status
//     } = req.query;
    
//     const offset = (page - 1) * limit;

//     const where = {};
    
//     // Search filter
//     if (search) {
//       where[Op.or] = [
//         { firstName: { [Op.like]: `%${search}%` } },
//         { lastName: { [Op.like]: `%${search}%` } },
//         { email: { [Op.like]: `%${search}%` } },
//         { phone: { [Op.like]: `%${search}%` } },
//       ];
//     }

//     // Tier filter
//     if (tier) {
//       where.tier = tier;
//     }

//     // Status filter
//     if (status) {
//       where.status = status;
//     }

//     const { count, rows } = await Customer.findAndCountAll({
//       where,
//       include: [
//         { 
//           model: CustomerAddress, 
//           as: 'addresses',
//           required: false
//         },
//         {
//           model: Order,
//           as: 'orders',
//           attributes: [],
//           required: false
//         }
//       ],
//       attributes: {
//         include: [
//           [sequelize.fn('COUNT', sequelize.col('orders.id')), 'totalOrders'],
//           [sequelize.fn('SUM', sequelize.col('orders.totalAmount')), 'totalSpent']
//         ]
//       },
//       group: ['Customer.id'],
//       limit: parseInt(limit),
//       offset: parseInt(offset),
//       order: [[sortBy, sortOrder.toUpperCase()]],
//       subQuery: false
//     });

//     res.json({
//       success: true,
//       customers: rows,
//       pagination: {
//         totalCustomers: count.length,
//         totalPages: Math.ceil(count.length / limit),
//         currentPage: parseInt(page),
//         limit: parseInt(limit)
//       }
//     });
//   } catch (error) {
//     console.error('Get customers error:', error);
//     res.status(500).json({ 
//       success: false, 
//       message: 'Error fetching customers', 
//       error: error.message 
//     });
//   }
// };

exports.getAllCustomers = async (req, res) => {
  try {
    const { 
      page = 1, 
      limit = 20, 
      search, 
      tier, 
      status,
      sortBy = 'createdAt', 
      sortOrder = 'DESC' 
    } = req.query;

    const offset = (page - 1) * limit;
    const whereClause = {};

    // Search filter
    if (search) {
      whereClause[Op.or] = [
        { firstName: { [Op.like]: `%${search}%` } },
        { lastName: { [Op.like]: `%${search}%` } },
        { email: { [Op.like]: `%${search}%` } },
        { phone: { [Op.like]: `%${search}%` } }
      ];
    }

    // Tier filter
    if (tier) {
      whereClause.tier = tier;
    }

    // Status filter (active/inactive)
    if (status) {
      whereClause.isActive = status === 'active';
    }

    // Get customers with basic info
    const { count, rows: customers } = await Customer.findAndCountAll({
      where: whereClause,
      limit: parseInt(limit),
      offset: parseInt(offset),
      order: [[sortBy, sortOrder]],
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['id', 'email', 'username'],
          required: false
        },
        {
          model: CustomerAddress,
          as: 'addresses',
          required: false
        }
      ]
    });

    // Calculate order statistics for each customer through their User
    const customersWithStats = await Promise.all(
      customers.map(async (customer) => {
        const customerData = customer.toJSON();
        
        // Map isActive to status for frontend
        customerData.status = customerData.isActive ? 'active' : 'inactive';
        customerData.registrationDate = customerData.createdAt;

        // Initialize default values
        customerData.totalOrders = 0;
        customerData.averageOrderValue = 0;
        customerData.lastOrderDate = customerData.lastPurchaseDate || null;

        // Get order statistics through the User association if userId exists
        if (customerData.userId) {
          try {
            const orderStats = await Order.findOne({
              where: { userId: customerData.userId },
              attributes: [
                [sequelize.fn('COUNT', sequelize.col('id')), 'totalOrders'],
                [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('totalAmount')), 0), 'totalSpent'],
                [sequelize.fn('COALESCE', sequelize.fn('AVG', sequelize.col('totalAmount')), 0), 'averageOrderValue'],
                [sequelize.fn('MAX', sequelize.col('createdAt')), 'lastOrderDate']
              ],
              raw: true
            });

            if (orderStats) {
              customerData.totalOrders = parseInt(orderStats.totalOrders) || 0;
              customerData.totalSpent = parseFloat(orderStats.totalSpent) || parseFloat(customerData.totalSpent) || 0;
              customerData.averageOrderValue = parseFloat(orderStats.averageOrderValue) || 0;
              customerData.lastOrderDate = orderStats.lastOrderDate || customerData.lastPurchaseDate;
            }
          } catch (orderError) {
            console.error(`Error fetching orders for customer ${customer.id}:`, orderError.message);
            // Keep default values
          }
        }

        return customerData;
      })
    );

    res.json({
      success: true,
      customers: customersWithStats,
      pagination: {
        currentPage: parseInt(page),
        totalPages: Math.ceil(count / limit),
        totalItems: count,
        itemsPerPage: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get customers error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching customers', 
      error: error.message 
    });
  }
};

/**
 * Search customers
 * @route GET /api/customers/search
 */
exports.searchCustomers = async (req, res) => {
  try {
    const { q } = req.query;

    if (!q || q.trim() === '') {
      return res.status(400).json({ 
        success: false, 
        message: 'Search query is required' 
      });
    }

    const customers = await Customer.findAll({
      where: {
        [Op.or]: [
          { firstName: { [Op.like]: `%${q}%` } },
          { lastName: { [Op.like]: `%${q}%` } },
          { email: { [Op.like]: `%${q}%` } },
          { phone: { [Op.like]: `%${q}%` } },
        ],
      },
      include: [{ 
        model: CustomerAddress, 
        as: 'addresses',
        required: false 
      }],
      limit: 30,
    });

    res.json({
      success: true,
      customers,
      count: customers.length
    });
  } catch (error) {
    console.error('Search error:', error);
    res.status(500).json({ 
      success: false, 
      message: 'Error searching customers', 
      error: error.message 
    });
  }
};

/**
 * Get customer by ID with full details
 * @route GET /api/customers/:id
 */
exports.getCustomerById = async (req, res) => {
  try {
    const customer = await Customer.findByPk(req.params.id, {
      include: [
        { 
          model: CustomerAddress, 
          as: 'addresses' 
        },
        { 
          model: Order, 
          as: 'orders',
          include: [
            {
              model: OrderItem,
              as: 'items',
              include: [{ model: Product, as: 'product' }]
            }
          ],
          order: [['orderDate', 'DESC']], 
          limit: 10 
        },
        {
          model: Review,
          as: 'reviews',
          include: [{ model: Product, as: 'product' }],
          limit: 5
        },
        {
          model: Wishlist,
          as: 'wishlists',
          include: [{ model: Product, as: 'product' }],
          limit: 10
        }
      ],
    });

    if (!customer) {
      return res.status(404).json({ 
        success: false, 
        message: 'Customer not found' 
      });
    }

    // Calculate additional metrics
    const totalSpent = customer.orders?.reduce((sum, o) => 
      sum + (o.paymentStatus === 'paid' ? Number(o.totalAmount || 0) : 0), 0
    ) || 0;

    const avgOrderValue = customer.orders?.length > 0 
      ? totalSpent / customer.orders.length 
      : 0;

    res.json({
      success: true,
      customer: {
        ...customer.toJSON(),
        metrics: {
          totalOrders: customer.orders?.length || 0,
          totalSpent,
          avgOrderValue,
          totalReviews: customer.reviews?.length || 0,
          wishlistItems: customer.wishlists?.length || 0
        }
      }
    });
  } catch (error) {
    console.error('Get customer error:', error);
    res.status(500).json({ 
      success: false, 
      message: 'Error fetching customer', 
      error: error.message 
    });
  }
};

/**
 * Create new customer
 * @route POST /api/customers
 */
exports.createCustomer = async (req, res) => {
  try {
    const {
      firstName,
      lastName,
      email,
      phone,
      password,
      dateOfBirth,
      gender,
      tier = 'bronze',
      status = 'active'
    } = req.body;

    // Validation
    if (!firstName || !email) {
      return res.status(400).json({
        success: false,
        message: 'First name and email are required'
      });
    }

    // Check if email already exists
    const existingCustomer = await Customer.findOne({ where: { email } });
    if (existingCustomer) {
      return res.status(409).json({
        success: false,
        message: 'Email already registered'
      });
    }

    // Hash password if provided
    let hashedPassword = null;
    if (password) {
      hashedPassword = await bcrypt.hash(password, 10);
    }

    const customer = await Customer.create({
      firstName,
      lastName,
      email,
      phone,
      password: hashedPassword,
      dateOfBirth,
      gender,
      tier,
      status,
      loyaltyPoints: 0,
      registrationDate: new Date()
    });

    // Remove password from response
    const customerData = customer.toJSON();
    delete customerData.password;

    res.status(201).json({ 
      success: true,
      message: 'Customer created successfully', 
      customer: customerData 
    });
  } catch (error) {
    console.error('Create customer error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error creating customer', 
      error: error.message 
    });
  }
};

/**
 * Update customer profile
 * @route PUT /api/customers/:id
 */
exports.updateCustomer = async (req, res) => {
  try {
    const customer = await Customer.findByPk(req.params.id);
    
    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    const {
      firstName,
      lastName,
      phone,
      dateOfBirth,
      gender,
      tier,
      status,
      profilePicture
    } = req.body;

    // Update only allowed fields
    const updateData = {};
    if (firstName !== undefined) updateData.firstName = firstName;
    if (lastName !== undefined) updateData.lastName = lastName;
    if (phone !== undefined) updateData.phone = phone;
    if (dateOfBirth !== undefined) updateData.dateOfBirth = dateOfBirth;
    if (gender !== undefined) updateData.gender = gender;
    if (tier !== undefined) updateData.tier = tier;
    if (status !== undefined) updateData.status = status;
    if (profilePicture !== undefined) updateData.profilePicture = profilePicture;

    await customer.update(updateData);

    const updatedCustomer = customer.toJSON();
    delete updatedCustomer.password;

    res.json({ 
      success: true,
      message: 'Customer updated successfully', 
      customer: updatedCustomer 
    });
  } catch (error) {
    console.error('Update customer error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error updating customer', 
      error: error.message 
    });
  }
};

/**
 * Update customer password
 * @route PUT /api/customers/:id/password
 */
exports.updatePassword = async (req, res) => {
  try {
    const { currentPassword, newPassword } = req.body;

    if (!currentPassword || !newPassword) {
      return res.status(400).json({
        success: false,
        message: 'Current password and new password are required'
      });
    }

    if (newPassword.length < 6) {
      return res.status(400).json({
        success: false,
        message: 'New password must be at least 6 characters long'
      });
    }

    const customer = await Customer.findByPk(req.params.id);
    
    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    // Verify current password
    if (customer.password) {
      const isPasswordValid = await bcrypt.compare(currentPassword, customer.password);
      if (!isPasswordValid) {
        return res.status(401).json({
          success: false,
          message: 'Current password is incorrect'
        });
      }
    }

    // Hash and update new password
    const hashedPassword = await bcrypt.hash(newPassword, 10);
    await customer.update({ password: hashedPassword });

    res.json({ 
      success: true,
      message: 'Password updated successfully'
    });
  } catch (error) {
    console.error('Update password error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error updating password', 
      error: error.message 
    });
  }
};

/**
 * Delete/Deactivate customer
 * @route DELETE /api/customers/:id
 */
exports.deleteCustomer = async (req, res) => {
  try {
    const { permanent = false } = req.query;
    const customer = await Customer.findByPk(req.params.id);
    
    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    if (permanent === 'true') {
      // Permanent deletion (use with caution)
      await customer.destroy();
      res.json({ 
        success: true,
        message: 'Customer permanently deleted' 
      });
    } else {
      // Soft delete - just deactivate
      await customer.update({ status: 'inactive' });
      res.json({ 
        success: true,
        message: 'Customer deactivated successfully' 
      });
    }
  } catch (error) {
    console.error('Delete customer error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error deleting customer', 
      error: error.message 
    });
  }
};

// ============================================
// 📍 ADDRESS MANAGEMENT
// ============================================

/**
 * Get customer addresses
 * @route GET /api/customers/:id/addresses
 */
exports.getCustomerAddresses = async (req, res) => {
  try {
    const addresses = await CustomerAddress.findAll({
      where: { customerId: req.params.id },
      order: [['isDefault', 'DESC'], ['createdAt', 'DESC']]
    });

    res.json({
      success: true,
      addresses
    });
  } catch (error) {
    console.error('Get addresses error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching addresses', 
      error: error.message 
    });
  }
};

/**
 * Add new address
 * @route POST /api/customers/:id/addresses
 */
exports.addCustomerAddress = async (req, res) => {
  try {
    const customerId = req.params.id;
    const {
      addressType,
      street,
      city,
      state,
      postalCode,
      country,
      isDefault
    } = req.body;

    // If this is set as default, unset other defaults
    if (isDefault) {
      await CustomerAddress.update(
        { isDefault: false },
        { where: { customerId } }
      );
    }

    const address = await CustomerAddress.create({
      customerId,
      addressType: addressType || 'shipping',
      street,
      city,
      state,
      postalCode,
      country: country || 'Kenya',
      isDefault: isDefault || false
    });

    res.status(201).json({
      success: true,
      message: 'Address added successfully',
      address
    });
  } catch (error) {
    console.error('Add address error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error adding address', 
      error: error.message 
    });
  }
};

/**
 * Update address
 * @route PUT /api/customers/:id/addresses/:addressId
 */
exports.updateCustomerAddress = async (req, res) => {
  try {
    const { addressId } = req.params;
    const address = await CustomerAddress.findByPk(addressId);

    if (!address) {
      return res.status(404).json({
        success: false,
        message: 'Address not found'
      });
    }

    // If setting as default, unset other defaults
    if (req.body.isDefault) {
      await CustomerAddress.update(
        { isDefault: false },
        { where: { customerId: address.customerId } }
      );
    }

    await address.update(req.body);

    res.json({
      success: true,
      message: 'Address updated successfully',
      address
    });
  } catch (error) {
    console.error('Update address error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error updating address', 
      error: error.message 
    });
  }
};

/**
 * Delete address
 * @route DELETE /api/customers/:id/addresses/:addressId
 */
exports.deleteCustomerAddress = async (req, res) => {
  try {
    const { addressId } = req.params;
    const address = await CustomerAddress.findByPk(addressId);

    if (!address) {
      return res.status(404).json({
        success: false,
        message: 'Address not found'
      });
    }

    await address.destroy();

    res.json({
      success: true,
      message: 'Address deleted successfully'
    });
  } catch (error) {
    console.error('Delete address error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error deleting address', 
      error: error.message 
    });
  }
};

// ============================================
// 💳 TRANSACTIONS & LOYALTY
// ============================================

/**
 * Get customer transactions
 * @route GET /api/customers/:id/transactions
 */
exports.getCustomerTransactions = async (req, res) => {
  try {
    const { page = 1, limit = 20 } = req.query;
    const offset = (page - 1) * limit;

    const { count, rows } = await Transaction.findAndCountAll({
      where: { customerId: req.params.id },
      order: [['transactionDate', 'DESC']],
      limit: parseInt(limit),
      offset: parseInt(offset)
    });

    res.json({
      success: true,
      transactions: rows,
      pagination: {
        total: count,
        totalPages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get transactions error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching transactions', 
      error: error.message 
    });
  }
};

/**
 * Update loyalty points
 * @route PUT /api/customers/:id/loyalty-points
 */
exports.updateLoyaltyPoints = async (req, res) => {
  try {
    const { points, action = 'add', reason } = req.body;

    if (!points || isNaN(points)) {
      return res.status(400).json({
        success: false,
        message: 'Valid points amount is required'
      });
    }

    const customer = await Customer.findByPk(req.params.id);

    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    const currentPoints = customer.loyaltyPoints || 0;
    let newPoints;

    if (action === 'add') {
      newPoints = currentPoints + parseInt(points);
    } else if (action === 'subtract') {
      newPoints = Math.max(0, currentPoints - parseInt(points));
    } else if (action === 'set') {
      newPoints = parseInt(points);
    } else {
      return res.status(400).json({
        success: false,
        message: 'Invalid action. Use: add, subtract, or set'
      });
    }

    await customer.update({ loyaltyPoints: newPoints });

    // Optionally log the transaction
    if (reason) {
      await Transaction.create({
        customerId: customer.id,
        transactionType: 'loyalty_points',
        amount: points,
        transactionDate: new Date(),
        description: reason
      });
    }

    res.json({ 
      success: true,
      message: 'Loyalty points updated successfully', 
      loyaltyPoints: newPoints,
      previousPoints: currentPoints,
      pointsChanged: newPoints - currentPoints
    });
  } catch (error) {
    console.error('Update loyalty points error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error updating loyalty points', 
      error: error.message 
    });
  }
};

/**
 * Redeem loyalty points
 * @route POST /api/customers/:id/redeem-points
 */
exports.redeemLoyaltyPoints = async (req, res) => {
  try {
    const { points, rewardType } = req.body;

    if (!points || points < 100) {
      return res.status(400).json({
        success: false,
        message: 'Minimum 100 points required for redemption'
      });
    }

    const customer = await Customer.findByPk(req.params.id);

    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    if (customer.loyaltyPoints < points) {
      return res.status(400).json({
        success: false,
        message: 'Insufficient loyalty points',
        available: customer.loyaltyPoints,
        required: points
      });
    }

    // Deduct points
    const newPoints = customer.loyaltyPoints - points;
    await customer.update({ loyaltyPoints: newPoints });

    // Calculate reward value (e.g., 2 points = 1 KSh)
    const rewardValue = points / 2;

    // Log redemption
    await Transaction.create({
      customerId: customer.id,
      transactionType: 'loyalty_redemption',
      amount: -points,
      transactionDate: new Date(),
      description: `Redeemed ${points} points for ${rewardType || 'discount'}`
    });

    res.json({
      success: true,
      message: 'Points redeemed successfully',
      pointsRedeemed: points,
      rewardValue,
      remainingPoints: newPoints
    });
  } catch (error) {
    console.error('Redeem points error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error redeeming points', 
      error: error.message 
    });
  }
};

/**
 * Get loyalty tier information
 * @route GET /api/customers/:id/tier-info
 */
exports.getTierInfo = async (req, res) => {
  try {
    const identifier = req.params.id;
    const { byUser = 'true' } = req.query; // Default to userId lookup

    let customer;

    // ✅ Determine lookup method
    if (byUser === 'true') {
      // Look up by userId
      customer = await Customer.findOne({
        where: { userId: identifier }
      });
    } else {
      // Look up by customerId (legacy support)
      customer = await Customer.findByPk(identifier);
    }

    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: byUser === 'true' 
          ? 'Customer not found for this user' 
          : 'Customer not found'
      });
    }

    const tiers = {
      bronze: { minPoints: 0, maxPoints: 999, benefits: ['Basic rewards', '5% discount'] },
      silver: { minPoints: 1000, maxPoints: 2499, benefits: ['Priority support', '10% discount', 'Free shipping'] },
      gold: { minPoints: 2500, maxPoints: 4999, benefits: ['VIP support', '15% discount', 'Free shipping', 'Early access'] },
      platinum: { minPoints: 5000, maxPoints: Infinity, benefits: ['Dedicated manager', '20% discount', 'Free express shipping', 'Exclusive products'] }
    };

    const currentTier = customer.tier || 'bronze';
    const currentPoints = customer.loyaltyPoints || 0;
    const tierInfo = tiers[currentTier];

    // Find next tier
    const tierOrder = ['bronze', 'silver', 'gold', 'platinum'];
    const currentTierIndex = tierOrder.indexOf(currentTier);
    const nextTier = currentTierIndex < tierOrder.length - 1 
      ? tierOrder[currentTierIndex + 1] 
      : null;
    
    const pointsToNextTier = nextTier 
      ? tiers[nextTier].minPoints - currentPoints 
      : 0;

    res.json({
      success: true,
      customerId: customer.id,
      userId: customer.userId,
      currentTier,
      currentPoints,
      tierInfo,
      nextTier,
      pointsToNextTier: Math.max(0, pointsToNextTier),
      progress: nextTier 
        ? Math.min(100, (currentPoints / tiers[nextTier].minPoints) * 100)
        : 100
    });
  } catch (error) {
    console.error('Get tier info error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching tier information', 
      error: error.message 
    });
  }
};

// ============================================
// 📊 REPORTS & EXPORTS
// ============================================

/**
 * Get customer activity report
 * @route GET /api/customers/:id/activity-report
 */
exports.getCustomerActivityReport = async (req, res) => {
  try {
    const { startDate, endDate } = req.query;
    const customerId = req.params.id;

    const dateFilter = {};
    if (startDate && endDate) {
      dateFilter.orderDate = {
        [Op.between]: [new Date(startDate), new Date(endDate)]
      };
    }

    const [orders, reviews, wishlistActivity] = await Promise.all([
      Order.findAll({
        where: { customerId, ...dateFilter },
        include: [{ model: OrderItem, as: 'items' }]
      }),
      Review.findAll({
        where: { customerId },
        order: [['createdAt', 'DESC']],
        limit: 50
      }),
      Wishlist.findAll({
        where: { customerId },
        include: [{ model: Product, as: 'product' }]
      })
    ]);

    const totalSpent = orders
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);

    res.json({
      success: true,
      report: {
        period: { startDate, endDate },
        orders: {
          total: orders.length,
          totalSpent,
          avgOrderValue: orders.length > 0 ? totalSpent / orders.length : 0
        },
        reviews: {
          total: reviews.length,
          avgRating: reviews.length > 0 
            ? reviews.reduce((sum, r) => sum + r.rating, 0) / reviews.length 
            : 0
        },
        wishlist: {
          totalItems: wishlistActivity.length
        }
      }
    });
  } catch (error) {
    console.error('Activity report error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error generating activity report', 
      error: error.message 
    });
  }
};

/**
 * Export customer data (GDPR compliance)
 * @route GET /api/customers/:id/export
 */
exports.exportCustomerData = async (req, res) => {
  try {
    const customer = await Customer.findByPk(req.params.id, {
      include: [
        { model: CustomerAddress, as: 'addresses' },
        { 
          model: Order, 
          as: 'orders',
          include: [{ model: OrderItem, as: 'items' }]
        },
        { model: Review, as: 'reviews' },
        { model: Wishlist, as: 'wishlists' },
        { model: Transaction, as: 'transactions' }
      ]
    });

    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    // Remove sensitive data
    const exportData = customer.toJSON();
    delete exportData.password;

    res.json({
      success: true,
      data: exportData,
      exportDate: new Date().toISOString()
    });
  } catch (error) {
    console.error('Export data error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error exporting customer data', 
      error: error.message 
    });
  }
};

// ============================================
// 🎯 PREFERENCES & SETTINGS
// ============================================

/**
 * Update customer preferences
 * @route PUT /api/customers/:id/preferences
 */
exports.updatePreferences = async (req, res) => {
  try {
    const customer = await Customer.findByPk(req.params.id);

    if (!customer) {
      return res.status(404).json({ 
        success: false,
        message: 'Customer not found' 
      });
    }

    const {
      emailNotifications,
      smsNotifications,
      marketingEmails,
      language,
      currency
    } = req.body;

    const preferences = {
      emailNotifications: emailNotifications !== undefined ? emailNotifications : true,
      smsNotifications: smsNotifications !== undefined ? smsNotifications : false,
      marketingEmails: marketingEmails !== undefined ? marketingEmails : true,
      language: language || 'en',
      currency: currency || 'KES'
    };

    await customer.update({ preferences });

    res.json({
      success: true,
      message: 'Preferences updated successfully',
      preferences
    });
  } catch (error) {
    console.error('Update preferences error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error updating preferences', 
      error: error.message 
    });
  }
};

/**
 * Get customer statistics (Admin view)
 * @route GET /api/customers/statistics
 */
// exports.getCustomerStatistics = async (req, res) => {
//   try {
//     const [
//       totalCustomers,
//       activeCustomers,
//       newThisMonth,
//       tierDistribution
//     ] = await Promise.all([
//       Customer.count(),
//       Customer.count({ where: { status: 'active' } }),
//       Customer.count({
//         where: {
//           createdAt: {
//             [Op.gte]: new Date(new Date().getFullYear(), new Date().getMonth(), 1)
//           }
//         }
//       }),
//       Customer.findAll({
//         attributes: [
//           'tier',
//           [sequelize.fn('COUNT', sequelize.col('id')), 'count']
//         ],
//         group: ['tier']
//       })
//     ]);

//     res.json({
//       success: true,
//       statistics: {
//         totalCustomers,
//         activeCustomers,
//         newThisMonth,
//         tierDistribution: tierDistribution.reduce((acc, item) => {
//           acc[item.tier] = parseInt(item.get('count'));
//           return acc;
//         }, {})
//       }
//     });
//   } catch (error) {
//     console.error('Statistics error:', error);
//     res.status(500).json({ 
//       success: false,
//       message: 'Error fetching statistics', 
//       error: error.message 
//     });
//   }
// };

// ============================================
// 💰 PAYMENT MANAGEMENT
// ============================================
exports.getCustomerStatistics = async (req, res) => {
  try {
    const [
      totalCustomers,
      activeCustomers,
      newThisMonth,
      tierDistribution
    ] = await Promise.all([
      Customer.count(),
      Customer.count({ where: { isActive: true } }),
      Customer.count({
        where: {
          createdAt: {
            [Op.gte]: new Date(new Date().getFullYear(), new Date().getMonth(), 1)
          }
        }
      }),
      Customer.findAll({
        attributes: [
          'tier',
          [sequelize.fn('COUNT', sequelize.col('id')), 'count']
        ],
        group: ['tier'],
        raw: true
      })
    ]);

    // Initialize all tiers with 0 count
    const tierCounts = {
      bronze: 0,
      silver: 0,
      gold: 0,
      platinum: 0
    };

    // Populate with actual counts
    tierDistribution.forEach(item => {
      tierCounts[item.tier] = parseInt(item.count) || 0;
    });

    res.json({
      success: true,
      statistics: {
        totalCustomers,
        activeCustomers,
        newThisMonth,
        tierDistribution: tierCounts
      }
    });
  } catch (error) {
    console.error('Statistics error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching statistics', 
      error: error.message 
    });
  }
};
/**
 * Get customer payment methods
 * @route GET /api/customers/:id/payment-methods
 */
exports.getPaymentMethods = async (req, res) => {
  try {
    const customerId = req.params.id;

    // Get unique payment methods used by customer
    const payments = await Payment.findAll({
      include: [{
        model: Transaction,
        as: 'transaction',
        where: { customerId },
        required: true
      }],
      attributes: [
        'paymentMethod',
        'cardType',
        'cardLastFour',
        'mobileMoneyProvider',
        [sequelize.fn('COUNT', sequelize.col('Payment.id')), 'usageCount'],
        [sequelize.fn('MAX', sequelize.col('Payment.processedAt')), 'lastUsed']
      ],
      group: ['paymentMethod', 'cardType', 'cardLastFour', 'mobileMoneyProvider'],
      order: [[sequelize.fn('MAX', sequelize.col('Payment.processedAt')), 'DESC']]
    });

    res.json({
      success: true,
      paymentMethods: payments
    });
  } catch (error) {
    console.error('Get payment methods error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching payment methods', 
      error: error.message 
    });
  }
};

/**
 * Get customer payment history
 * @route GET /api/customers/:id/payments
 */
exports.getCustomerPayments = async (req, res) => {
  try {
    const { page = 1, limit = 20, status, paymentMethod } = req.query;
    const offset = (page - 1) * limit;
    const customerId = req.params.id;

    const paymentWhere = {};
    if (status) paymentWhere.status = status;
    if (paymentMethod) paymentWhere.paymentMethod = paymentMethod;

    const { count, rows } = await Payment.findAndCountAll({
      where: paymentWhere,
      include: [{
        model: Transaction,
        as: 'transaction',
        where: { customerId },
        required: true,
        include: [{
          model: Order,
          as: 'order',
          attributes: ['orderId', 'orderStatus']
        }]
      }],
      order: [['processedAt', 'DESC']],
      limit: parseInt(limit),
      offset: parseInt(offset)
    });

    // Calculate payment statistics
    const totalPaid = rows
      .filter(p => p.status === 'completed')
      .reduce((sum, p) => sum + Number(p.amount || 0), 0);

    const paymentMethodStats = {};
    rows.forEach(payment => {
      const method = payment.paymentMethod;
      if (!paymentMethodStats[method]) {
        paymentMethodStats[method] = { count: 0, total: 0 };
      }
      paymentMethodStats[method].count++;
      if (payment.status === 'completed') {
        paymentMethodStats[method].total += Number(payment.amount || 0);
      }
    });

    res.json({
      success: true,
      payments: rows,
      statistics: {
        totalPayments: count,
        totalPaid,
        paymentMethodStats
      },
      pagination: {
        total: count,
        totalPages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get payments error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching payment history', 
      error: error.message 
    });
  }
};

/**
 * Process customer payment
 * @route POST /api/customers/:id/payments
 */
exports.processPayment = async (req, res) => {
  try {
    const customerId = req.params.id;
    const {
      transactionId,
      paymentMethod,
      amount,
      cardLastFour,
      cardType,
      mobileMoneyProvider,
      mobileMoneyNumber,
      processedBy
    } = req.body;

    // Validation
    if (!transactionId || !paymentMethod || !amount) {
      return res.status(400).json({
        success: false,
        message: 'Transaction ID, payment method, and amount are required'
      });
    }

    // Verify transaction exists and belongs to customer
    const transaction = await Transaction.findOne({
      where: { 
        id: transactionId,
        customerId 
      }
    });

    if (!transaction) {
      return res.status(404).json({
        success: false,
        message: 'Transaction not found or does not belong to this customer'
      });
    }

    // Generate reference number
    const referenceNumber = `PAY-${Date.now()}-${Math.random().toString(36).substr(2, 9).toUpperCase()}`;

    // Create payment record
    const payment = await Payment.create({
      transactionId,
      paymentMethod,
      amount,
      status: 'pending',
      referenceNumber,
      cardLastFour: paymentMethod === 'card' ? cardLastFour : null,
      cardType: paymentMethod === 'card' ? cardType : null,
      mobileMoneyProvider: paymentMethod === 'mobile_money' ? mobileMoneyProvider : null,
      mobileMoneyNumber: paymentMethod === 'mobile_money' ? mobileMoneyNumber : null,
      processedBy,
      processedAt: new Date()
    });

    // Simulate payment processing (in production, integrate with payment gateway)
    setTimeout(async () => {
      try {
        await payment.update({ status: 'completed' });
        
        // Update transaction status
        await transaction.update({ 
          paymentStatus: 'paid',
          paidAt: new Date()
        });

        // Award loyalty points (0.5 points per KSh)
        const customer = await Customer.findByPk(customerId);
        if (customer) {
          const pointsEarned = Math.floor(amount * 0.5);
          await customer.update({ 
            loyaltyPoints: (customer.loyaltyPoints || 0) + pointsEarned 
          });

          // Check for tier upgrade
          await checkAndUpgradeTier(customer);
        }
      } catch (err) {
        console.error('Payment processing error:', err);
      }
    }, 2000);

    res.status(201).json({
      success: true,
      message: 'Payment processing initiated',
      payment: {
        id: payment.id,
        referenceNumber: payment.referenceNumber,
        status: payment.status,
        amount: payment.amount
      }
    });
  } catch (error) {
    console.error('Process payment error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error processing payment', 
      error: error.message 
    });
  }
};

/**
 * Verify payment status
 * @route GET /api/customers/:id/payments/:paymentId/verify
 */
exports.verifyPayment = async (req, res) => {
  try {
    const { paymentId } = req.params;

    const payment = await Payment.findByPk(paymentId, {
      include: [{
        model: Transaction,
        as: 'transaction',
        include: [{
          model: Order,
          as: 'order'
        }]
      }]
    });

    if (!payment) {
      return res.status(404).json({
        success: false,
        message: 'Payment not found'
      });
    }

    res.json({
      success: true,
      payment: {
        id: payment.id,
        referenceNumber: payment.referenceNumber,
        status: payment.status,
        amount: payment.amount,
        paymentMethod: payment.paymentMethod,
        processedAt: payment.processedAt,
        transaction: payment.transaction
      }
    });
  } catch (error) {
    console.error('Verify payment error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error verifying payment', 
      error: error.message 
    });
  }
};

/**
 * Get payment statistics for customer
 * @route GET /api/customers/:id/payment-stats
 */
exports.getPaymentStatistics = async (req, res) => {
  try {
    const customerId = req.params.id;

    const payments = await Payment.findAll({
      include: [{
        model: Transaction,
        as: 'transaction',
        where: { customerId },
        required: true
      }]
    });

    const stats = {
      totalPayments: payments.length,
      successfulPayments: payments.filter(p => p.status === 'completed').length,
      failedPayments: payments.filter(p => p.status === 'failed').length,
      pendingPayments: payments.filter(p => p.status === 'pending').length,
      totalAmountPaid: payments
        .filter(p => p.status === 'completed')
        .reduce((sum, p) => sum + Number(p.amount || 0), 0),
      byMethod: {},
      byMonth: {}
    };

    // Group by payment method
    payments.forEach(payment => {
      const method = payment.paymentMethod;
      if (!stats.byMethod[method]) {
        stats.byMethod[method] = {
          count: 0,
          totalAmount: 0,
          successful: 0
        };
      }
      stats.byMethod[method].count++;
      if (payment.status === 'completed') {
        stats.byMethod[method].totalAmount += Number(payment.amount || 0);
        stats.byMethod[method].successful++;
      }
    });

    // Group by month
    payments.forEach(payment => {
      if (payment.processedAt) {
        const monthKey = new Date(payment.processedAt).toISOString().substr(0, 7);
        if (!stats.byMonth[monthKey]) {
          stats.byMonth[monthKey] = {
            count: 0,
            totalAmount: 0
          };
        }
        stats.byMonth[monthKey].count++;
        if (payment.status === 'completed') {
          stats.byMonth[monthKey].totalAmount += Number(payment.amount || 0);
        }
      }
    });

    res.json({
      success: true,
      statistics: stats
    });
  } catch (error) {
    console.error('Payment statistics error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error fetching payment statistics', 
      error: error.message 
    });
  }
};

/**
 * Refund payment
 * @route POST /api/customers/:id/payments/:paymentId/refund
 */
exports.refundPayment = async (req, res) => {
  try {
    const { paymentId } = req.params;
    const { reason, refundAmount, processedBy } = req.body;

    const payment = await Payment.findByPk(paymentId, {
      include: [{
        model: Transaction,
        as: 'transaction'
      }]
    });

    if (!payment) {
      return res.status(404).json({
        success: false,
        message: 'Payment not found'
      });
    }

    if (payment.status !== 'completed') {
      return res.status(400).json({
        success: false,
        message: 'Can only refund completed payments'
      });
    }

    const amountToRefund = refundAmount || payment.amount;

    if (amountToRefund > payment.amount) {
      return res.status(400).json({
        success: false,
        message: 'Refund amount cannot exceed payment amount'
      });
    }

    // Create refund payment record
    const refund = await Payment.create({
      transactionId: payment.transactionId,
      paymentMethod: payment.paymentMethod,
      amount: -amountToRefund,
      status: 'completed',
      referenceNumber: `REF-${payment.referenceNumber}`,
      processedBy,
      processedAt: new Date()
    });

    // Update original payment status
    await payment.update({ 
      status: amountToRefund === payment.amount ? 'refunded' : 'partially_refunded'
    });

    // Deduct loyalty points
    const customer = await Customer.findByPk(payment.transaction.customerId);
    if (customer) {
      const pointsToDeduct = Math.floor(amountToRefund * 0.5);
      await customer.update({ 
        loyaltyPoints: Math.max(0, (customer.loyaltyPoints || 0) - pointsToDeduct)
      });
    }

    res.json({
      success: true,
      message: 'Refund processed successfully',
      refund: {
        id: refund.id,
        amount: refund.amount,
        referenceNumber: refund.referenceNumber
      }
    });
  } catch (error) {
    console.error('Refund payment error:', error);
    res.status(500).json({ 
      success: false,
      message: 'Error processing refund', 
      error: error.message 
    });
  }
};

// ============================================
// 🎖️ HELPER FUNCTIONS
// ============================================

/**
 * Check and upgrade customer tier based on points
 */
async function checkAndUpgradeTier(customer) {
  const points = customer.loyaltyPoints || 0;
  let newTier = 'bronze';

  if (points >= 5000) {
    newTier = 'platinum';
  } else if (points >= 2500) {
    newTier = 'gold';
  } else if (points >= 1000) {
    newTier = 'silver';
  }

  if (newTier !== customer.tier) {
    await customer.update({ tier: newTier });
    console.log(`Customer ${customer.id} upgraded to ${newTier} tier`);
  }
}

// ============================================
// 📦 ORDER MANAGEMENT
// ============================================

/**
 * Get all orders for a customer
 * @route GET /api/customers/:id/orders
 */
exports.getCustomerOrders = async (req, res) => {
  try {
    const customerId = req.params.id;
    const { 
      page = 1, 
      limit = 20, 
      status, 
      paymentStatus,
      sortBy = 'orderDate',
      sortOrder = 'DESC',
      startDate,
      endDate
    } = req.query;

    const offset = (page - 1) * limit;

    // Build where clause
    const where = { customerId };
    
    if (status) {
      where.orderStatus = status;
    }
    
    if (paymentStatus) {
      where.paymentStatus = paymentStatus;
    }

    if (startDate && endDate) {
      where.orderDate = {
        [Op.between]: [new Date(startDate), new Date(endDate)]
      };
    }

    const { count, rows } = await Order.findAndCountAll({
      where,
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'productName', 'category', 'imageUrl']
            }
          ]
        },
        {
          model: CustomerAddress,
          as: 'shippingAddress'
        },
        {
          model: Payment,
          as: 'payments'
        }
      ],
      order: [[sortBy, sortOrder.toUpperCase()]],
      limit: parseInt(limit),
      offset: parseInt(offset)
    });

    // Calculate summary statistics
    const totalSpent = rows
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + Number(o.totalAmount || 0), 0);

    const statusBreakdown = rows.reduce((acc, order) => {
      acc[order.orderStatus] = (acc[order.orderStatus] || 0) + 1;
      return acc;
    }, {});

    res.json({
      success: true,
      orders: rows,
      summary: {
        totalOrders: count,
        totalSpent,
        statusBreakdown
      },
      pagination: {
        total: count,
        totalPages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get customer orders error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching customer orders',
      error: error.message
    });
  }
};

/**
 * Get a specific order for a customer
 * @route GET /api/customers/:id/orders/:orderId
 */
exports.getCustomerOrderById = async (req, res) => {
  try {
    const { id: customerId, orderId } = req.params;

    const order = await Order.findOne({
      where: { 
        id: orderId,
        customerId 
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product'
            }
          ]
        },
        {
          model: CustomerAddress,
          as: 'shippingAddress'
        },
        {
          model: CustomerAddress,
          as: 'billingAddress'
        },
        {
          model: Payment,
          as: 'payments',
          order: [['processedAt', 'DESC']]
        },
        {
          model: Transaction,
          as: 'transaction'
        }
      ]
    });

    if (!order) {
      return res.status(404).json({
        success: false,
        message: 'Order not found or does not belong to this customer'
      });
    }

    res.json({
      success: true,
      order
    });
  } catch (error) {
    console.error('Get order by ID error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching order details',
      error: error.message
    });
  }
};

/**
 * Get active orders (pending, confirmed, processing, shipped)
 * @route GET /api/customers/:id/orders/active
 */
exports.getActiveOrders = async (req, res) => {
  try {
    const customerId = req.params.id;

    const activeOrders = await Order.findAll({
      where: {
        customerId,
        orderStatus: {
          [Op.in]: ['pending', 'confirmed', 'processing', 'shipped']
        }
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'productName', 'imageUrl']
            }
          ]
        }
      ],
      order: [['orderDate', 'DESC']]
    });

    res.json({
      success: true,
      activeOrders,
      count: activeOrders.length
    });
  } catch (error) {
    console.error('Get active orders error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching active orders',
      error: error.message
    });
  }
};

/**
 * Get order history (completed/delivered orders)
 * @route GET /api/customers/:id/orders/history
 */
exports.getOrderHistory = async (req, res) => {
  try {
    const customerId = req.params.id;
    const { page = 1, limit = 20 } = req.query;
    const offset = (page - 1) * limit;

    const { count, rows } = await Order.findAndCountAll({
      where: {
        customerId,
        orderStatus: 'delivered'
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product',
              attributes: ['id', 'productName', 'category', 'imageUrl']
            }
          ]
        }
      ],
      order: [['deliveredAt', 'DESC']],
      limit: parseInt(limit),
      offset: parseInt(offset)
    });

    // Get items eligible for review (delivered but not reviewed)
    const itemsToReview = [];
    for (const order of rows) {
      for (const item of order.items || []) {
        const existingReview = await Review.findOne({
          where: {
            customerId,
            productId: item.productId
          }
        });
        
        if (!existingReview) {
          itemsToReview.push({
            orderId: order.id,
            orderNumber: order.orderId,
            productId: item.productId,
            productName: item.product?.productName,
            deliveredAt: order.deliveredAt
          });
        }
      }
    }

    res.json({
      success: true,
      orderHistory: rows,
      itemsToReview,
      pagination: {
        total: count,
        totalPages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    console.error('Get order history error:', error);
    res.status(500).json({
      success: false,
      message: 'Error fetching order history',
      error: error.message
    });
  }
};




/**
 * Reorder items from a previous order
 * @route POST /api/customers/:id/orders/:orderId/reorder
 */
exports.reorderItems = async (req, res) => {
  try {
    const { id: customerId, orderId } = req.params;

    const originalOrder = await Order.findOne({
      where: {
        id: orderId,
        customerId
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [
            {
              model: Product,
              as: 'product'
            }
          ]
        }
      ]
    });

    if (!originalOrder) {
      return res.status(404).json({
        success: false,
        message: 'Original order not found'
      });
    }

    // Check product availability and prices
    const itemsToReorder = [];
    const unavailableItems = [];

    for (const item of originalOrder.items || []) {
      const product = await Product.findByPk(item.productId);
      
      if (!product || product.stockQuantity < item.quantity) {
        unavailableItems.push({
          productId: item.productId,
          productName: item.productName,
          requestedQuantity: item.quantity,
          availableQuantity: product?.stockQuantity || 0
        });
      } else {
        itemsToReorder.push({
          productId: product.id,
          productName: product.productName,
          quantity: item.quantity,
          unitPrice: product.unitPrice,
          subtotal: product.unitPrice * item.quantity
        });
      }
    }

    if (unavailableItems.length > 0) {
      return res.status(400).json({
        success: false,
        message: 'Some items are not available for reorder',
        unavailableItems,
        availableItems: itemsToReorder
      });
    }

    res.json({
      success: true,
      message: 'Items ready for reorder',
      items: itemsToReorder,
      totalAmount: itemsToReorder.reduce((sum, item) => sum + item.subtotal, 0)
    });
  } catch (error) {
    console.error('Reorder error:', error);
    res.status(500).json({
      success: false,
      message: 'Error processing reorder',
      error: error.message
    });
  }
};

/**
 * Track order shipment
 * @route GET /api/customers/:id/orders/:orderId/track
 */
exports.trackOrder = async (req, res) => {
  try {
    const { id: customerId, orderId } = req.params;

    const order = await Order.findOne({
      where: {
        id: orderId,
        customerId
      },
      include: [
        {
          model: OrderItem,
          as: 'items',
          include: [{ model: Product, as: 'product' }]
        }
      ]
    });

    if (!order) {
      return res.status(404).json({
        success: false,
        message: 'Order not found'
      });
    }

    // Get shipment tracking info (if you have a Shipment model)
    // const shipment = await Shipment.findOne({ where: { orderId: order.id } });

    const trackingInfo = {
      orderId: order.orderId,
      orderStatus: order.orderStatus,
      orderDate: order.orderDate,
      estimatedDelivery: order.estimatedDelivery,
      timeline: [
        {
          status: 'placed',
          timestamp: order.orderDate,
          completed: true,
          description: 'Order placed successfully'
        },
        {
          status: 'confirmed',
          timestamp: order.confirmedAt,
          completed: !!order.confirmedAt,
          description: 'Order confirmed and being prepared'
        },
        {
          status: 'processing',
          timestamp: order.processingAt,
          completed: !!order.processingAt,
          description: 'Order is being processed'
        },
        {
          status: 'shipped',
          timestamp: order.shippedAt,
          completed: !!order.shippedAt,
          description: 'Order has been shipped'
        },
        {
          status: 'delivered',
          timestamp: order.deliveredAt,
          completed: !!order.deliveredAt,
          description: 'Order delivered successfully'
        }
      ].filter(step => step.completed || order.orderStatus === step.status)
    };

    res.json({
      success: true,
      tracking: trackingInfo
    });
  } catch (error) {
    console.error('Track order error:', error);
    res.status(500).json({
      success: false,
      message: 'Error tracking order',
      error: error.message
    });
  }
};



module.exports = exports;