/**
 * Service d'export des données en Excel et PDF
 */

import * as XLSX from 'xlsx';
import { jsPDF } from 'jspdf';
import autoTable from 'jspdf-autotable';
import * as fs from 'fs';
import * as path from 'path';

interface InscriptionExport {
  nom: string;
  prenom: string;
  email: string;
  codeEtablissement: string | null;
  fonction: string | null;
  statut: string;
  dateInscription: Date;
}

interface SequenceInfo {
  formationNom: string;
  sequenceNom: string;
  dates: Array<{ dateDebut: Date; dateFin: Date; ordre: number }>;
  lieu: string;
  publicCible: string;
  inscriptions: InscriptionExport[];
}

interface ApprenantPresence {
  nom: string;
  prenom: string;
  codeEtablissement: string | null;
  fonction: string | null;
  presences?: Array<{
    dateFormationId: number;
    periode: 'matin' | 'apres_midi';
    signatureUrl: string | null;
  }>;
}

interface FeuillePresenceInfo {
  formationNom: string;
  sequenceNom: string;
  dates: Array<{ id: number; dateDebut: Date; dateFin: Date; ordre: number }>;
  lieu: string;
  publicCible: string;
  formateur?: string;
  apprenants: ApprenantPresence[];
  signaturesFormateurs?: Array<{
    dateFormationId: number;
    periode: 'matin' | 'apres_midi';
    signatureUrl: string | null;
  }>;
}

/**
 * Génère un fichier Excel avec la liste des inscrits
 */
export function generateExcelExport(sequenceInfo: SequenceInfo): Buffer {
  // Préparer les données
  const data = sequenceInfo.inscriptions.map(i => ({
    'Nom': i.nom,
    'Prénom': i.prenom,
    'Email': i.email,
    'Code établissement': i.codeEtablissement || '',
    'Fonction': i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre',
    'Statut': i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée',
    'Date d\'inscription': i.dateInscription.toLocaleDateString('fr-FR'),
  }));

  // Créer le workbook
  const ws = XLSX.utils.json_to_sheet(data);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, 'Inscrits');

  // Ajouter une feuille d'informations
  const infoData = [
    { 'Information': 'Formation', 'Valeur': sequenceInfo.formationNom },
    { 'Information': 'Séquence', 'Valeur': sequenceInfo.sequenceNom },
    { 'Information': 'Lieu', 'Valeur': sequenceInfo.lieu },
    { 'Information': 'Public cible', 'Valeur': sequenceInfo.publicCible === 'directeur' ? 'Directeurs' : sequenceInfo.publicCible === 'chef_service' ? 'Chefs de service' : sequenceInfo.publicCible === 'tous' ? 'Tous' : 'Autre' },
    { 'Information': 'Nombre d\'inscrits', 'Valeur': sequenceInfo.inscriptions.length.toString() },
  ];

  // Ajouter les dates
  sequenceInfo.dates.forEach(date => {
    infoData.push({
      'Information': `Date ${date.ordre}`,
      'Valeur': date.dateDebut.toLocaleDateString('fr-FR', { 
        weekday: 'long', 
        year: 'numeric', 
        month: 'long', 
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
      })
    });
  });

  const wsInfo = XLSX.utils.json_to_sheet(infoData);
  XLSX.utils.book_append_sheet(wb, wsInfo, 'Informations');

  // Générer le buffer
  return Buffer.from(XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' }));
}

/**
 * Génère un PDF avec la liste des inscrits
 */
export function generatePDFExport(sequenceInfo: SequenceInfo): Buffer {
  const doc = new jsPDF();

  // Titre
  doc.setFontSize(18);
  doc.text('Liste des inscrits', 14, 20);

  // Informations de séquence
  doc.setFontSize(10);
  let yPos = 35;
  doc.text(`Formation : ${sequenceInfo.formationNom}`, 14, yPos);
  yPos += 6;
  doc.text(`Séquence : ${sequenceInfo.sequenceNom}`, 14, yPos);
  yPos += 6;
  doc.text(`Lieu : ${sequenceInfo.lieu}`, 14, yPos);
  yPos += 6;
  doc.text(`Public cible : ${sequenceInfo.publicCible === 'directeur' ? 'Directeurs' : sequenceInfo.publicCible === 'chef_service' ? 'Chefs de service' : sequenceInfo.publicCible === 'tous' ? 'Tous' : 'Autre'}`, 14, yPos);
  yPos += 8;

  // Dates de formation
  doc.setFontSize(9);
  sequenceInfo.dates.forEach(date => {
    doc.text(`Date ${date.ordre} : ${date.dateDebut.toLocaleDateString('fr-FR', { 
      weekday: 'long', 
      year: 'numeric', 
      month: 'long', 
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    })}`, 14, yPos);
    yPos += 5;
  });

  // Tableau des inscrits
  const tableData = sequenceInfo.inscriptions.map(i => [
    i.nom,
    i.prenom,
    i.email,
    i.codeEtablissement || '',
    i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre',
    i.statut === 'confirmee' ? 'Confirmée' : i.statut === 'liste_attente' ? 'Liste d\'attente' : 'Annulée',
  ]);

  autoTable(doc, {
    startY: yPos + 10,
    head: [['Nom', 'Prénom', 'Email', 'Code étab.', 'Fonction', 'Statut']],
    body: tableData,
    styles: { fontSize: 9 },
    headStyles: { fillColor: [37, 99, 235] },
  });

  return Buffer.from(doc.output('arraybuffer'));
}

