import express from 'express';
import { businessTodayStr, businessDateOf, businessNow, formatDateCol } from '../../shared/business-time/index.js';
const router = express.Router();

// Get all orders with pagination, filtering, and sorting
router.get('/', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 50;
    const offset = (page - 1) * limit;
    const search = req.query.search || '';
    const status = req.query.status || 'all';
    // Date filters are BUSINESS dates ('YYYY-MM-DD', Chicago calendar).
    const fromDate = req.query.fromDate ? businessDateOf(req.query.fromDate) : null;
    const toDate = req.query.toDate ? businessDateOf(req.query.toDate) : null;
    const minAmount = parseFloat(req.query.minAmount) || 0;
    const maxAmount = req.query.maxAmount ? parseFloat(req.query.maxAmount) : null;
    const sortColumn = req.query.sortColumn || 'date';
    const sortDirection = req.query.sortDirection === 'desc' ? 'DESC' : 'ASC';

    // Build the WHERE clause
    const conditions = ['o1.canceled = false'];
    const params = [];
    let paramCounter = 1;

    if (search) {
      conditions.push(`(o1.order_number ILIKE $${paramCounter} OR o1.customer ILIKE $${paramCounter})`);
      params.push(`%${search}%`);
      paramCounter++;
    }

    if (status !== 'all') {
      conditions.push(`o1.status = $${paramCounter}`);
      params.push(status);
      paramCounter++;
    }

    if (fromDate) {
      conditions.push(`DATE(o1.date) >= $${paramCounter}::date`);
      params.push(fromDate);
      paramCounter++;
    }

    if (toDate) {
      conditions.push(`DATE(o1.date) <= $${paramCounter}::date`);
      params.push(toDate);
      paramCounter++;
    }

    if (minAmount > 0) {
      conditions.push(`total_amount >= $${paramCounter}`);
      params.push(minAmount);
      paramCounter++;
    }

    if (maxAmount) {
      conditions.push(`total_amount <= $${paramCounter}`);
      params.push(maxAmount);
      paramCounter++;
    }

    // Get total count for pagination
    const { rows: [countResult] } = await pool.query(`
      SELECT COUNT(DISTINCT o1.order_number) as total 
      FROM orders o1
      LEFT JOIN (
        SELECT order_number, SUM(price * quantity) as total_amount
        FROM orders
        GROUP BY order_number
      ) totals ON o1.order_number = totals.order_number
      WHERE ${conditions.join(' AND ')}
    `, params);
    
    const total = countResult.total;

    // Get paginated results
    const query = `
      SELECT 
        o1.order_number,
        o1.customer,
        o1.date,
        o1.status,
        o1.payment_method,
        o1.shipping_method,
        COUNT(o2.pid) as items_count,
        ROUND(SUM(o2.price * o2.quantity)::numeric, 3) as total_amount
      FROM orders o1
      JOIN orders o2 ON o1.order_number = o2.order_number
      WHERE ${conditions.join(' AND ')}
      GROUP BY 
        o1.order_number,
        o1.customer,
        o1.date,
        o1.status,
        o1.payment_method,
        o1.shipping_method
      ORDER BY ${
        sortColumn === 'items_count' || sortColumn === 'total_amount' 
          ? `${sortColumn} ${sortDirection}`
          : `o1.${sortColumn} ${sortDirection}`
      }
      LIMIT $${paramCounter} OFFSET $${paramCounter + 1}
    `;

    params.push(limit, offset);
    const { rows } = await pool.query(query, params);

    // Get order statistics
    const { rows: [orderStats] } = await pool.query(`
      WITH CurrentStats AS (
        SELECT 
          COUNT(DISTINCT order_number) as total_orders,
          ROUND(SUM(price * quantity)::numeric, 3) as total_revenue
        FROM orders
        WHERE canceled = false
          AND DATE(date) >= CURRENT_DATE - INTERVAL '30 days'
      ),
      PreviousStats AS (
        SELECT 
          COUNT(DISTINCT order_number) as prev_orders,
          ROUND(SUM(price * quantity)::numeric, 3) as prev_revenue
        FROM orders
        WHERE canceled = false
          AND DATE(date) BETWEEN CURRENT_DATE - INTERVAL '60 days' AND CURRENT_DATE - INTERVAL '30 days'
      ),
      OrderValues AS (
        SELECT 
          order_number,
          ROUND(SUM(price * quantity)::numeric, 3) as order_value
        FROM orders
        WHERE canceled = false
          AND DATE(date) >= CURRENT_DATE - INTERVAL '30 days'
        GROUP BY order_number
      )
      SELECT 
        cs.total_orders,
        cs.total_revenue,
        CASE 
          WHEN ps.prev_orders > 0 
          THEN ROUND(((cs.total_orders - ps.prev_orders)::numeric / ps.prev_orders * 100), 1)
          ELSE 0 
        END as order_growth,
        CASE 
          WHEN ps.prev_revenue > 0 
          THEN ROUND(((cs.total_revenue - ps.prev_revenue)::numeric / ps.prev_revenue * 100), 1)
          ELSE 0 
        END as revenue_growth,
        CASE 
          WHEN cs.total_orders > 0 
          THEN ROUND((cs.total_revenue::numeric / cs.total_orders), 3)
          ELSE 0 
        END as average_order_value,
        CASE 
          WHEN ps.prev_orders > 0 
          THEN ROUND((ps.prev_revenue::numeric / ps.prev_orders), 3)
          ELSE 0 
        END as prev_average_order_value
      FROM CurrentStats cs
      CROSS JOIN PreviousStats ps
    `);
    
    res.json({
      orders: rows.map(row => ({
        ...row,
        total_amount: parseFloat(row.total_amount) || 0,
        items_count: parseInt(row.items_count) || 0,
        date: row.date
      })),
      pagination: {
        total,
        pages: Math.ceil(total / limit),
        currentPage: page,
        limit
      },
      stats: {
        totalOrders: parseInt(orderStats.total_orders) || 0,
        totalRevenue: parseFloat(orderStats.total_revenue) || 0,
        orderGrowth: parseFloat(orderStats.order_growth) || 0,
        revenueGrowth: parseFloat(orderStats.revenue_growth) || 0,
        averageOrderValue: parseFloat(orderStats.average_order_value) || 0,
        aovGrowth: orderStats.prev_average_order_value > 0 
          ? ((orderStats.average_order_value - orderStats.prev_average_order_value) / orderStats.prev_average_order_value * 100)
          : 0,
        conversionRate: 2.5, // Placeholder - would need actual visitor data
        conversionGrowth: 0.5 // Placeholder - would need actual visitor data
      }
    });
  } catch (error) {
    console.error('Error fetching orders:', error);
    res.status(500).json({ error: 'Failed to fetch orders' });
  }
});

