// app/api/staff/bulk-email-stream/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createSbServer } from "@/lib/supabaseServer";
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
import { emailLogger, EmailType } from "@/lib/emailLoggingService";

interface Recipient {
  id: string;
  email: string;
  organizations: Array<{
    id: string;
    name: string;
    role: string;
    structure_api: string | null;
  }>;
}

interface BulkEmailRequest {
  subject: string;
  htmlContent: string;
  recipients: Recipient[];
}

export async function POST(request: NextRequest) {
  try {
    const sb = createSbServer();
    
    // Vérifier que l'utilisateur est authentifié et a le rôle staff
    const { data: { user }, error: authError } = await sb.auth.getUser();
    
    if (authError || !user) {
      return NextResponse.json(
        { error: "Non authentifié" },
        { status: 401 }
      );
    }

    // Vérifier les permissions staff
    const { data: staffMember, error: staffError } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();

    if (staffError || !staffMember?.is_staff) {
      return NextResponse.json(
        { error: "Accès refusé - permissions insuffisantes" },
        { status: 403 }
      );
    }

    const body: BulkEmailRequest = await request.json();
    const { subject, htmlContent, recipients } = body;

    // Validation des données
    if (!subject?.trim() || !htmlContent?.trim() || !recipients?.length) {
      return NextResponse.json(
        { error: "Tous les champs sont requis" },
        { status: 400 }
      );
    }

    if (recipients.length > 100) {
      return NextResponse.json(
        { error: "Maximum 100 destinataires par envoi" },
        { status: 400 }
      );
    }

    // Configuration SES
    const region = process.env.AWS_REGION || "eu-west-3";
    const fromEmail = process.env.AWS_SES_FROM;
    
    if (!fromEmail) {
      return NextResponse.json(
        { error: "Configuration SES manquante" },
        { status: 500 }
      );
    }

    // Configuration du streaming response
    const encoder = new TextEncoder();
    
    const stream = new ReadableStream({
      async start(controller) {
        const ses = new SESClient({ region });
        
        // Créer le contenu texte simple à partir du HTML
        const textContent = htmlContent
          .replace(/<[^>]*>/g, '') // Supprimer les balises HTML
          .replace(/\s+/g, ' ') // Normaliser les espaces
          .trim();

        let sentCount = 0;
        const failedEmails: Array<{email: string, error: string}> = [];

        // Fonction pour envoyer un update
        const sendUpdate = (data: any) => {
          const chunk = encoder.encode(`data: ${JSON.stringify(data)}\n\n`);
          controller.enqueue(chunk);
        };

        // Envoyer l'état initial
        sendUpdate({
          type: 'init',
          total: recipients.length,
          completed: 0,
          success: 0,
          errors: 0
        });

        try {
          // Configuration optimisée pour limite SES de 14 emails/seconde
          // Stratégie : 12 emails par lot avec pause de 1 seconde
          // Calcul : 12 emails/sec < 14 emails/sec (marge de sécurité de 2 emails/sec)
          // Performance résultante : ~720 emails/minute
          const batchSize = 12;
          const batchDelayMs = 1000; // 1 seconde entre les lots
          
          for (let i = 0; i < recipients.length; i += batchSize) {
            const batch = recipients.slice(i, i + batchSize);
            
            const promises = batch.map(async (recipient, batchIndex) => {
              const globalIndex = i + batchIndex;
              let logId: string | null = null;
              
              try {
                // Validation de l'adresse email
                if (!recipient.email || !recipient.email.includes('@') || !recipient.email.includes('.')) {
                  throw new Error('Adresse email invalide');
                }
                
                // Notifier le début de l'envoi
                sendUpdate({
                  type: 'progress',
                  recipientId: recipient.id,
                  email: recipient.email,
                  status: 'sending',
                  index: globalIndex
                });

                // Personnaliser le contenu si nécessaire
                let personalizedHtml = htmlContent;
                let personalizedSubject = subject;
                
                // Créer le log d'email AVANT l'envoi
                logId = await emailLogger.logEmail({
                  senderEmail: fromEmail || 'paie@odentas.fr',
                  recipientEmail: recipient.email,
                  subject: personalizedSubject,
                  htmlContent: personalizedHtml,
                  textContent: textContent,
                  emailType: 'bulk_communication' as EmailType,
                  templateName: 'bulk-email-stream',
                  templateData: {
                    recipients_count: recipients.length,
                    batch_index: Math.floor(globalIndex / batchSize),
                    global_index: globalIndex
                  },
                  emailStatus: 'sending',
                  organizationId: recipient.organizations?.[0]?.id,
                  tags: {
                    email_system: 'bulk_stream',
                    batch_size: batchSize.toString(),
                    total_recipients: recipients.length.toString()
                  },
                  context: {
                    recipient_id: recipient.id,
                    recipient_orgs: recipient.organizations?.map(org => org.name).join(', ') || 'No organizations',
                    subject_preview: personalizedSubject.substring(0, 100)
                  }
                });
                
                // Formater l'adresse email source correctement
                // Extraire l'email pur de fromEmail (peut contenir "Nom <email>" ou juste "email")
                let pureEmail = fromEmail;
                if (fromEmail && fromEmail.includes('<') && fromEmail.includes('>')) {
                  // Extraire l'email entre < et >
                  const match = fromEmail.match(/<([^>]+)>/);
                  pureEmail = match ? match[1] : fromEmail;
                } else if (fromEmail && fromEmail.includes('<')) {
                  // Si < présent mais pas >, extraire la partie après <
                  pureEmail = fromEmail.split('<')[1] || fromEmail;
                }
                
                // Construire le format Source correct : "Nom <email@domain.com>"
                const sourceEmail = `Espace Paie Odentas <${pureEmail}>`;
                
                const cmd = new SendEmailCommand({
                  Destination: {
                    ToAddresses: [recipient.email]
                  },
                  Source: sourceEmail,
                  Message: {
                    Subject: { 
                      Data: personalizedSubject, 
                      Charset: "UTF-8" 
                    },
                    Body: {
                      Html: { 
                        Data: personalizedHtml, 
                        Charset: "UTF-8" 
                      },
                      Text: { 
                        Data: textContent, 
                        Charset: "UTF-8" 
                      }
                    }
                  }
                });
                
                const response = await ses.send(cmd);
                const messageId = (response as any)?.MessageId || '';
                sentCount++;
                
                // Mettre à jour le log avec le succès
                if (logId) {
                  await emailLogger.updateEmailLog(logId, {
                    emailStatus: 'sent',
                    sesMessageId: messageId,
                    sentAt: new Date()
                  });
                }
                
                // Notifier le succès
                sendUpdate({
                  type: 'progress',
                  recipientId: recipient.id,
                  email: recipient.email,
                  status: 'success',
                  index: globalIndex,
                  sentAt: new Date().toISOString(),
                  messageId: messageId
                });
                
                console.log(`Email envoyé avec succès à ${recipient.email} - MessageId: ${messageId}`);
              } catch (error: any) {
                let errorMessage = 'Erreur SES inconnue';
                
                // Améliorer les messages d'erreur
                if (error.message) {
                  if (error.message.includes('Missing')) {
                    errorMessage = 'Format email source invalide';
                  } else if (error.message.includes('InvalidParameterValue')) {
                    errorMessage = 'Adresse email invalide';
                  } else if (error.message.includes('MessageRejected')) {
                    errorMessage = 'Email rejeté par SES';
                  } else if (error.message.includes('Daily sending quota exceeded')) {
                    errorMessage = 'Quota journalier dépassé';
                  } else if (error.message.includes('Sending rate exceeded')) {
                    errorMessage = 'Limite de débit dépassée';
                  } else {
                    errorMessage = error.message;
                  }
                }
                
                // Mettre à jour le log avec l'erreur
                if (logId) {
                  await emailLogger.updateEmailLog(logId, {
                    emailStatus: 'failed',
                    failureReason: errorMessage
                  });
                }
                
                failedEmails.push({ email: recipient.email, error: errorMessage });
                
                // Notifier l'erreur
                sendUpdate({
                  type: 'progress',
                  recipientId: recipient.id,
                  email: recipient.email,
                  status: 'error',
                  index: globalIndex,
                  error: errorMessage
                });
                
                console.error(`Erreur envoi email à ${recipient.email}:`, error);
              }
            });
            
            await Promise.all(promises);
            
            // Envoyer une mise à jour globale
            sendUpdate({
              type: 'batch_complete',
              completed: Math.min(i + batchSize, recipients.length),
              success: sentCount,
              errors: failedEmails.length,
              total: recipients.length
            });
            
            // Pause entre les lots pour respecter les limites SES (14 emails/seconde max)
            if (i + batchSize < recipients.length) {
              await new Promise(resolve => setTimeout(resolve, batchDelayMs));
            }
          }

          // Log de l'activité pour traçabilité
          try {
            await sb
              .from("email_logs")
              .insert({
                user_id: user.id,
                type: "bulk_email_stream",
                subject: subject,
                recipients_count: recipients.length,
                sent_count: sentCount,
                failed_count: failedEmails.length,
                failed_emails: failedEmails.length > 0 ? failedEmails : null,
                created_at: new Date().toISOString()
              });
          } catch (logError) {
            console.error("Erreur lors de l'enregistrement du log:", logError);
          }

          // Envoyer le résultat final
          sendUpdate({
            type: 'complete',
            total: recipients.length,
            success: sentCount,
            errors: failedEmails.length,
            failedEmails: failedEmails,
            message: `${sentCount} email(s) envoyé(s) avec succès${failedEmails.length > 0 ? `, ${failedEmails.length} échec(s)` : ''}`
          });

        } catch (error) {
          console.error("Erreur dans le streaming d'emails:", error);
          sendUpdate({
            type: 'error',
            error: 'Erreur interne du serveur'
          });
        } finally {
          controller.close();
        }
      }
    });

    return new Response(stream, {
      headers: {
        'Content-Type': 'text/plain; charset=utf-8',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
      },
    });

  } catch (error) {
    console.error("Erreur dans l'API bulk-email-stream:", error);
    return NextResponse.json(
      { error: "Erreur interne du serveur" },
      { status: 500 }
    );
  }
}