/**
 * Génère une feuille de présence PDF avec signatures matin/après-midi pour chaque journée
 */
export function generateFeuillePresence(feuilleInfo: FeuillePresenceInfo): Buffer {
  const doc = new jsPDF();
  
  // Charger le logo
  let logoData: string | null = null;
  
  try {
    // Utiliser un chemin absolu depuis la racine du projet
    const logoPath = path.resolve(process.cwd(), 'client/public/itinova-logo.png');
    const logoBuffer = fs.readFileSync(logoPath);
    logoData = `data:image/png;base64,${logoBuffer.toString('base64')}`;
  } catch (error) {
    console.warn('Logo Itinova non trouvé, génération sans logo:', error);
  }

  // Fonction pour générer une page de feuille de présence pour une journée
  const generatePageForDate = (dateInfo: { dateDebut: Date; dateFin: Date; ordre: number }, isFirstPage: boolean) => {
    if (!isFirstPage) {
      doc.addPage();
    }

    // Ajouter le logo en haut à droite si disponible
    if (logoData) {
      doc.addImage(logoData, 'PNG', 160, 10, 40, 15);
    }

    // Titre
    doc.setFontSize(18);
    doc.text('Feuille de présence', 14, 20);

    // Informations de séquence
    doc.setFontSize(10);
    let yPos = 35;
    doc.text(`Formation : ${feuilleInfo.formationNom}`, 14, yPos);
    yPos += 6;
    doc.text(`Séquence : ${feuilleInfo.sequenceNom}`, 14, yPos);
    yPos += 6;
    doc.text(`Lieu : ${feuilleInfo.lieu}`, 14, yPos);
    yPos += 6;
    
    // Ajouter le formateur si disponible
    if (feuilleInfo.formateur) {
      doc.text(`Formateur : ${feuilleInfo.formateur}`, 14, yPos);
      yPos += 6;
    }
    
    doc.text(`Public cible : ${feuilleInfo.publicCible === 'directeur' ? 'Directeurs' : feuilleInfo.publicCible === 'chef_service' ? 'Chefs de service' : feuilleInfo.publicCible === 'tous' ? 'Tous' : 'Autre'}`, 14, yPos);
    yPos += 8;

    // Date de la journée
    doc.setFontSize(12);
    doc.setFont('helvetica', 'bold');
    doc.text(`Date ${dateInfo.ordre} : ${dateInfo.dateDebut.toLocaleDateString('fr-FR', { 
      weekday: 'long', 
      year: 'numeric', 
      month: 'long', 
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    })}`, 14, yPos);
    doc.setFont('helvetica', 'normal');
    yPos += 10;

    // Tableau de présence avec signatures matin et après-midi
    const tableData = feuilleInfo.apprenants.map(i => {
      // Trouver les présences pour cette date (utiliser l'ID de la date, pas l'ordre)
      const presenceMatin = i.presences?.find(p => p.dateFormationId === dateInfo.id && p.periode === 'matin');
      const presenceApresMidi = i.presences?.find(p => p.dateFormationId === dateInfo.id && p.periode === 'apres_midi');
      
      return [
        i.nom,
        i.prenom,
        i.codeEtablissement || '',
        i.fonction === 'directeur' ? 'Directeur' : i.fonction === 'chef_service' ? 'Chef de service' : 'Autre',
        presenceMatin?.signatureUrl || '', // Signature matin (sera remplacée par l'image)
        presenceApresMidi?.signatureUrl || '', // Signature après-midi (sera remplacée par l'image)
      ];
    });

    autoTable(doc, {
      startY: yPos,
      head: [['Nom', 'Prénom', 'Code étab.', 'Fonction', 'Signature\nMatin', 'Signature\nAprès-midi']],
      body: tableData,
      styles: { 
        fontSize: 9, 
        cellPadding: 3,
        minCellHeight: 15, // Augmenté pour les signatures
      },
      headStyles: { 
        fillColor: [37, 99, 235],
        halign: 'center',
      },
      columnStyles: {
        0: { cellWidth: 30 }, // Nom
        1: { cellWidth: 30 }, // Prénom
        2: { cellWidth: 25 }, // Code établissement
        3: { cellWidth: 30 }, // Fonction
        4: { cellWidth: 35 }, // Signature matin
        5: { cellWidth: 35 }, // Signature après-midi
      },
      didDrawCell: (data) => {
        // Insérer les images de signatures dans les colonnes 4 et 5
        if (data.section === 'body' && (data.column.index === 4 || data.column.index === 5)) {
          const signatureUrl = data.cell.raw as string;
          
          if (signatureUrl && signatureUrl.startsWith('/uploads/signatures/')) {
            try {
              // Construire le chemin absolu vers le fichier de signature
              const signaturePath = path.resolve(process.cwd(), signatureUrl.substring(1)); // Enlever le / du début
              
              // Vérifier si le fichier existe
              if (fs.existsSync(signaturePath)) {
                // Charger l'image
                const signatureBuffer = fs.readFileSync(signaturePath);
                const signatureBase64 = `data:image/png;base64,${signatureBuffer.toString('base64')}`;
                
                // Insérer l'image dans la cellule
                const cellX = data.cell.x + 2;
                const cellY = data.cell.y + 2;
                const cellWidth = data.cell.width - 4;
                const cellHeight = data.cell.height - 4;
                
                doc.addImage(signatureBase64, 'PNG', cellX, cellY, cellWidth, cellHeight);
              }
            } catch (error) {
              console.error('Erreur lors du chargement de la signature:', error);
            }
          }
        }
      },
    });

    // Ajouter deux champs de signature pour le formateur (Matin et Après-midi)
    const finalY = (doc as any).lastAutoTable.finalY || yPos + 50;
    const signatureY = finalY + 20;
    
    doc.setFontSize(10);
    doc.setFont('helvetica', 'bold');
    doc.text('Signatures du formateur :', 14, signatureY);
    doc.setFont('helvetica', 'normal');
    
    // Récupérer les signatures formateurs pour cette date
    const signatureMatin = feuilleInfo.signaturesFormateurs?.find(
      s => s.dateFormationId === dateInfo.id && s.periode === 'matin'
    );
    const signatureApresMidi = feuilleInfo.signaturesFormateurs?.find(
      s => s.dateFormationId === dateInfo.id && s.periode === 'apres_midi'
    );
    
    // Signature Matin
    doc.setFontSize(9);
    doc.text('Matin :', 14, signatureY + 8);
    
    if (signatureMatin?.signatureUrl) {
      try {
        const signaturePath = path.resolve(process.cwd(), signatureMatin.signatureUrl.substring(1));
        if (fs.existsSync(signaturePath)) {
          const signatureBuffer = fs.readFileSync(signaturePath);
          const signatureBase64 = `data:image/png;base64,${signatureBuffer.toString('base64')}`;
          doc.addImage(signatureBase64, 'PNG', 30, signatureY + 2, 60, 15);
        } else {
          doc.line(30, signatureY + 8, 90, signatureY + 8);
        }
      } catch (error) {
        console.error('Erreur lors du chargement de la signature formateur matin:', error);
        doc.line(30, signatureY + 8, 90, signatureY + 8);
      }
    } else {
      doc.line(30, signatureY + 8, 90, signatureY + 8);
    }
    
    // Signature Après-midi
    doc.text('Après-midi :', 110, signatureY + 8);
    
    if (signatureApresMidi?.signatureUrl) {
      try {
        const signaturePath = path.resolve(process.cwd(), signatureApresMidi.signatureUrl.substring(1));
        if (fs.existsSync(signaturePath)) {
          const signatureBuffer = fs.readFileSync(signaturePath);
          const signatureBase64 = `data:image/png;base64,${signatureBuffer.toString('base64')}`;
          doc.addImage(signatureBase64, 'PNG', 140, signatureY + 2, 60, 15);
        } else {
          doc.line(140, signatureY + 8, 200, signatureY + 8);
        }
      } catch (error) {
        console.error('Erreur lors du chargement de la signature formateur après-midi:', error);
        doc.line(140, signatureY + 8, 200, signatureY + 8);
      }
    } else {
      doc.line(140, signatureY + 8, 200, signatureY + 8);
    }
  };

  // Générer une page pour chaque date
  feuilleInfo.dates.forEach((date, index) => {
    generatePageForDate(date, index === 0);
  });

  return Buffer.from(doc.output('arraybuffer'));
}
