import { getDb } from "./db";
import { eq, and, lte, sql } from "drizzle-orm";
import {
  questionnaires,
  sequences,
  inscriptions,
  apprenants,
  datesFormation,
  envoisQuestionnaires,
} from "../drizzle/schema";
import {
  getAllQuestionnaires,
  checkEnvoiExists,
  createEnvoiQuestionnaire,
} from "./questionnaireDb";
import { sendEmail } from "./_core/emailSender";
import crypto from "crypto";

/**
 * Génère un token unique pour accéder au questionnaire
 */
function generateToken(): string {
  return crypto.randomBytes(32).toString("hex");
}

/**
 * Envoie un questionnaire à un apprenant pour une séquence donnée
 */
async function envoyerQuestionnaire(
  questionnaireId: number,
  apprenantId: number,
  sequenceId: number,
  apprenantEmail: string,
  apprenantNom: string,
  apprenantPrenom: string,
  questionnairenom: string,
  sequenceNom: string
) {
  // Vérifier si le questionnaire n'a pas déjà été envoyé
  const dejaEnvoye = await checkEnvoiExists(questionnaireId, apprenantId, sequenceId);
  if (dejaEnvoye) {
    console.log(
      `[Questionnaires] Questionnaire ${questionnaireId} déjà envoyé à l'apprenant ${apprenantId} pour la séquence ${sequenceId}`
    );
    return false;
  }

  // Générer un token unique
  const token = generateToken();

  // Créer l'envoi
  await createEnvoiQuestionnaire({
    questionnaireId,
    apprenantId,
    sequenceId,
    token,
    dateEnvoi: new Date(),
    dateReponse: null,
  });

  // Envoyer l'email
  const lienQuestionnaire = `${process.env.VITE_FRONTEND_URL || "http://localhost:3000"}/questionnaire/${token}`;

  const emailSent = await sendEmail({
    to: apprenantEmail,
    subject: `Questionnaire : ${questionnairenom}`,
    html: `
      <h2>Bonjour ${apprenantPrenom} ${apprenantNom},</h2>
      
      <p>Nous vous remercions d'avoir participé à la formation <strong>${sequenceNom}</strong>.</p>
      
      <p>Afin d'améliorer continuellement la qualité de nos formations, nous vous invitons à répondre à ce questionnaire :</p>
      
      <p style="margin: 30px 0;">
        <a href="${lienQuestionnaire}" 
           style="background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; display: inline-block;">
          Répondre au questionnaire
        </a>
      </p>
      
      <p>Ce questionnaire ne vous prendra que quelques minutes.</p>
      
      <p>Merci pour votre participation !</p>
      
      <p style="margin-top: 30px; font-size: 12px; color: #666;">
        Si le bouton ne fonctionne pas, copiez ce lien dans votre navigateur :<br>
        <a href="${lienQuestionnaire}">${lienQuestionnaire}</a>
      </p>
    `,
  });

  if (emailSent) {
    console.log(
      `[Questionnaires] Questionnaire ${questionnaireId} envoyé à ${apprenantEmail} pour la séquence ${sequenceId}`
    );
    return true;
  } else {
    console.error(
      `[Questionnaires] Échec de l'envoi du questionnaire ${questionnaireId} à ${apprenantEmail}`
    );
    return false;
  }
}

/**
 * Traite les envois automatiques de questionnaires post-formation
 */
