// API Route: /api/orders
// Handles CRUD operations for orders

import { NextApiRequest, NextApiResponse } from 'next';
import { orderService, orderServiceExtended, orderItemService } from '@/lib/database/mysql-service';
import { withAuth } from '@/lib/middleware/auth';
import { withErrorHandler } from '@/lib/middleware/error-handler';
import { z } from 'zod';

// Validation schemas
const orderItemSchema = z.object({
  name: z.string().min(1, 'Item name is required'),
  quantity: z.number().min(1, 'Quantity must be at least 1'),
  price: z.number().min(0, 'Price must be positive'),
  artisan_wage: z.number().min(0, 'Artisan wage must be positive'),
  measurements: z.string().optional(),
  fabric_used: z.number().optional(),
  notes: z.string().optional(),
});

const createOrderSchema = z.object({
  memo_id: z.string().optional(),
  customer_id: z.number().min(1, 'Customer ID is required'),
  customer_name: z.string().min(1, 'Customer name is required'),
  customer_phone: z.string().min(1, 'Customer phone is required'),
  type: z.enum(['pickup', 'delivery']),
  status: z.enum(['New', 'In Progress', 'Ready for Delivery', 'Delivered', 'Completed', 'Cancelled']).default('New'),
  order_date: z.string().transform(val => new Date(val)),
  delivery_date: z.string().optional().transform(val => val ? new Date(val) : undefined),
  delivery_address: z.string().optional(),
  total_amount: z.number().min(0, 'Total amount must be positive'),
  paid_amount: z.number().min(0, 'Paid amount must be positive'),
  total_artisan_wage: z.number().min(0, 'Total artisan wage must be positive'),
  artisan_id: z.number().optional(),
  artisan_name: z.string().optional(),
  cutting_master_id: z.number().optional(),
  cutting_master_name: z.string().optional(),
  priority: z.enum(['low', 'medium', 'high']).default('medium'),
  notes: z.string().optional(),
  items: z.array(orderItemSchema).min(1, 'At least one item is required'),
});

const querySchema = z.object({
  page: z.string().optional().transform(val => val ? parseInt(val) : 1),
  limit: z.string().optional().transform(val => val ? parseInt(val) : 10),
  status: z.string().optional(),
  customer_id: z.string().optional().transform(val => val ? parseInt(val) : undefined),
  start_date: z.string().optional(),
  end_date: z.string().optional(),
  search: z.string().optional(),
  orderBy: z.string().optional().default('order_date'),
  orderDirection: z.enum(['ASC', 'DESC']).optional().default('DESC'),
});

async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { method } = req;
  const { user, shopId } = req as any;

  switch (method) {
    case 'GET':
      return handleGet(req, res, shopId);
    case 'POST':
      return handlePost(req, res, shopId, user.id);
    default:
      res.setHeader('Allow', ['GET', 'POST']);
      return res.status(405).json({ error: `Method ${method} not allowed` });
  }
}

async function handleGet(req: NextApiRequest, res: NextApiResponse, shopId: number) {
  const query = querySchema.parse(req.query);
  
  try {
    let result;
    
    if (query.status) {
      // Get orders by status
      const orders = await orderServiceExtended.getOrdersByStatus(shopId, query.status as any);
      result = {
        data: orders,
        total: orders.length,
        page: 1,
        limit: orders.length,
        totalPages: 1,
      };
    } else if (query.start_date && query.end_date) {
      // Get orders by date range
      const orders = await orderServiceExtended.getOrdersByDateRange(
        shopId, 
        new Date(query.start_date), 
        new Date(query.end_date)
      );
      result = {
        data: orders,
        total: orders.length,
        page: 1,
        limit: orders.length,
        totalPages: 1,
      };
    } else {
      // Get all orders with pagination and filters
      const filters: any = {};
      if (query.customer_id) filters.customer_id = query.customer_id;
      if (query.status) filters.status = query.status;
      
      const searchOptions = query.search ? {
        searchTerm: query.search,
        searchFields: ['memo_id', 'customer_name', 'notes']
      } : {};
      
      result = await orderService.findByShop(shopId, {
        page: query.page,
        limit: query.limit,
        orderBy: query.orderBy,
        orderDirection: query.orderDirection,
      }, searchOptions);
    }
    
    // Get order items for each order
    for (const order of result.data) {
      const items = await orderItemService.getOrderItems(order.id);
      (order as any).items = items;
    }
    
    return res.status(200).json({
      success: true,
      ...result,
    });
  } catch (error: any) {
    console.error('Error fetching orders:', error);
    return res.status(500).json({
      success: false,
      error: 'Failed to fetch orders',
      details: error.message,
    });
  }
}

async function handlePost(req: NextApiRequest, res: NextApiResponse, shopId: number, userId: number) {
  try {
    const validatedData = createOrderSchema.parse(req.body);
    const { items, ...orderData } = validatedData;
    
    // Create order
    const order = await orderService.create({
      ...orderData,
      shop_id: shopId,
    });
    
    // Create order items
    const createdItems = await orderItemService.createOrderItems(order.id, items);
    
    // Return order with items
    const orderWithItems = {
      ...order,
      items: createdItems,
    };
    
    return res.status(201).json({
      success: true,
      data: orderWithItems,
      message: 'Order created successfully',
    });
  } catch (error: any) {
    if (error.name === 'ZodError') {
      return res.status(400).json({
        success: false,
        error: 'Validation error',
        details: error.errors,
      });
    }
    
    console.error('Error creating order:', error);
    return res.status(500).json({
      success: false,
      error: 'Failed to create order',
      details: error.message,
    });
  }
}

export default withErrorHandler(withAuth(handler));
