/**
 * WhatsApp Controller
 * ERP Transportistas
 *
 * REST API endpoints for WhatsApp notifications.
 * Sprint: S5 - TASK-007
 * Module: WhatsApp Integration
 */

import { Request, Response, Router } from 'express';
import { DataSource } from 'typeorm';
import {
  WhatsAppNotificationService,
  NotificationRequest,
} from '../services/whatsapp-notification.service';
import { TipoTemplateTransporte } from '../templates/transport-templates';

/**
 * Create WhatsApp controller with DataSource injection
 */
export function createWhatsAppController(dataSource: DataSource): Router {
  const router = Router();
  const notificationService = new WhatsAppNotificationService();

  /**
   * POST /configurar
   * Configure WhatsApp API credentials
   */
  router.post('/configurar', async (req: Request, res: Response) => {
    try {
      const { apiUrl, accessToken, phoneNumberId, businessAccountId } = req.body;

      if (!apiUrl || !accessToken || !phoneNumberId || !businessAccountId) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos: apiUrl, accessToken, phoneNumberId, businessAccountId',
        });
      }

      notificationService.configure({
        apiUrl,
        accessToken,
        phoneNumberId,
        businessAccountId,
      });

      res.json({
        success: true,
        data: {
          message: 'WhatsApp API configurado correctamente',
          enabled: notificationService.isEnabled(),
        },
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * GET /estado
   * Get service status
   */
  router.get('/estado', async (_req: Request, res: Response) => {
    try {
      res.json({
        success: true,
        data: {
          enabled: notificationService.isEnabled(),
          templatesDisponibles: Object.values(TipoTemplateTransporte),
        },
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /enviar
   * Send a single notification
   */
  router.post('/enviar', async (req: Request, res: Response) => {
    try {
      const { telefono, tipoTemplate, parametros, metadata } = req.body;

      if (!telefono || !tipoTemplate || !parametros) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos: telefono, tipoTemplate, parametros',
        });
      }

      // Validate template type
      if (!Object.values(TipoTemplateTransporte).includes(tipoTemplate)) {
        return res.status(400).json({
          success: false,
          error: `Template inválido. Opciones: ${Object.values(TipoTemplateTransporte).join(', ')}`,
        });
      }

      const request: NotificationRequest = {
        telefono,
        tipoTemplate,
        parametros,
        metadata,
      };

      const result = await notificationService.enviarNotificacion(request);

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /enviar-lote
   * Send batch notifications
   */
  router.post('/enviar-lote', async (req: Request, res: Response) => {
    try {
      const { notificaciones } = req.body;

      if (!notificaciones || !Array.isArray(notificaciones) || notificaciones.length === 0) {
        return res.status(400).json({
          success: false,
          error: 'Se requiere un array de notificaciones',
        });
      }

      // Validate each notification
      for (const notif of notificaciones) {
        if (!notif.telefono || !notif.tipoTemplate || !notif.parametros) {
          return res.status(400).json({
            success: false,
            error: 'Cada notificación requiere: telefono, tipoTemplate, parametros',
          });
        }
        if (!Object.values(TipoTemplateTransporte).includes(notif.tipoTemplate)) {
          return res.status(400).json({
            success: false,
            error: `Template inválido: ${notif.tipoTemplate}`,
          });
        }
      }

      const result = await notificationService.enviarLote(notificaciones);

      res.json({
        success: true,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  // ==========================================
  // Transport-Specific Endpoints
  // ==========================================

  /**
   * POST /viaje-asignado
   * Notify operator of trip assignment
   */
  router.post('/viaje-asignado', async (req: Request, res: Response) => {
    try {
      const { telefono, nombreOperador, origen, destino, fecha, horaCita, folioViaje } = req.body;

      if (!telefono || !nombreOperador || !origen || !destino || !fecha || !horaCita || !folioViaje) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos',
        });
      }

      const result = await notificationService.notificarViajeAsignado(telefono, {
        nombreOperador,
        origen,
        destino,
        fecha,
        horaCita,
        folioViaje,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /viaje-confirmado
   * Notify client of shipment confirmation
   */
  router.post('/viaje-confirmado', async (req: Request, res: Response) => {
    try {
      const { telefono, nombreCliente, folio, unidad, operador, fecha, eta, codigoTracking } = req.body;

      if (!telefono || !nombreCliente || !folio || !unidad || !operador || !fecha || !eta || !codigoTracking) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos',
        });
      }

      const result = await notificationService.notificarViajeConfirmado(telefono, {
        nombreCliente,
        folio,
        unidad,
        operador,
        fecha,
        eta,
        codigoTracking,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /eta-actualizado
   * Notify ETA update
   */
  router.post('/eta-actualizado', async (req: Request, res: Response) => {
    try {
      const { telefono, folio, nuevoEta, motivo } = req.body;

      if (!telefono || !folio || !nuevoEta || !motivo) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos: telefono, folio, nuevoEta, motivo',
        });
      }

      const result = await notificationService.notificarEtaActualizado(telefono, {
        folio,
        nuevoEta,
        motivo,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /viaje-completado
   * Notify trip completion
   */
  router.post('/viaje-completado', async (req: Request, res: Response) => {
    try {
      const { telefono, nombreCliente, folio, destino, fechaHora, receptor } = req.body;

      if (!telefono || !nombreCliente || !folio || !destino || !fechaHora || !receptor) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos',
        });
      }

      const result = await notificationService.notificarViajeCompletado(telefono, {
        nombreCliente,
        folio,
        destino,
        fechaHora,
        receptor,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /alerta-retraso
   * Notify delay alert
   */
  router.post('/alerta-retraso', async (req: Request, res: Response) => {
    try {
      const { telefono, nombre, folio, etaOriginal, nuevoEta, motivo } = req.body;

      if (!telefono || !nombre || !folio || !etaOriginal || !nuevoEta || !motivo) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos',
        });
      }

      const result = await notificationService.notificarAlertaRetraso(telefono, {
        nombre,
        folio,
        etaOriginal,
        nuevoEta,
        motivo,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /asignacion-carrier
   * Notify carrier of service request
   */
  router.post('/asignacion-carrier', async (req: Request, res: Response) => {
    try {
      const { telefono, nombreCarrier, origen, destino, fecha, tarifa } = req.body;

      if (!telefono || !nombreCarrier || !origen || !destino || !fecha || !tarifa) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos',
        });
      }

      const result = await notificationService.notificarAsignacionCarrier(telefono, {
        nombreCarrier,
        origen,
        destino,
        fecha,
        tarifa,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  /**
   * POST /recordatorio-mantenimiento
   * Notify maintenance reminder
   */
  router.post('/recordatorio-mantenimiento', async (req: Request, res: Response) => {
    try {
      const { telefono, unidad, tipoMantenimiento, fechaLimite, kmActual, kmProgramado } = req.body;

      if (!telefono || !unidad || !tipoMantenimiento || !fechaLimite || !kmActual || !kmProgramado) {
        return res.status(400).json({
          success: false,
          error: 'Faltan campos requeridos',
        });
      }

      const result = await notificationService.notificarRecordatorioMantenimiento(telefono, {
        unidad,
        tipoMantenimiento,
        fechaLimite,
        kmActual,
        kmProgramado,
      });

      res.json({
        success: result.success,
        data: result,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: (error as Error).message,
      });
    }
  });

  return router;
}
