/**
 * Certificacion Controller
 * ERP Transportistas
 *
 * REST API endpoints for operator certifications.
 * Module: MAI-005 Despacho
 * Adapted from: erp-mecanicas-diesel MMD-011 SkillController
 */

import { Router, Request, Response, NextFunction } from 'express';
import { DataSource } from 'typeorm';
import { CertificacionService, FiltrosCertificacion } from '../services/certificacion.service';
import { NivelCertificacion } from '../entities/operador-certificacion.entity';

interface TenantRequest extends Request {
  tenantId?: string;
  userId?: string;
}

export function createCertificacionController(dataSource: DataSource): Router {
  const router = Router();
  const service = new CertificacionService(dataSource);

  const extractTenant = (req: TenantRequest, res: Response, next: NextFunction) => {
    const tenantId = req.headers['x-tenant-id'] as string;
    if (!tenantId) {
      return res.status(400).json({ error: 'Tenant ID es requerido' });
    }
    req.tenantId = tenantId;
    req.userId = req.headers['x-user-id'] as string;
    next();
  };

  router.use(extractTenant);

  /**
   * Add certification to operator
   * POST /api/despacho/certificaciones
   */
  router.post('/', async (req: TenantRequest, res: Response) => {
    try {
      const certificacion = await service.agregarCertificacion(req.tenantId!, req.body);
      res.status(201).json(certificacion);
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });

  /**
   * List certifications with filters
   * GET /api/despacho/certificaciones
   */
  router.get('/', async (req: TenantRequest, res: Response) => {
    try {
      const filtros: FiltrosCertificacion = {
        operadorId: req.query.operadorId as string,
        codigoCertificacion: req.query.codigoCertificacion as string,
        nivel: req.query.nivel as NivelCertificacion,
        activa: req.query.activa === 'true' ? true : req.query.activa === 'false' ? false : undefined,
        porVencerDias: req.query.porVencerDias
          ? parseInt(req.query.porVencerDias as string, 10)
          : undefined,
      };

      const paginacion = {
        pagina: parseInt(req.query.pagina as string, 10) || 1,
        limite: Math.min(parseInt(req.query.limite as string, 10) || 20, 100),
      };

      const resultado = await service.listar(req.tenantId!, filtros, paginacion);
      res.json(resultado);
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Get certification matrix
   * GET /api/despacho/certificaciones/matriz
   */
  router.get('/matriz', async (req: TenantRequest, res: Response) => {
    try {
      const matriz = await service.getMatrizCertificaciones(req.tenantId!);
      res.json(matriz);
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Get expiring certifications
   * GET /api/despacho/certificaciones/por-vencer
   */
  router.get('/por-vencer', async (req: TenantRequest, res: Response) => {
    try {
      const dias = parseInt(req.query.dias as string, 10) || 30;
      const certificaciones = await service.getCertificacionesPorVencer(req.tenantId!, dias);
      res.json(certificaciones);
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Get operators with specific certification
   * GET /api/despacho/certificaciones/por-codigo/:codigoCertificacion
   */
  router.get('/por-codigo/:codigoCertificacion', async (req: TenantRequest, res: Response) => {
    try {
      const nivelMinimo = req.query.nivelMinimo as NivelCertificacion;
      const certificaciones = await service.getOperadoresConCertificacion(
        req.tenantId!,
        req.params.codigoCertificacion,
        nivelMinimo
      );
      res.json(certificaciones);
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Get certifications for operator
   * GET /api/despacho/certificaciones/operador/:operadorId
   */
  router.get('/operador/:operadorId', async (req: TenantRequest, res: Response) => {
    try {
      const soloActivas = req.query.soloActivas !== 'false';
      const certificaciones = await service.getCertificacionesOperador(
        req.tenantId!,
        req.params.operadorId,
        soloActivas
      );
      res.json(certificaciones);
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Validate operator certifications for service
   * POST /api/despacho/certificaciones/validar
   */
  router.post('/validar', async (req: TenantRequest, res: Response) => {
    try {
      const { operadorId, certificacionesRequeridas, nivelMinimo } = req.body;
      const resultado = await service.validarCertificacionesOperador(
        req.tenantId!,
        operadorId,
        certificacionesRequeridas,
        nivelMinimo
      );
      res.json(resultado);
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });

  /**
   * Get certification by ID
   * GET /api/despacho/certificaciones/:id
   */
  router.get('/:id', async (req: TenantRequest, res: Response) => {
    try {
      const certificacion = await service.getById(req.tenantId!, req.params.id);
      if (!certificacion) {
        return res.status(404).json({ error: 'Certificacion no encontrada' });
      }
      res.json(certificacion);
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Update certification
   * PATCH /api/despacho/certificaciones/:id
   */
  router.patch('/:id', async (req: TenantRequest, res: Response) => {
    try {
      const certificacion = await service.actualizarCertificacion(req.tenantId!, req.params.id, req.body);
      if (!certificacion) {
        return res.status(404).json({ error: 'Certificacion no encontrada' });
      }
      res.json(certificacion);
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });

  /**
   * Verify certification (admin)
   * POST /api/despacho/certificaciones/:id/verificar
   */
  router.post('/:id/verificar', async (req: TenantRequest, res: Response) => {
    try {
      const certificacion = await service.verificarCertificacion(req.tenantId!, req.params.id, req.userId!);
      if (!certificacion) {
        return res.status(404).json({ error: 'Certificacion no encontrada' });
      }
      res.json(certificacion);
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });

  /**
   * Deactivate certification
   * DELETE /api/despacho/certificaciones/:id
   */
  router.delete('/:id', async (req: TenantRequest, res: Response) => {
    try {
      const success = await service.desactivarCertificacion(req.tenantId!, req.params.id);
      if (!success) {
        return res.status(404).json({ error: 'Certificacion no encontrada' });
      }
      res.status(204).send();
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  return router;
}
