import { Router } from 'express';

import { authenticate } from '../../middlewares/auth.middleware';
import { requirePermission } from '../../middlewares/rbac.middleware';

import { accessAnalyticsController } from './analytics';
import { accessRequestController } from './request';
import { accessReviewController } from './review';

/**
 * EN: Create and configure Access Management routes
 * VI: Tạo và cấu hình routes cho Access Management
 */
export const createAccessRouter = (): Router => {
    const router = Router();

    // =============================================================================
    // EN: Access Request Endpoints
    // VI: Endpoints Yêu Cầu Truy Cập
    // =============================================================================

    /**
     * @swagger
     * /api/{version}/access/requests:
     *   get:
     *     summary: List access requests
     *     description: List access requests visible to the current user
     *     tags: [Access - Requests]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: query
     *         name: status
     *         schema:
     *           type: string
     *           enum: [PENDING, APPROVED, REJECTED, CANCELLED]
     *       - in: query
     *         name: page
     *         schema:
     *           type: integer
     *       - in: query
     *         name: limit
     *         schema:
     *           type: integer
     *     responses:
     *       200:
     *         description: Requests list
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       type: array
     *                       items:
     *                         $ref: '#/components/schemas/AccessRequest'
     */
    router.get('/requests', authenticate(), accessRequestController.list.bind(accessRequestController));

    /**
     * @swagger
     * /api/{version}/access/requests:
     *   post:
     *     summary: Create access request
     *     description: Submit a new access request
     *     tags: [Access - Requests]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *     requestBody:
     *       required: true
     *       content:
     *         application/json:
     *           schema:
     *             $ref: '#/components/schemas/CreateAccessRequest'
     *     responses:
     *       201:
     *         description: Request created
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       $ref: '#/components/schemas/AccessRequest'
     */
    router.post('/requests', authenticate(), accessRequestController.create.bind(accessRequestController));

    /**
     * @swagger
     * /api/{version}/access/requests/{id}:
     *   get:
     *     summary: Get access request
     *     description: Get access request details
     *     tags: [Access - Requests]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Request ID
     *     responses:
     *       200:
     *         description: Request details
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       $ref: '#/components/schemas/AccessRequest'
     */
    router.get('/requests/:id', authenticate(), accessRequestController.get.bind(accessRequestController));

    /**
     * @swagger
     * /api/{version}/access/requests/{id}/approve:
     *   put:
     *     summary: Approve access request
     *     description: Approve a pending access request
     *     tags: [Access - Requests]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Request ID
     *     requestBody:
     *       content:
     *         application/json:
     *           schema:
     *             type: object
     *             properties:
     *               comment:
     *                 type: string
     *     responses:
     *       200:
     *         description: Request approved
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.put('/requests/:id/approve', authenticate(), requirePermission('access', 'approve'), accessRequestController.approve.bind(accessRequestController));

    /**
     * @swagger
     * /api/{version}/access/requests/{id}/reject:
     *   put:
     *     summary: Reject access request
     *     description: Reject a pending access request
     *     tags: [Access - Requests]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Request ID
     *     requestBody:
     *       content:
     *         application/json:
     *           schema:
     *             type: object
     *             properties:
     *               comment:
     *                 type: string
     *     responses:
     *       200:
     *         description: Request rejected
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.put('/requests/:id/reject', authenticate(), requirePermission('access', 'approve'), accessRequestController.reject.bind(accessRequestController));

    /**
     * @swagger
     * /api/{version}/access/requests/{id}:
     *   delete:
     *     summary: Cancel access request
     *     description: Cancel a pending access request
     *     tags: [Access - Requests]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Request ID
     *     responses:
     *       200:
     *         description: Request cancelled
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.delete('/requests/:id', authenticate(), accessRequestController.cancel.bind(accessRequestController));

    // =============================================================================
    // EN: Access Review Endpoints
    // VI: Endpoints Đánh Giá Truy Cập
    // =============================================================================

    /**
     * @swagger
     * /api/{version}/access/reviews:
     *   get:
     *     summary: List access reviews
     *     description: List access reviews
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *     responses:
     *       200:
     *         description: Reviews list
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       type: array
     *                       items:
     *                         $ref: '#/components/schemas/AccessReview'
     */
    router.get('/reviews', authenticate(), requirePermission('access', 'read'), accessReviewController.list.bind(accessReviewController));

    /**
     * @swagger
     * /api/{version}/access/reviews:
     *   post:
     *     summary: Create access review
     *     description: Create a new access review campaign
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *     requestBody:
     *       required: true
     *       content:
     *         application/json:
     *           schema:
     *             $ref: '#/components/schemas/CreateAccessReviewRequest'
     *     responses:
     *       201:
     *         description: Review created
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       $ref: '#/components/schemas/AccessReview'
     */
    router.post('/reviews', authenticate(), requirePermission('access', 'create'), accessReviewController.create.bind(accessReviewController));

    /**
     * @swagger
     * /api/{version}/access/reviews/{id}:
     *   get:
     *     summary: Get access review
     *     description: Get access review details
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Review ID
     *     responses:
     *       200:
     *         description: Review details
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       $ref: '#/components/schemas/AccessReview'
     */
    router.get('/reviews/:id', authenticate(), requirePermission('access', 'read'), accessReviewController.get.bind(accessReviewController));

    /**
     * @swagger
     * /api/{version}/access/reviews/{id}/start:
     *   post:
     *     summary: Start access review
     *     description: Start an access review campaign
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Review ID
     *     responses:
     *       200:
     *         description: Review started
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.post('/reviews/:id/start', authenticate(), requirePermission('access', 'update'), accessReviewController.start.bind(accessReviewController));

    /**
     * @swagger
     * /api/{version}/access/reviews/{id}/complete:
     *   post:
     *     summary: Complete access review
     *     description: Complete an access review campaign
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Review ID
     *     responses:
     *       200:
     *         description: Review completed
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.post('/reviews/:id/complete', authenticate(), requirePermission('access', 'update'), accessReviewController.complete.bind(accessReviewController));

    /**
     * @swagger
     * /api/{version}/access/reviews/{id}/items:
     *   get:
     *     summary: Get review items
     *     description: Get items in an access review
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Review ID
     *     responses:
     *       200:
     *         description: Review items
     *         content:
     *           application/json:
     *             schema:
     *               allOf:
     *                 - $ref: '#/components/schemas/ApiResponse'
     *                 - type: object
     *                   properties:
     *                     data:
     *                       type: array
     *                       items:
     *                         $ref: '#/components/schemas/AccessReviewItem'
     */
    router.get('/reviews/:id/items', authenticate(), requirePermission('access', 'read'), accessReviewController.getItems.bind(accessReviewController));

    /**
     * @swagger
     * /api/{version}/access/reviews/{id}/items/{itemId}/review:
     *   put:
     *     summary: Review item
     *     description: Make a decision on a review item (Certify/Revoke)
     *     tags: [Access - Reviews]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *       - in: path
     *         name: id
     *         required: true
     *         schema:
     *           type: string
     *         description: Review ID
     *       - in: path
     *         name: itemId
     *         required: true
     *         schema:
     *           type: string
     *         description: Item ID
     *     requestBody:
     *       required: true
     *       content:
     *         application/json:
     *           schema:
     *             type: object
     *             required: [decision]
     *             properties:
     *               decision:
     *                 type: string
     *                 enum: [CERTIFY, REVOKE]
     *               comment:
     *                 type: string
     *     responses:
     *       200:
     *         description: Item reviewed
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.put('/reviews/:id/items/:itemId/review', authenticate(), requirePermission('access', 'update'), accessReviewController.reviewItem.bind(accessReviewController));

    // =============================================================================
    // EN: Analytics Endpoints
    // VI: Endpoints Analytics
    // =============================================================================

    /**
     * @swagger
     * /api/{version}/access/analytics/usage:
     *   get:
     *     summary: Access usage analytics
     *     description: Get access usage analytics
     *     tags: [Access - Analytics]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *     responses:
     *       200:
     *         description: Usage analytics
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.get('/analytics/usage', authenticate(), requirePermission('access', 'read'), accessAnalyticsController.usage.bind(accessAnalyticsController));

    /**
     * @swagger
     * /api/{version}/access/analytics/permissions:
     *   get:
     *     summary: Permissions analytics
     *     description: Get permissions analytics
     *     tags: [Access - Analytics]
     *     security:
     *       - bearerAuth: []
     *     parameters:
     *       - in: path
     *         name: version
     *         required: true
     *         schema:
     *           type: string
     *           default: v1
     *         description: API version
     *     responses:
     *       200:
     *         description: Permissions analytics
     *         content:
     *           application/json:
     *             schema:
     *               $ref: '#/components/schemas/ApiResponse'
     */
    router.get('/analytics/permissions', authenticate(), requirePermission('access', 'read'), accessAnalyticsController.permissions.bind(accessAnalyticsController));

    return router;
};
