/**
 * Payments Routes
 * API routes for payment operations
 */

// Import Express router
const express = require('express');
// Create router instance
const router = express.Router();
// Import payment controllers
const paymentControllers = require('../controllers');
// Import validation rules
const paymentValidations = require('../validations');
// Import authentication middleware
const { authenticate, requireRole, requireAnyRole } = require('../../../middlewares/auth');

/**
 * @swagger
 * /api/payments:
 *   post:
 *     summary: Create payment (Cash/Bank)
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - sale_id
 *               - provider
 *               - amount
 *             properties:
 *               sale_id:
 *                 type: integer
 *                 description: Sale ID
 *               provider:
 *                 type: string
 *                 enum: [CASH, CARD, MPESA]
 *                 description: Payment provider
 *               amount:
 *                 type: number
 *                 description: Payment amount
 *               reference:
 *                 type: string
 *                 description: Payment reference (optional)
 *     responses:
 *       201:
 *         description: Payment created successfully
 *       400:
 *         description: Validation error
 *       404:
 *         description: Sale not found
 */
router.post(
  '/', // POST /api/payments
  authenticate, // Require authentication
  requireAnyRole(['cashier', 'manager', 'system_admin']), // Require role
  paymentValidations.validateCreatePayment, // Validate request
  paymentControllers.createPayment // Create payment controller
);

/**
 * @swagger
 * /api/payments/paystack/initialize:
 *   post:
 *     summary: Initialize Paystack payment
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - sale_id
 *               - email
 *               - amount
 *             properties:
 *               sale_id:
 *                 type: integer
 *                 description: Sale ID
 *               email:
 *                 type: string
 *                 format: email
 *                 description: Customer email
 *               amount:
 *                 type: number
 *                 description: Payment amount
 *               metadata:
 *                 type: object
 *                 description: Additional metadata (optional)
 *     responses:
 *       201:
 *         description: Paystack payment initialized successfully
 *       400:
 *         description: Validation error
 *       404:
 *         description: Sale not found
 */
router.post(
  '/paystack/initialize', // POST /api/payments/paystack/initialize
  authenticate, // Require authentication
  requireAnyRole(['cashier', 'manager', 'system_admin']), // Require role
  paymentValidations.validateProcessPaystackPayment, // Validate request
  paymentControllers.processPaystackPayment // Process Paystack payment controller
);

/**
 * @swagger
 * /api/payments/paystack/verify/{reference}:
 *   post:
 *     summary: Verify Paystack payment
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: reference
 *         required: true
 *         schema:
 *           type: string
 *         description: Payment reference
 *     responses:
 *       200:
 *         description: Payment verified successfully
 *       400:
 *         description: Validation error
 *       404:
 *         description: Payment not found
 */
router.post(
  '/paystack/verify/:reference', // POST /api/payments/paystack/verify/:reference
  authenticate, // Require authentication
  requireAnyRole(['cashier', 'manager', 'system_admin']), // Require role
  paymentValidations.validateVerifyPaystackPayment, // Validate request
  paymentControllers.verifyPaystackPayment // Verify Paystack payment controller
);

/**
 * @swagger
 * /api/payments/paystack/webhook:
 *   post:
 *     summary: Handle Paystack webhook
 *     tags: [Payments]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *     responses:
 *       200:
 *         description: Webhook received
 */
router.post(
  '/paystack/webhook', // POST /api/payments/paystack/webhook
  // Note: Webhook endpoint should verify Paystack signature in production
  paymentControllers.handlePaystackWebhook // Handle Paystack webhook controller
);

/**
 * @swagger
 * /api/payments/mobile:
 *   post:
 *     summary: Process mobile money payment
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - sale_id
 *               - amount
 *               - phone_number
 *             properties:
 *               sale_id:
 *                 type: integer
 *                 description: Sale ID
 *               amount:
 *                 type: number
 *                 description: Payment amount
 *               phone_number:
 *                 type: string
 *                 description: Phone number (E.164 format)
 *     responses:
 *       201:
 *         description: Mobile money payment processed successfully
 *       400:
 *         description: Validation error
 *       404:
 *         description: Sale not found
 */
router.post(
  '/mobile', // POST /api/payments/mobile
  authenticate, // Require authentication
  requireAnyRole(['cashier', 'manager', 'system_admin']), // Require role
  paymentValidations.validateProcessMobileMoneyPayment, // Validate request
  paymentControllers.processMobileMoneyPayment // Process mobile money payment controller
);