// Get a single order with its items
router.get('/:orderNumber', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    // Get order details
    const { rows: orderRows } = await pool.query(`
      SELECT DISTINCT
        o1.order_number,
        o1.customer,
        o1.date,
        o1.status,
        o1.payment_method,
        o1.shipping_method,
        o1.shipping_address,
        o1.billing_address,
        COUNT(o2.pid) as items_count,
        ROUND(SUM(o2.price * o2.quantity)::numeric, 3) as total_amount
      FROM orders o1
      JOIN orders o2 ON o1.order_number = o2.order_number
      WHERE o1.order_number = $1 AND o1.canceled = false
      GROUP BY 
        o1.order_number,
        o1.customer,
        o1.date,
        o1.status,
        o1.payment_method,
        o1.shipping_method,
        o1.shipping_address,
        o1.billing_address
    `, [req.params.orderNumber]);

    if (orderRows.length === 0) {
      return res.status(404).json({ error: 'Order not found' });
    }

    // Get order items
    const { rows: itemRows } = await pool.query(`
      SELECT 
        o.pid,
        p.title,
        p.SKU,
        o.quantity,
        o.price,
        ROUND((o.price * o.quantity)::numeric, 3) as total
      FROM orders o
      JOIN products p ON o.pid = p.pid
      WHERE o.order_number = $1 AND o.canceled = false
    `, [req.params.orderNumber]);

    const order = {
      ...orderRows[0],
      total_amount: parseFloat(orderRows[0].total_amount) || 0,
      items_count: parseInt(orderRows[0].items_count) || 0,
      items: itemRows.map(item => ({
        ...item,
        price: parseFloat(item.price) || 0,
        total: parseFloat(item.total) || 0,
        quantity: parseInt(item.quantity) || 0
      }))
    };

    res.json(order);
  } catch (error) {
    console.error('Error fetching order:', error);
    res.status(500).json({ error: 'Failed to fetch order' });
  }
});

export default router;
