import { Router } from 'express';
import { {{entity}}Controller } from '../controllers/{{entityLower}}.controller';
import { {{entity}}Service } from '../services/{{entityLower}}.service';
import { {{entity}}Validators } from '../validators/{{entityLower}}.validator';
import { paginationMiddleware, validateIdMiddleware, sanitizeInputMiddleware } from '../middleware/crud.middleware';
{{#if features.auth}}
import { authMiddleware, requireRoles } from '../middleware/auth.middleware';
{{/if}}
{{#if features.rateLimit}}
import { rateLimitMiddleware } from '../middleware/rateLimit.middleware';
{{/if}}
{{#if features.audit}}
import { AuditService } from '../services/audit.service';
{{/if}}

const router = Router();

// Inicializar servicios y controlador
const {{entityLower}}Service = new {{entity}}Service();
{{#if features.audit}}
const auditService = new AuditService();
const {{entityLower}}Controller = new {{entity}}Controller({{entityLower}}Service, auditService);
{{else}}
const {{entityLower}}Controller = new {{entity}}Controller({{entityLower}}Service);
{{/if}}

// Middleware global para todas las rutas
{{#if features.rateLimit}}
router.use(rateLimitMiddleware);
{{/if}}
{{#if features.auth}}
router.use(authMiddleware);
{{/if}}

/**
 * @swagger
 * components:
 *   schemas:
 *     {{entity}}:
 *       type: object
 *       properties:
 *         id:
 *           type: string
 *           description: Unique identifier
 *         createdAt:
 *           type: string
 *           format: date-time
 *           description: Creation timestamp
 *         updatedAt:
 *           type: string
 *           format: date-time
 *           description: Last update timestamp
 *       required:
 *         - id
 *     {{entity}}Create:
 *       type: object
 *       properties:
 *         # Agregar propiedades específicas de la entidad aquí
 *       required:
 *         # Agregar campos requeridos aquí
 *     {{entity}}Update:
 *       type: object
 *       properties:
 *         # Agregar propiedades específicas de la entidad aquí
 *     Pagination:
 *       type: object
 *       properties:
 *         page:
 *           type: integer
 *           description: Current page number
 *         limit:
 *           type: integer
 *           description: Items per page
 *         total:
 *           type: integer
 *           description: Total number of items
 *         totalPages:
 *           type: integer
 *           description: Total number of pages
 *         hasNext:
 *           type: boolean
 *           description: Whether there is a next page
 *         hasPrev:
 *           type: boolean
 *           description: Whether there is a previous page
 */

/**
 * @swagger
 * tags:
 *   name: {{entity}}
 *   description: {{entity}} management endpoints
 */

// GET /{{entityPlural}} - Obtener todos los {{entityPlural}}
router.get(
  '/',
  paginationMiddleware,
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entityLower}}Controller.findAll.bind({{entityLower}}Controller)
);

// GET /{{entityPlural}}/:id - Obtener {{entity}} por ID
router.get(
  '/:id',
  validateIdMiddleware,
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entityLower}}Controller.findById.bind({{entityLower}}Controller)
);

// POST /{{entityPlural}} - Crear nuevo {{entity}}
router.post(
  '/',
  sanitizeInputMiddleware,
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entity}}Validators.validateCreation,
  {{entityLower}}Controller.create.bind({{entityLower}}Controller)
);

// PUT /{{entityPlural}}/:id - Actualizar {{entity}}
router.put(
  '/:id',
  validateIdMiddleware,
  sanitizeInputMiddleware,
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entity}}Validators.validateUpdate,
  {{entityLower}}Controller.update.bind({{entityLower}}Controller)
);

// PATCH /{{entityPlural}}/:id - Actualización parcial de {{entity}}
router.patch(
  '/:id',
  validateIdMiddleware,
  sanitizeInputMiddleware,
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entity}}Validators.validatePartialUpdate,
  {{entityLower}}Controller.update.bind({{entityLower}}Controller)
);

// DELETE /{{entityPlural}}/:id - Eliminar {{entity}}
router.delete(
  '/:id',
  validateIdMiddleware,
  {{#if features.auth}}
  requireRoles(['admin']),
  {{/if}}
  {{entityLower}}Controller.delete.bind({{entityLower}}Controller)
);

// GET /{{entityPlural}}/search - Búsqueda avanzada
router.get(
  '/search',
  paginationMiddleware,
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entity}}Validators.validateSearch,
  {{entityLower}}Controller.search.bind({{entityLower}}Controller)
);

// GET /{{entityPlural}}/count - Contar registros
router.get(
  '/count',
  {{#if features.auth}}
  requireRoles(['admin', 'user']),
  {{/if}}
  {{entityLower}}Controller.count.bind({{entityLower}}Controller)
);

// POST /{{entityPlural}}/bulk - Operaciones en lote
router.post(
  '/bulk',
  {{#if features.auth}}
  requireRoles(['admin']),
  {{/if}}
  {{entity}}Validators.validateBulkOperation,
  {{entityLower}}Controller.bulkOperation.bind({{entityLower}}Controller)
);

// GET /{{entityPlural}}/export - Exportar datos
router.get(
  '/export',
  {{#if features.auth}}
  requireRoles(['admin']),
  {{/if}}
  {{entityLower}}Controller.export.bind({{entityLower}}Controller)
);

// Middleware de manejo de errores específico para {{entity}}
router.use((error: any, req: any, res: any, next: any) => {
  if (error.code === 'P2002') {
    // Prisma unique constraint error
    return res.status(409).json({
      success: false,
      message: 'A {{entity}} with this data already exists',
      error: 'DUPLICATE_ENTRY'
    });
  }
  
  if (error.code === 'P2025') {
    // Prisma record not found error
    return res.status(404).json({
      success: false,
      message: '{{entity}} not found',
      error: 'NOT_FOUND'
    });
  }
  
  next(error);
});

export default router;