import { NextRequest, NextResponse } from 'next/server';
import { supabaseAdmin, logSignEvent } from '@/lib/odentas-sign/supabase';
import { verifyOTP, isOTPExpired } from '@/lib/odentas-sign/crypto';
import { createSignatureSession } from '@/lib/odentas-sign/jwt';

const MAX_OTP_ATTEMPTS = 3;

/**
 * POST /api/odentas-sign/signers/[id]/verify-otp
 * 
 * Vérifie le code OTP et crée une session de signature
 */
export async function POST(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const signerId = params.id;
    const body = await request.json();
    const { otp } = body;
    
    if (!otp || !/^\d{6}$/.test(otp)) {
      return NextResponse.json(
        { error: 'Code OTP invalide (6 chiffres requis)' },
        { status: 400 }
      );
    }
    
    // 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 est active
    if (signer.sign_requests.status !== 'pending' && signer.sign_requests.status !== 'in_progress') {
      return NextResponse.json(
        { error: 'Cette demande de signature n\'est plus active' },
        { status: 400 }
      );
    }
    
    // Vérifier si déjà signé
    if (signer.signed_at) {
      return NextResponse.json(
        { error: 'Vous avez déjà signé ce document' },
        { status: 400 }
      );
    }
    
    // Vérifier si un OTP existe
    if (!signer.otp_hash) {
      return NextResponse.json(
        { error: 'Aucun code OTP n\'a été généré. Veuillez en demander un.' },
        { status: 400 }
      );
    }
    
    // Vérifier si l'OTP est expiré
    if (isOTPExpired(signer.otp_expires_at)) {
      return NextResponse.json(
        { error: 'Le code OTP a expiré. Veuillez en demander un nouveau.' },
        { status: 400 }
      );
    }
    
    // Vérifier le nombre de tentatives
    if (signer.otp_attempts >= MAX_OTP_ATTEMPTS) {
      await logSignEvent({
        requestId: signer.sign_requests.id,
        signerId: signer.id,
        event: 'otp_max_attempts_exceeded',
        ip: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined,
        userAgent: request.headers.get('user-agent') || undefined,
      });
      
      return NextResponse.json(
        { error: 'Nombre maximum de tentatives atteint. Veuillez demander un nouveau code.' },
        { status: 429 }
      );
    }
    
    // Vérifier le code OTP
    const isValid = await verifyOTP(otp, signer.otp_hash);
    
    if (!isValid) {
      // Incrémenter le compteur de tentatives
      const newAttempts = signer.otp_attempts + 1;
      
      await supabaseAdmin
        .from('signers')
        .update({ otp_attempts: newAttempts })
        .eq('id', signerId);
      
      await logSignEvent({
        requestId: signer.sign_requests.id,
        signerId: signer.id,
        event: 'otp_verification_failed',
        ip: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined,
        userAgent: request.headers.get('user-agent') || undefined,
        metadata: {
          attempt: newAttempts,
          max_attempts: MAX_OTP_ATTEMPTS,
        },
      });
      
      const remainingAttempts = MAX_OTP_ATTEMPTS - newAttempts;
      
      return NextResponse.json(
        { 
          error: `Code incorrect. ${remainingAttempts} tentative${remainingAttempts > 1 ? 's' : ''} restante${remainingAttempts > 1 ? 's' : ''}.`,
          remainingAttempts,
        },
        { status: 401 }
      );
    }
    
    // ✅ Code OTP valide !
    console.log(`[OTP] ✅ Code vérifié pour ${signer.email}`);
    
    // Réinitialiser les tentatives
    await supabaseAdmin
      .from('signers')
      .update({ 
        otp_attempts: 0,
      })
      .eq('id', signerId);
    
    // Logger l'événement
    await logSignEvent({
      requestId: signer.sign_requests.id,
      signerId: signer.id,
      event: 'otp_verified',
      ip: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined,
      userAgent: request.headers.get('user-agent') || undefined,
    });
    
    // Mettre à jour le statut de la demande à "in_progress" si c'est la première vérification
    if (signer.sign_requests.status === 'pending') {
      await supabaseAdmin
        .from('sign_requests')
        .update({ status: 'in_progress' })
        .eq('id', signer.sign_requests.id);
    }
    
    // Créer un JWT de session (valide 30 minutes)
    const sessionToken = createSignatureSession({
      signerId: signer.id,
      requestId: signer.sign_requests.id,
      email: signer.email,
      role: signer.role,
    });
    
    return NextResponse.json({
      success: true,
      message: 'Code vérifié avec succès',
      sessionToken,
      signer: {
        id: signer.id,
        name: signer.name,
        email: signer.email,
        role: signer.role,
      },
      request: {
        id: signer.sign_requests.id,
        ref: signer.sign_requests.ref,
        title: signer.sign_requests.title,
      },
    });
    
  } catch (error) {
    console.error('[VERIFY OTP] Erreur:', error);
    return NextResponse.json(
      { error: 'Erreur serveur', details: error instanceof Error ? error.message : String(error) },
      { status: 500 }
    );
  }
}
