import { NextRequest, NextResponse } from 'next/server';
import { supabaseAdmin, logSignEvent } from '@/lib/odentas-sign/supabase';
import { generateOTP, hashOTP, getOTPExpiration } from '@/lib/odentas-sign/crypto';

/**
 * POST /api/odentas-sign/signers/[id]/send-otp
 * 
 * Génère et envoie un code OTP par email à un signataire
 */
export async function POST(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const signerId = params.id;
    
    // Récupérer le signataire
    const { data: signer, error: signerError } = await supabaseAdmin
      .from('signers')
      .select('*, sign_requests(id, ref, title, status)')
      .eq('id', signerId)
      .single();
    
    if (signerError || !signer) {
      return NextResponse.json(
        { error: 'Signataire introuvable' },
        { status: 404 }
      );
    }
    
    // Vérifier que la demande n'est pas annulée ou complétée
    if (signer.sign_requests.status === 'cancelled') {
      return NextResponse.json(
        { error: 'Cette demande de signature a été annulée' },
        { status: 400 }
      );
    }
    
    if (signer.sign_requests.status === 'completed') {
      return NextResponse.json(
        { error: 'Cette demande de signature est déjà complétée' },
        { status: 400 }
      );
    }
    
    // Vérifier si le signataire a déjà signé
    if (signer.signed_at) {
      return NextResponse.json(
        { error: 'Vous avez déjà signé ce document' },
        { status: 400 }
      );
    }
    
    // Limite de fréquence : ne pas renvoyer d'OTP si un a été envoyé il y a moins de 60 secondes
    if (signer.otp_last_sent_at) {
      const lastSentAt = new Date(signer.otp_last_sent_at);
      const now = new Date();
      const diffSeconds = (now.getTime() - lastSentAt.getTime()) / 1000;
      
      if (diffSeconds < 60) {
        return NextResponse.json(
          { error: `Veuillez attendre ${Math.ceil(60 - diffSeconds)} secondes avant de redemander un code` },
          { status: 429 }
        );
      }
    }
    
    // Générer le code OTP
    const otpCode = generateOTP();
    const otpHash = await hashOTP(otpCode);
    const otpExpires = getOTPExpiration();
    
    // Détecter le mode test
    const testEmails = ['paie@odentas.fr', 'renaud.breviere@gmail.com'];
    const isTestMode = signer.email.includes('test@') || 
                       signer.email.includes('@example.com') || 
                       signer.sign_requests.ref?.startsWith('TEST-') ||
                       testEmails.includes(signer.email.toLowerCase());
    
    if (isTestMode) {
      console.log(`[OTP] 🧪 MODE TEST détecté`);
      console.log(`[OTP] ========================================`);
      console.log(`[OTP] 🔐 CODE OTP POUR ${signer.email}:`);
      console.log(`[OTP] ➡️  ${otpCode}`);
      console.log(`[OTP] ========================================`);
      console.log(`[OTP] Expire à: ${otpExpires.toISOString()}`);
    } else {
      console.log(`[OTP] Code généré pour ${signer.email} (expire à ${otpExpires.toISOString()})`);
    }
    
    // Mettre à jour le signataire avec le nouveau OTP
    const { error: updateError } = await supabaseAdmin
      .from('signers')
      .update({
        otp_hash: otpHash,
        otp_expires_at: otpExpires.toISOString(),
        otp_last_sent_at: new Date().toISOString(),
      })
      .eq('id', signerId);
    
    if (updateError) {
      console.error('[OTP] Erreur mise à jour signataire:', updateError);
      return NextResponse.json(
        { error: 'Erreur lors de la génération du code' },
        { status: 500 }
      );
    }
    
    // Logger l'événement
    await logSignEvent({
      requestId: signer.sign_requests.id,
      signerId: signer.id,
      event: 'otp_sent',
      ip: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined,
      userAgent: request.headers.get('user-agent') || undefined,
      metadata: {
        email: signer.email,
        expires_at: otpExpires.toISOString(),
      },
    });
    
    // Envoyer l'email avec le code OTP
    // TODO: Intégrer avec le système d'email existant (SES)
    const emailResult = await sendOTPEmail({
      to: signer.email,
      name: signer.name,
      otpCode,
      documentTitle: signer.sign_requests.title,
      documentRef: signer.sign_requests.ref,
      isTestMode,
    });
    
    if (!emailResult.success) {
      console.error('[OTP] Erreur envoi email:', emailResult.error);
      
      // En mode test, on continue quand même
      if (!isTestMode) {
        return NextResponse.json(
          { error: 'Erreur lors de l\'envoi de l\'email' },
          { status: 500 }
        );
      }
    }
    
    console.log(`[OTP] ✅ ${isTestMode ? 'Mode test - Code affiché dans les logs' : `Code envoyé à ${signer.email}`}`);
    
    return NextResponse.json({
      success: true,
      message: isTestMode 
        ? 'Mode test : le code OTP est affiché dans les logs serveur' 
        : 'Code de vérification envoyé par email',
      test_mode: isTestMode,
      ...(isTestMode && { otp_code_in_logs: true }),
      expires_at: otpExpires.toISOString(),
      signer: {
        name: signer.name,
        email: signer.email,
      },
    });
    
  } catch (error) {
    console.error('[SEND OTP] Erreur:', error);
    return NextResponse.json(
      { error: 'Erreur serveur', details: error instanceof Error ? error.message : String(error) },
      { status: 500 }
    );
  }
}

/**
 * Envoie un email avec le code OTP
 */
async function sendOTPEmail(params: {
  to: string;
  name: string;
  otpCode: string;
  documentTitle: string;
  documentRef: string;
  isTestMode?: boolean;
}): Promise<{ success: boolean; error?: string }> {
  const { to, name, otpCode, documentTitle, documentRef, isTestMode } = params;
  
  // En mode test, ne pas envoyer d'email réellement
  if (isTestMode) {
    console.log(`[EMAIL] 🧪 MODE TEST : Email non envoyé (code affiché dans les logs)`);
    return { success: true };
  }
  
  try {
    // Appeler l'API d'envoi d'email existante
    const response = await fetch(`${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/api/send-email`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        to,
        subject: `Code de vérification - Signature électronique`,
        template: 'otp-signature',
        variables: {
          name,
          otpCode,
          documentTitle,
          documentRef,
          expirationMinutes: '15',
        },
      }),
    });
    
    if (!response.ok) {
      const errorData = await response.json().catch(() => ({}));
      return { success: false, error: errorData.error || 'Erreur HTTP' };
    }
    
    return { success: true };
  } catch (error) {
    console.error('[EMAIL] Erreur:', error);
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
}
