const express = require('express');
const router = express.Router();
const tradingController = require('../controllers/tradingController');
const { authenticate } = require('../middleware/auth');
const { tradingLimiter } = require('../middleware/rateLimiter');
const { validate, body, query, param } = require('../middleware/validation');

router.get('/overview', authenticate, tradingController.getOverview)
router.get('/assets/all', authenticate, tradingController.getAllAsset)
router.get('/terminal', authenticate, tradingController.getTerminal)
router.get('/history/all', authenticate, tradingController.getAllHistory)
router.post('/terminal/history', authenticate, tradingController.getTerminalHistory)
router.post('/terminal/close', authenticate, tradingController.closeTerminalTrade)
router.get('/assets', authenticate, tradingController.getAssetData)
router.get('/spot', authenticate, tradingController.getSpotData)
router.get('/forex', authenticate, tradingController.getFxData)
router.post(
  '/assets/trade',
  authenticate,
  tradingLimiter, [
  body('asset').trim().toUpperCase().notEmpty(),
  body('side').isIn(['buy', 'sell']),
  body('marketType').isIn(['market', 'limit', 'stop']),
  body('quantity').isFloat({ min: 0 }),
  body('price').optional().isFloat({ min: 0 }),
  body('limit').optional().trim().isLength({ max: 100 }),
],
  validate,
  tradingController.tradeAsset)

router.post(
  "/spot/orders",
  authenticate,
  tradingLimiter,
  [
    body("symbol").trim().notEmpty().withMessage("Symbol is required"),
    body("side").isIn(["buy", "sell"]).withMessage("Invalid side"),
    body("orderType")
      .isIn(["market", "limit", "stop-limit"])
      .withMessage("Invalid order type"),
    body("amount").isFloat({ min: 0.00000001 }).withMessage("Invalid amount"),
    body("price")
      .optional({ nullable: true })
      .isFloat({ min: 0.00000001 })
      .withMessage("Invalid price"),
    body("stopPrice")
      .optional({ nullable: true })
      .isFloat({ min: 0.00000001 })
      .withMessage("Invalid stop price"),
    body("clientOrderId")
      .optional()
      .isString()
      .isLength({ max: 64 }),
  ],
  validate,
  tradingController.tradeSpot
);

router.delete(
  "/spot/orders/:id",
  authenticate,
  [
    param("id").isInt({ min: 1 }).withMessage("Invalid order id"),
  ],
  validate,
  tradingController.cancelSpotOrder
);

router.post(
  '/terminal/trade',
  authenticate,
  tradingLimiter, [
  body('asset').trim().toUpperCase().notEmpty(),
  body('side').isIn(['buy', 'sell']),
  body('marketType').isIn(['market', 'limit', 'stop']),
  body('quantity').isFloat({ min: 0 }),
  body('price').optional().isFloat({ min: 0 }),
  body('limit').optional().trim().isLength({ max: 100 }),
  body('leverage').isInt({ min: 1 }),
  body('duration').isInt({ min: 1 }),
  body('stopLoss').optional().isFloat({ min: 0 }),
  body('takeProfit').optional().isFloat({ min: 0 })
],
  validate,
  tradingController.tradeTerminal)

router.get('/markets/:type', authenticate, tradingController.getMarketsByType)
/**
 * @route   POST /api/v1/trading/orders
 * @desc    Create a new order
 * @access  Private
 */
router.post(
  '/orders',
  authenticate,
  tradingLimiter,
  [
    body('market').isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    body('symbol').trim().toUpperCase().notEmpty(),
    body('side').isIn(['buy', 'sell']),
    body('type').isIn(['market', 'limit', 'stop_limit', 'stop_market']),
    body('quantity').isFloat({ min: 0 }),
    body('price').optional().isFloat({ min: 0 }),
    body('stopPrice').optional().isFloat({ min: 0 }),
    body('leverage').optional().isInt({ min: 1, max: 125 }),
    body('takeProfit').optional().isFloat({ min: 0 }),
    body('stopLoss').optional().isFloat({ min: 0 }),
    body('timeInForce').optional().isIn(['GTC', 'IOC', 'FOK', 'GTD']),
    body('reduceOnly').optional().isBoolean(),
    body('postOnly').optional().isBoolean(),
    body('clientOrderId').optional().trim().isLength({ max: 100 }),
  ],
  validate,
  tradingController.createOrder
);

