import { Router } from 'express';
import { z } from 'zod';
import { CollaborationController } from './collaborationController';
import { validate, validateMultiple } from '../api/middleware/validation.middleware';
import { authenticateToken, requirePermission } from '../api/middleware/rbac.middleware';
import { generalLimiter, strictLimiter } from '../api/middleware/rateLimit.middleware';
import { Permission } from '../api/services/rbac.service';

const router = Router();
const collaborationController = new CollaborationController();

// Validation schemas
const DocumentIdSchema = z.object({
  documentId: z.string().min(1)
});

const ChangeHistorySchema = z.object({
  limit: z.coerce.number().int().min(1).max(1000).optional()
});

const RestoreSnapshotSchema = z.object({
  snapshot: z.record(z.any())
});

const ApplyChangeSchema = z.object({
  field: z.string().min(1),
  value: z.any()
});

/**
 * @route   GET /api/collaboration/:documentId/status
 * @desc    Get collaboration status for a document
 * @access  Protected
 */
router.get(
  '/:documentId/status',
  authenticateToken,
  generalLimiter,
  validate(DocumentIdSchema, 'params'),
  (req: any, res) => collaborationController.getDocumentStatus(req, res)
);

/**
 * @route   GET /api/collaboration/:documentId/history
 * @desc    Get change history for a document
 * @access  Protected
 */
router.get(
  '/:documentId/history',
  authenticateToken,
  generalLimiter,
  validateMultiple({
    params: DocumentIdSchema,
    query: ChangeHistorySchema
  }),
  (req: any, res) => collaborationController.getChangeHistory(req, res)
);

/**
 * @route   GET /api/collaboration/:documentId/snapshot
 * @desc    Create a snapshot of the current document state
 * @access  Protected
 */
router.get(
  '/:documentId/snapshot',
  authenticateToken,
  generalLimiter,
  validate(DocumentIdSchema, 'params'),
  (req: any, res) => collaborationController.createSnapshot(req, res)
);

/**
 * @route   POST /api/collaboration/:documentId/restore
 * @desc    Restore document from a snapshot
 * @access  Protected - Requires UPDATE_TASK permission
 */
router.post(
  '/:documentId/restore',
  authenticateToken,
  requirePermission(Permission.UPDATE_TASK),
  strictLimiter,
  validateMultiple({
    params: DocumentIdSchema,
    body: RestoreSnapshotSchema
  }),
  (req: any, res) => collaborationController.restoreSnapshot(req, res)
);

/**
 * @route   POST /api/collaboration/:documentId/apply
 * @desc    Apply external changes to a document
 * @access  Protected - Requires UPDATE_TASK permission
 */
router.post(
  '/:documentId/apply',
  authenticateToken,
  requirePermission(Permission.UPDATE_TASK),
  strictLimiter,
  validateMultiple({
    params: DocumentIdSchema,
    body: ApplyChangeSchema
  }),
  (req: any, res) => collaborationController.applyChange(req, res)
);

/**
 * @route   GET /api/collaboration/:documentId/users
 * @desc    Get active users for a document
 * @access  Protected
 */
router.get(
  '/:documentId/users',
  authenticateToken,
  generalLimiter,
  validate(DocumentIdSchema, 'params'),
  (req: any, res) => collaborationController.getActiveUsers(req, res)
);

/**
 * @route   DELETE /api/collaboration/:documentId
 * @desc    Clean up a document (admin only)
 * @access  Protected - Admin only
 */
router.delete(
  '/:documentId',
  authenticateToken,
  requirePermission(Permission.MANAGE_SYSTEM),
  strictLimiter,
  validate(DocumentIdSchema, 'params'),
  (req: any, res) => collaborationController.cleanupDocument(req, res)
);

export default router;