/**
 * GPS Integration Controller
 * ERP Transportistas
 *
 * REST API endpoints for GPS-Dispatch integration.
 * Sprint: S3 - TASK-007
 * Module: MAI-005/MAI-006 Integration
 */

import { Router, Request, Response, NextFunction } from 'express';
import { DataSource } from 'typeorm';
import { GpsDispatchIntegrationService } from '../services/gps-dispatch-integration.service';

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

export function createGpsIntegrationController(dataSource: DataSource): Router {
  const router = Router();
  const service = new GpsDispatchIntegrationService(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);

  /**
   * Sync GPS positions to unit statuses
   * POST /api/despacho/gps/sincronizar
   */
  router.post('/sincronizar', async (req: TenantRequest, res: Response) => {
    try {
      const actualizados = await service.sincronizarPosicionesGps(req.tenantId!);
      res.json({
        success: true,
        unidadesActualizadas: actualizados,
        timestamp: new Date().toISOString(),
      });
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Get all units with GPS positions
   * GET /api/despacho/gps/unidades
   */
  router.get('/unidades', async (req: TenantRequest, res: Response) => {
    try {
      const unidades = await service.obtenerUnidadesConPosicionGps(req.tenantId!);
      res.json({
        data: unidades,
        total: unidades.length,
        timestamp: new Date().toISOString(),
      });
    } catch (error) {
      res.status(500).json({ error: (error as Error).message });
    }
  });

  /**
   * Get assignment suggestions with real-time GPS data
   * POST /api/despacho/gps/sugerir
   */
  router.post('/sugerir', async (req: TenantRequest, res: Response) => {
    try {
      const {
        viajeId,
        origenLat,
        origenLng,
        tipoCarga,
        pesoKg,
        distanciaRutaKm,
        requiereFrio,
        requiereLicenciaFederal,
        requiereCertificadoMP,
      } = req.body;

      if (!viajeId || !origenLat || !origenLng) {
        return res.status(400).json({
          error: 'viajeId, origenLat y origenLng son requeridos',
        });
      }

      const sugerencias = await service.sugerirAsignacionConGps(req.tenantId!, {
        viajeId,
        origenLat: parseFloat(origenLat),
        origenLng: parseFloat(origenLng),
        tipoCarga,
        pesoKg: pesoKg ? parseFloat(pesoKg) : undefined,
        distanciaRutaKm: distanciaRutaKm ? parseFloat(distanciaRutaKm) : undefined,
        requiereFrio: requiereFrio === true || requiereFrio === 'true',
        requiereLicenciaFederal: requiereLicenciaFederal === true || requiereLicenciaFederal === 'true',
        requiereCertificadoMP: requiereCertificadoMP === true || requiereCertificadoMP === 'true',
      });

      res.json({
        data: sugerencias,
        total: sugerencias.length,
        viajeId,
        timestamp: new Date().toISOString(),
      });
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });

  /**
   * Update unit status from GPS position
   * POST /api/despacho/gps/actualizar-posicion
   */
  router.post('/actualizar-posicion', async (req: TenantRequest, res: Response) => {
    try {
      const { unidadId, latitud, longitud, timestamp } = req.body;

      if (!unidadId || latitud === undefined || longitud === undefined) {
        return res.status(400).json({
          error: 'unidadId, latitud y longitud son requeridos',
        });
      }

      const estadoUnidad = await service.actualizarEstadoUnidadPorGps(
        req.tenantId!,
        unidadId,
        parseFloat(latitud),
        parseFloat(longitud),
        timestamp ? new Date(timestamp) : new Date()
      );

      if (!estadoUnidad) {
        return res.status(404).json({ error: 'Unidad no encontrada' });
      }

      res.json({
        success: true,
        unidadId: estadoUnidad.unidadId,
        posicion: {
          lat: estadoUnidad.ultimaPosicionLat,
          lng: estadoUnidad.ultimaPosicionLng,
          timestamp: estadoUnidad.ultimaActualizacionUbicacion,
        },
      });
    } catch (error) {
      res.status(400).json({ error: (error as Error).message });
    }
  });

  return router;
}