export async function processEnvoisAutomatiques() {
  console.log("[Questionnaires] Démarrage du traitement des envois automatiques...");

  const db = await getDb();
  if (!db) {
    console.log("[Questionnaires] Base de données non disponible");
    return { success: false, message: "Base de données non disponible" };
  }

  try {
    // Récupérer tous les questionnaires actifs avec envoi automatique
    const questionnairesActifs = await getAllQuestionnaires();
    const questionnairesAEnvoyer = questionnairesActifs.filter(
      (q) => q.actif && q.envoiAutomatique
    );

    if (questionnairesAEnvoyer.length === 0) {
      console.log("[Questionnaires] Aucun questionnaire avec envoi automatique configuré");
      return { success: true, message: "Aucun questionnaire à envoyer", count: 0 };
    }

    let totalEnvoyes = 0;

    for (const questionnaire of questionnairesAEnvoyer) {
      console.log(
        `[Questionnaires] Traitement du questionnaire "${questionnaire.titre}" (délai: J+${questionnaire.delaiEnvoiJours})`
      );

      // Calculer la date cible (aujourd'hui - délai)
      const dateCible = new Date();
      dateCible.setDate(dateCible.getDate() - questionnaire.delaiEnvoiJours);
      dateCible.setHours(0, 0, 0, 0);

      // Récupérer les séquences terminées à la date cible
      const sequencesTerminees = await db
        .select({
          sequenceId: sequences.id,
          sequenceNom: sequences.nom,
          formationId: sequences.formationId,
        })
        .from(sequences)
        .innerJoin(datesFormation, eq(datesFormation.sequenceId, sequences.id))
        .where(lte(datesFormation.dateFin, dateCible))
        .groupBy(sequences.id);

      console.log(
        `[Questionnaires] ${sequencesTerminees.length} séquence(s) terminée(s) trouvée(s) pour le ${dateCible.toLocaleDateString("fr-FR")}`
      );

      // Pour chaque séquence terminée
      for (const seq of sequencesTerminees) {
        // Vérifier si le questionnaire est lié à une formation spécifique
        if (questionnaire.formationId && questionnaire.formationId !== seq.formationId) {
          continue;
        }

        // Récupérer les apprenants inscrits et validés
        const apprenantsInscrits = await db
          .select({
            apprenantId: apprenants.id,
            apprenantEmail: apprenants.email,
            apprenantNom: apprenants.nom,
            apprenantPrenom: apprenants.prenom,
          })
          .from(inscriptions)
          .innerJoin(apprenants, eq(apprenants.id, inscriptions.apprenantId))
          .where(
            and(
              eq(inscriptions.sequenceId, seq.sequenceId),
              eq(inscriptions.statut, "confirmee")
            )
          );

        console.log(
          `[Questionnaires] ${apprenantsInscrits.length} apprenant(s) inscrit(s) à la séquence ${seq.sequenceId}`
        );

        // Envoyer le questionnaire à chaque apprenant
        for (const apprenant of apprenantsInscrits) {
          if (!apprenant.apprenantEmail) {
            console.log(
              `[Questionnaires] Apprenant ${apprenant.apprenantId} sans email, envoi ignoré`
            );
            continue;
          }

          const envoye = await envoyerQuestionnaire(
            questionnaire.id,
            apprenant.apprenantId,
            seq.sequenceId,
            apprenant.apprenantEmail,
            apprenant.apprenantNom,
            apprenant.apprenantPrenom,
            questionnaire.titre,
            seq.sequenceNom
          );

          if (envoye) {
            totalEnvoyes++;
          }
        }
      }
    }

    console.log(`[Questionnaires] Traitement terminé - ${totalEnvoyes} questionnaire(s) envoyé(s)`);
    return {
      success: true,
      message: `${totalEnvoyes} questionnaire(s) envoyé(s)`,
      count: totalEnvoyes,
    };
  } catch (error: any) {
    console.error("[Questionnaires] Erreur lors du traitement :", error);
    return { success: false, message: error.message, count: 0 };
  }
}

/**
 * Initialise le scheduler pour les envois automatiques de questionnaires
 * Exécute le traitement tous les jours à 9h00
 */
export function initQuestionnaireScheduler() {
  console.log("[Questionnaires] Initialisation du scheduler d'envoi automatique");

  // Exécuter immédiatement au démarrage
  processEnvoisAutomatiques();

  // Puis exécuter tous les jours à 9h00
  const interval = setInterval(
    () => {
      const now = new Date();
      if (now.getHours() === 9 && now.getMinutes() === 0) {
        processEnvoisAutomatiques();
      }
    },
    60 * 1000 // Vérifier toutes les minutes
  );

  console.log("[Questionnaires] Scheduler initialisé - vérification quotidienne à 9h00");

  return interval;
}
