const {onCall} = require("firebase-functions/v2/https");
const admin = require("firebase-admin");
const nodemailer = require("nodemailer");
const handlebars = require("handlebars");
const fs = require("fs").promises;
const path = require("path");
const {getSmtpConfig, EMAIL_CONFIG} = require("./utils/emailConfig");

/**
 * Envoie un email d'alerte à un utilisateur
 * Appelé par le client Dart via callable function
 */
const handler = async (request) => {
  // Vérifier l'authentification
  if (!request.auth) {
    throw new Error("L'utilisateur doit être authentifié");
  }

  const {alertId, userId, templateType} = request.data;

  if (!alertId || !userId) {
    throw new Error("alertId et userId sont requis");
  }

  try {
    // Récupérer l'alerte depuis Firestore
    const alertDoc = await admin.firestore()
        .collection("alerts")
        .doc(alertId)
        .get();

    if (!alertDoc.exists) {
      throw new Error("Alerte introuvable");
    }

    const alert = alertDoc.data();

    // Récupérer l'utilisateur
    const userDoc = await admin.firestore()
        .collection("users")
        .doc(userId)
        .get();

    if (!userDoc.exists) {
      throw new Error("Utilisateur introuvable");
    }

    const user = userDoc.data();

    // Vérifier les préférences email de l'utilisateur
    const prefs = user.notificationPreferences || {};
    if (!prefs.emailEnabled) {
      console.log(`Email désactivé pour l'utilisateur ${userId}`);
      return {success: true, skipped: true, reason: "email_disabled"};
    }

    // Vérifier la préférence pour ce type d'alerte
    const alertType = alert.type;
    const shouldSend = checkAlertPreference(alertType, prefs);
    if (!shouldSend) {
      console.log(`Type d'alerte ${alertType} désactivé pour ${userId}`);
      return {success: true, skipped: true, reason: "alert_type_disabled"};
    }

    // Préparer les données pour le template
    const templateData = await prepareTemplateData(alert, user);

    // Rendre le template HTML
    const html = await renderTemplate(
        templateType || "alert-individual",
        templateData,
    );

    // Configurer le transporteur SMTP
    const transporter = nodemailer.createTransport(getSmtpConfig());

    // Envoyer l'email
    const info = await transporter.sendMail({
      from: `"${EMAIL_CONFIG.from.name}" <${EMAIL_CONFIG.from.address}>`,
      to: user.email,
      replyTo: EMAIL_CONFIG.replyTo,
      subject: getEmailSubject(alert),
      html: html,
      // Fallback texte brut
      text: alert.message,
    });

    console.log("Email envoyé:", info.messageId);

    // Marquer l'email comme envoyé dans l'alerte
    await alertDoc.ref.update({
      emailSent: true,
      emailSentAt: admin.firestore.FieldValue.serverTimestamp(),
    });

    return {
      success: true,
      messageId: info.messageId,
      skipped: false,
    };
  } catch (error) {
    console.error("Erreur envoi email:", error);
    throw new Error(`Erreur lors de l'envoi de l'email: ${error.message}`);
  }
});

/**
 * Vérifie si l'utilisateur souhaite recevoir ce type d'alerte
 */
function checkAlertPreference(alertType, preferences) {
  const typeMapping = {
    "EVENT_CREATED": "eventsNotifications",
    "EVENT_MODIFIED": "eventsNotifications",
    "EVENT_CANCELLED": "eventsNotifications",
    "LOST": "equipmentNotifications",
    "EQUIPMENT_MISSING": "equipmentNotifications",
    "MAINTENANCE_REMINDER": "maintenanceNotifications",
    "STOCK_LOW": "stockNotifications",
  };

  const prefKey = typeMapping[alertType];
  return prefKey ? (preferences[prefKey] !== false) : true;
}

/**
 * Prépare les données pour le template
 */