/**
 * @route   GET /api/v1/trading/orders
 * @desc    Get all orders
 * @access  Private
 */
router.get(
  '/orders',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
    query('side').optional().isIn(['buy', 'sell']),
    query('status').optional().isIn(['pending', 'open', 'partially_filled', 'filled', 'cancelled', 'rejected', 'expired']),
    query('startDate').optional().isISO8601(),
    query('endDate').optional().isISO8601(),
    query('page').optional().isInt({ min: 1 }).toInt(),
    query('limit').optional().isInt({ min: 1, max: 100 }).toInt(),
  ],
  validate,
  tradingController.getOrders
);

/**
 * @route   GET /api/v1/trading/orders/open
 * @desc    Get open orders
 * @access  Private
 */
router.get(
  '/orders/open',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
  ],
  validate,
  tradingController.getOpenOrders
);

router.get(
  '/orders/spot',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
  ],
  validate,
  tradingController.getSpotOrders
);

router.get(
  '/orders/options',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
  ],
  validate,
  tradingController.getOptionOrders
);

router.get(
  '/orders/options/open',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
  ],
  validate,
  tradingController.getOpenOptionOrders
);


/**
 * @route   GET /api/v1/trading/orders/:id
 * @desc    Get order by ID
 * @access  Private
 */
router.get(
  '/orders/:id',
  authenticate,
  [param('id').isUUID()],
  validate,
  tradingController.getOrderById
);

/**
 * @route   DELETE /api/v1/trading/orders/:id
 * @desc    Cancel order
 * @access  Private
 */
router.delete(
  '/orders/:id',
  authenticate,
  [param('id').isUUID()],
  validate,
  tradingController.cancelOrder
);

/**
 * @route   DELETE /api/v1/trading/orders
 * @desc    Cancel all open orders
 * @access  Private
 */
router.delete(
  '/orders',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
  ],
  validate,
  tradingController.cancelAllOrders
);

/**
 * @route   GET /api/v1/trading/trades
 * @desc    Get trade history
 * @access  Private
 */
router.get(
  '/trades',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
    query('side').optional().isIn(['buy', 'sell']),
    query('startDate').optional().isISO8601(),
    query('endDate').optional().isISO8601(),
    query('page').optional().isInt({ min: 1 }).toInt(),
    query('limit').optional().isInt({ min: 1, max: 100 }).toInt(),
  ],
  validate,
  tradingController.getTrades
);

router.get(
  '/history/orders',
  authenticate,
  [
    query('market').optional().isIn(['spot', 'futures', 'margin', 'forex', 'stocks']),
    query('symbol').optional().trim().toUpperCase(),
    query('side').optional().isIn(['buy', 'sell']),
    query('startDate').optional().isISO8601(),
    query('endDate').optional().isISO8601(),
    query('page').optional().isInt({ min: 1 }).toInt(),
    query('limit').optional().isInt({ min: 1, max: 100 }).toInt(),
  ],
  validate,
  tradingController.getTrades
);


/**
 * @route   GET /api/v1/trading/trades/:id
 * @desc    Get trade by ID
 * @access  Private
 */
router.get(
  '/trades/:id',
  authenticate,
  [param('id').isUUID()],
  validate,
  tradingController.getTradeById
);

/**
 * @route   GET /api/v1/trading/statistics
 * @desc    Get trading statistics
 * @access  Private
 */
router.get(
  '/statistics',
  authenticate,
  [
    query('startDate').optional().isISO8601(),
    query('endDate').optional().isISO8601(),
  ],
  validate,
  tradingController.getStatistics
);

/**
 * @route   GET /api/v1/trading/pnl
 * @desc    Get profit/loss data
 * @access  Private
 */
router.get(
  '/pnl',
  authenticate,
  [query('period').optional().isIn(['7d', '30d', '90d', '365d'])],
  validate,
  tradingController.getProfitLoss
);

module.exports = router;
