import { Hono } from 'hono';
import { z } from 'zod';
import { IServiceContainer } from '@stock-bot/di';
import { OrderRequestSchema } from '../../types';
import { ExecutionService } from '../../services/ExecutionService';

const OrderIdSchema = z.object({
  orderId: z.string()
});

export function createOrderRoutes(container: IServiceContainer): Hono {
  const app = new Hono();
  const executionService = container.custom?.ExecutionService as ExecutionService;

  // Submit new order
  app.post('/', async (c) => {
    try {
      const body = await c.req.json();
      const orderRequest = OrderRequestSchema.parse(body);
      
      const result = await executionService.submitOrder(orderRequest);
      
      return c.json(result, 201);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return c.json({ 
          error: 'Invalid order request', 
          details: error.errors 
        }, 400);
      }
      
      container.logger.error('Error submitting order:', error);
      return c.json({ 
        error: error instanceof Error ? error.message : 'Failed to submit order' 
      }, 500);
    }
  });

  // Cancel order
  app.delete('/:orderId', async (c) => {
    try {
      const { orderId } = OrderIdSchema.parse(c.req.param());
      
      const success = await executionService.cancelOrder(orderId);
      
      if (success) {
        return c.json({ message: 'Order cancelled successfully' });
      } else {
        return c.json({ error: 'Order not found or already filled' }, 404);
      }
    } catch (error) {
      container.logger.error('Error cancelling order:', error);
      return c.json({ 
        error: error instanceof Error ? error.message : 'Failed to cancel order' 
      }, 500);
    }
  });

  // Get order status
  app.get('/:orderId', async (c) => {
    try {
      const { orderId } = OrderIdSchema.parse(c.req.param());
      
      const status = await executionService.getOrderStatus(orderId);
      
      if (status) {
        return c.json(status);
      } else {
        return c.json({ error: 'Order not found' }, 404);
      }
    } catch (error) {
      container.logger.error('Error getting order status:', error);
      return c.json({ 
        error: error instanceof Error ? error.message : 'Failed to get order status' 
      }, 500);
    }
  });

  // Batch order submission
  app.post('/batch', async (c) => {
    try {
      const body = await c.req.json();
      const orders = z.array(OrderRequestSchema).parse(body);
      
      const results = await Promise.allSettled(
        orders.map(order => executionService.submitOrder(order))
      );
      
      const response = results.map((result, index) => ({
        order: orders[index],
        result: result.status === 'fulfilled' ? result.value : { error: result.reason }
      }));
      
      return c.json(response, 201);
    } catch (error) {
      if (error instanceof z.ZodError) {
        return c.json({ 
          error: 'Invalid batch order request', 
          details: error.errors 
        }, 400);
      }
      
      container.logger.error('Error submitting batch orders:', error);
      return c.json({ 
        error: error instanceof Error ? error.message : 'Failed to submit batch orders' 
      }, 500);
    }
  });

  return app;
}