async function prepareTemplateData(alert, user) {
  const data = {
    userName: `${user.firstName || ""} ${user.lastName || ""}`.trim() ||
              "Utilisateur",
    alertTitle: getAlertTitle(alert.type),
    alertMessage: alert.message,
    isCritical: alert.severity === "CRITICAL",
    actionUrl: `${EMAIL_CONFIG.appUrl}${alert.actionUrl || "/alerts"}`,
    appUrl: EMAIL_CONFIG.appUrl,
    unsubscribeUrl: `${EMAIL_CONFIG.appUrl}/my_account?tab=notifications`,
    year: new Date().getFullYear(),
    subject: getEmailSubject(alert),
  };

  // Ajouter des détails selon le type d'alerte
  if (alert.eventId) {
    try {
      const eventDoc = await admin.firestore()
          .collection("events")
          .doc(alert.eventId)
          .get();

      if (eventDoc.exists) {
        const event = eventDoc.data();
        data.eventName = event.Name;
        if (event.StartDateTime) {
          const date = event.StartDateTime.toDate();
          data.eventDate = date.toLocaleDateString("fr-FR", {
            day: "2-digit",
            month: "2-digit",
            year: "numeric",
          });
        }
      }
    } catch (error) {
      console.error("Erreur récupération événement:", error);
    }
  }

  if (alert.equipmentId) {
    try {
      const eqDoc = await admin.firestore()
          .collection("equipments")
          .doc(alert.equipmentId)
          .get();

      if (eqDoc.exists) {
        data.equipmentName = eqDoc.data().name;
      }
    } catch (error) {
      console.error("Erreur récupération équipement:", error);
    }
  }

  return data;
}

/**
 * Génère le titre de l'email selon le type d'alerte
 */
function getEmailSubject(alert) {
  const subjects = {
    "EVENT_CREATED": "📅 Nouvel événement créé",
    "EVENT_MODIFIED": "📝 Événement modifié",
    "EVENT_CANCELLED": "❌ Événement annulé",
    "LOST": "🔴 Alerte critique : Équipement perdu",
    "EQUIPMENT_MISSING": "⚠️ Équipement manquant",
    "MAINTENANCE_REMINDER": "🔧 Rappel de maintenance",
    "STOCK_LOW": "📦 Stock faible",
  };

  return subjects[alert.type] || "🔔 Nouvelle alerte - EM2 Events";
}

/**
 * Génère le titre pour le corps de l'email
 */
function getAlertTitle(type) {
  const titles = {
    "EVENT_CREATED": "Nouvel événement créé",
    "EVENT_MODIFIED": "Événement modifié",
    "EVENT_CANCELLED": "Événement annulé",
    "LOST": "Équipement perdu",
    "EQUIPMENT_MISSING": "Équipement manquant",
    "MAINTENANCE_REMINDER": "Maintenance requise",
    "STOCK_LOW": "Stock faible",
  };

  return titles[type] || "Nouvelle alerte";
}

/**
 * Rend un template HTML avec Handlebars
 */
async function renderTemplate(templateName, data) {
  try {
    // Lire le template de base
    const basePath = path.join(__dirname, "templates", "base-template.html");
    const baseTemplate = await fs.readFile(basePath, "utf8");

    // Lire le template de contenu
    const contentPath = path.join(
        __dirname,
        "templates",
        `${templateName}.html`,
    );
    const contentTemplate = await fs.readFile(contentPath, "utf8");

    // Compiler les templates
    const compileContent = handlebars.compile(contentTemplate);
    const compileBase = handlebars.compile(baseTemplate);

    // Rendre le contenu
    const renderedContent = compileContent(data);

    // Rendre le template de base avec le contenu
    return compileBase({
      ...data,
      content: renderedContent,
    });
  } catch (error) {
    console.error("Erreur rendu template:", error);
    // Fallback vers un template simple
    return `
      <html>
        <body>
          <h2>${data.alertTitle}</h2>
          <p>${data.alertMessage}</p>
          <a href="${data.actionUrl}">Voir l'alerte</a>
        </body>
      </html>
    `;
  }
}

exports.sendAlertEmail = onCall({
  region: "europe-west9",
  cors: true,
}, handler);

exports.handler = handler;

