/**
 * Lambda déclenchée par S3 ObjectCreated
 * Convertit automatiquement les PDF en images JPEG avec pdfjs-dist + canvas
 * et les stocke dans S3 pour les pages de signature
 */

const { S3Client, GetObjectCommand, PutObjectCommand } = require('@aws-sdk/client-s3');
const { getDocument } = require('pdfjs-dist/legacy/build/pdf.js');
const { createCanvas } = require('canvas');
const sharp = require('sharp');

// Client S3
const s3Client = new S3Client({ region: process.env.AWS_REGION || 'eu-west-3' });

const SOURCE_BUCKET = process.env.SOURCE_BUCKET || 'odentas-sign';
const DEST_BUCKET = process.env.DEST_BUCKET || 'odentas-docs';

/**
 * Convertit une page PDF en image JPEG avec Sharp
 */
async function convertPdfPageToJpeg(pdfPage, scale = 2.0) {
  const viewport = pdfPage.getViewport({ scale });
  const canvas = createCanvas(viewport.width, viewport.height);
  const context = canvas.getContext('2d');

  await pdfPage.render({
    canvasContext: context,
    viewport: viewport,
  }).promise;

  // Convertir le canvas en buffer puis optimiser avec Sharp
  const rawImageBuffer = canvas.toBuffer('raw');
  
  return await sharp(rawImageBuffer, {
    raw: {
      width: Math.floor(viewport.width),
      height: Math.floor(viewport.height),
      channels: 4, // RGBA
    },
  })
    .jpeg({
      quality: 90,
      progressive: true,
    })
    .resize(1400, null, { // Max 1400px de largeur
      withoutEnlargement: true,
      fit: 'inside',
    })
    .toBuffer();
}

/**
 * Handler principal
 */
exports.handler = async (event) => {
  console.log('[Lambda] Event reçu:', JSON.stringify(event, null, 2));

  try {
    // Récupérer les informations du fichier uploadé
    const record = event.Records[0];
    const bucket = record.s3.bucket.name;
    const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));

    console.log(`[Lambda] Fichier détecté: s3://${bucket}/${key}`);

    // Extraire le requestId depuis la clé S3
    // Format attendu: source/{folder}/{requestId}-{timestamp}.pdf
    const keyParts = key.split('/');
    const filename = keyParts[keyParts.length - 1];
    const requestId = filename.split('-')[0]; // Prend la partie avant le premier tiret

    if (!requestId) {
      throw new Error(`Impossible d'extraire requestId depuis la clé: ${key}`);
    }

    console.log(`[Lambda] Request ID extrait: ${requestId}`);

    // 1. Télécharger le PDF depuis S3
    console.log('[Lambda] Téléchargement du PDF depuis S3...');
    const getObjectCommand = new GetObjectCommand({
      Bucket: bucket,
      Key: key,
    });
    const s3Response = await s3Client.send(getObjectCommand);
    const pdfBuffer = Buffer.from(await s3Response.Body.transformToByteArray());
    console.log(`[Lambda] PDF téléchargé: ${pdfBuffer.length} bytes`);

    // 2. Upload sur Cloudinary pour conversion (upload en tant que PDF, pas en JPG)
    console.log('[Lambda] Upload sur Cloudinary pour conversion...');
    const uploadResult = await new Promise((resolve, reject) => {
      const uploadStream = cloudinary.uploader.upload_stream(
        {
          folder: `odentas-sign-temp/${requestId}`,
          resource_type: 'raw',  // 'raw' pour préserver le PDF tel quel
          public_id: `pdf-${requestId}`,
          transformation: [
            { width: 1400, crop: 'scale' },
            { quality: 90 },
          ],
        },
        (error, result) => {
          if (error) reject(error);
          else resolve(result);
        }
      );

      bufferToStream(pdfBuffer).pipe(uploadStream);
    });

    console.log('[Lambda] Upload Cloudinary réussi:', uploadResult.secure_url);
    console.log('[Lambda] Pages détectées par Cloudinary:', uploadResult.pages);

    const baseUrl = uploadResult.secure_url;
    
    // Cloudinary ne retourne pas toujours le nombre de pages correctement
    // On va tester chaque page jusqu'à ce qu'on obtienne une erreur 404
    const pages = [];
    let pageNum = 1;
    const maxPages = 100; // Sécurité pour éviter une boucle infinie

    console.log('[Lambda] Détection du nombre de pages...');

    // 3. Pour chaque page, télécharger depuis Cloudinary et stocker sur S3
    while (pageNum <= maxPages) {
      // Pour un PDF uploadé en 'raw', on doit forcer le format JPG avec .jpg
      const public_id_with_folder = `${uploadResult.folder}/${uploadResult.public_id}`;
      const cloudinaryPageUrl = `https://res.cloudinary.com/${process.env.CLOUDINARY_CLOUD_NAME}/image/upload/pg_${pageNum}/w_1400,q_90/${public_id_with_folder}.jpg`;

      console.log(`[Lambda] Test page ${pageNum}: Téléchargement depuis Cloudinary...`);

      // Télécharger l'image
      const imageResponse = await fetch(cloudinaryPageUrl);
      
      // Si 4xx, on a atteint la fin du PDF (404 ou 400 selon Cloudinary)
      if (imageResponse.status >= 400 && imageResponse.status < 500) {
        console.log(`[Lambda] Page ${pageNum} non trouvée (${imageResponse.status}), fin du PDF`);
        break;
      }
      
      if (!imageResponse.ok) {
        throw new Error(`Erreur téléchargement page ${pageNum}: ${imageResponse.statusText}`);
      }

      const imageBuffer = Buffer.from(await imageResponse.arrayBuffer());

      // Stocker sur S3
      const s3Key = `odentas-sign-images/${requestId}/page-${pageNum}.jpg`;
      await s3Client.send(
        new PutObjectCommand({
          Bucket: DEST_BUCKET,
          Key: s3Key,
          Body: imageBuffer,
          ContentType: 'image/jpeg',
          CacheControl: 'public, max-age=31536000',
          Metadata: {
            'source-pdf': key,
            'request-id': requestId,
            'page-number': pageNum.toString(),
            'converted-at': new Date().toISOString(),
          },
        })
      );

      pages.push(s3Key);
      console.log(`[Lambda] Page ${pageNum} stockée sur S3 → ${s3Key}`);
      
      pageNum++;
    }

    const totalPages = pages.length;

    // 4. Nettoyer Cloudinary
    console.log('[Lambda] Nettoyage Cloudinary...');
    try {
      await cloudinary.uploader.destroy(`odentas-sign-temp/${requestId}/pdf-${requestId}`);
      console.log('[Lambda] Nettoyage Cloudinary terminé');
    } catch (cleanupError) {
      console.warn('[Lambda] Erreur nettoyage Cloudinary (non bloquant):', cleanupError);
    }

    console.log(`[Lambda] ✅ Conversion terminée: ${totalPages} page(s) pour ${requestId}`);

    return {
      statusCode: 200,
      body: JSON.stringify({
        success: true,
        requestId,
        totalPages,
        message: 'PDF converti avec succès',
      }),
    };
  } catch (error) {
    console.error('[Lambda] ❌ Erreur:', error);
    
    return {
      statusCode: 500,
      body: JSON.stringify({
        success: false,
        error: error.message,
      }),
    };
  }
};