/**
 * @swagger
 * /api/payments/mpesa/query/{checkoutRequestID}:
 *   get:
 *     summary: Query M-Pesa STK Push status
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: checkoutRequestID
 *         required: true
 *         schema:
 *           type: string
 *         description: Checkout Request ID from STK Push
 *     responses:
 *       200:
 *         description: Status queried successfully
 *       400:
 *         description: Validation error
 *       404:
 *         description: Payment not found
 */
router.get(
  '/mpesa/query/:checkoutRequestID', // GET /api/payments/mpesa/query/:checkoutRequestID
  authenticate, // Require authentication
  requireAnyRole(['cashier', 'manager', 'system_admin']), // Require role
  paymentValidations.validateQuerySTKPushStatus, // Validate request
  paymentControllers.querySTKPushStatus // Query STK Push status controller
);

/**
 * @swagger
 * /api/payments/mpesa/callback:
 *   post:
 *     summary: Handle M-Pesa callback/webhook
 *     tags: [Payments]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *     responses:
 *       200:
 *         description: Callback processed successfully
 */
router.post(
  '/mpesa/callback', // POST /api/payments/mpesa/callback
  // Note: M-Pesa callback should verify signature in production
  paymentControllers.handleMPesaCallback // Handle M-Pesa callback controller
);

/**
 * @swagger
 * /api/payments/mpesa/manual-confirm:
 *   post:
 *     summary: Manually confirm M-Pesa payment (manager/admin only)
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - payment_id
 *               - mpesa_transaction_code
 *             properties:
 *               payment_id:
 *                 type: integer
 *                 description: Payment ID
 *               mpesa_transaction_code:
 *                 type: string
 *                 description: M-Pesa transaction code (receipt number)
 *     responses:
 *       200:
 *         description: Payment confirmed successfully
 *       400:
 *         description: Validation error
 *       404:
 *         description: Payment not found
 *       403:
 *         description: Unauthorized (manager/admin only)
 */
router.post(
  '/mpesa/manual-confirm', // POST /api/payments/mpesa/manual-confirm
  authenticate, // Require authentication
  requireAnyRole(['manager', 'system_admin']), // Require manager/admin role
  paymentValidations.validateManuallyConfirmMPesaPayment, // Validate request
  paymentControllers.manuallyConfirmMPesaPayment // Manually confirm M-Pesa payment controller
);

/**
 * @swagger
 * /api/payments:
 *   get:
 *     summary: List payments
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *         description: Page number
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *         description: Items per page
 *       - in: query
 *         name: sale_id
 *         schema:
 *           type: integer
 *         description: Filter by sale ID
 *       - in: query
 *         name: provider
 *         schema:
 *           type: string
 *           enum: [CASH, CARD, MPESA]
 *         description: Filter by provider
 *       - in: query
 *         name: status
 *         schema:
 *           type: string
 *           enum: [PENDING, SUCCESS, FAILED]
 *         description: Filter by status
 *       - in: query
 *         name: start_date
 *         schema:
 *           type: string
 *           format: date-time
 *         description: Filter by start date
 *       - in: query
 *         name: end_date
 *         schema:
 *           type: string
 *           format: date-time
 *         description: Filter by end date
 *     responses:
 *       200:
 *         description: Payments retrieved successfully
 */
router.get(
  '/', // GET /api/payments
  authenticate, // Require authentication
  paymentValidations.validateListPayments, // Validate request
  paymentControllers.listPayments // List payments controller
);

/**
 * @swagger
 * /api/payments/{id}:
 *   get:
 *     summary: Get payment by ID
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: integer
 *         description: Payment ID
 *     responses:
 *       200:
 *         description: Payment retrieved successfully
 *       404:
 *         description: Payment not found
 */
router.get(
  '/:id', // GET /api/payments/:id
  authenticate, // Require authentication
  paymentValidations.validateGetPayment, // Validate request
  paymentControllers.getPayment // Get payment controller
);

/**
 * @swagger
 * /api/payments/sale/{saleId}:
 *   get:
 *     summary: Get payments for a sale
 *     tags: [Payments]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: saleId
 *         required: true
 *         schema:
 *           type: integer
 *         description: Sale ID
 *     responses:
 *       200:
 *         description: Sale payments retrieved successfully
 *       404:
 *         description: Sale not found
 */
router.get(
  '/sale/:saleId', // GET /api/payments/sale/:saleId
  authenticate, // Require authentication
  paymentValidations.validateGetSalePayments, // Validate request
  paymentControllers.getSalePayments // Get sale payments controller
);

// Export router
module.exports = router;
