// app/api/staff/cotisations/[id]/notify-client/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { sendUniversalEmailV2 } from "@/lib/emailTemplateService";

export const dynamic = "force-dynamic";
export const revalidate = 0;
export const runtime = "nodejs";

/**
 * POST /api/staff/cotisations/[id]/notify-client
 * Envoie une notification d'échéance de cotisations au client
 * L'ID correspond à une cotisation spécifique, mais on notifie pour toute la période
 */
export async function POST(
  request: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const supabase = createRouteHandlerClient({ cookies });

    // 1) Authentification
    const {
      data: { session },
      error: sessionError,
    } = await supabase.auth.getSession();
    
    if (sessionError || !session) {
      return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
    }
    
    const user = session.user;

    // 2) Vérifier que l'utilisateur est staff
    const { data: staffData } = await supabase
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();
      
    const isStaff = staffData?.is_staff || false;
    
    if (!isStaff) {
      return NextResponse.json(
        { error: "Accès refusé : réservé au staff" },
        { status: 403 }
      );
    }

    // 3) Récupérer la cotisation (pour obtenir org_id et period_label)
    const { data: cotisation, error: cotisError } = await supabase
      .from("monthly_contributions")
      .select("*")
      .eq("id", params.id)
      .single();

    if (cotisError || !cotisation) {
      return NextResponse.json(
        { error: "Cotisation introuvable" },
        { status: 404 }
      );
    }

    // 4) Récupérer l'organisation et ses détails
    const { data: organization, error: orgError } = await supabase
      .from("organizations")
      .select("*")
      .eq("id", cotisation.org_id)
      .single();

    if (orgError || !organization) {
      return NextResponse.json(
        { error: "Organisation introuvable" },
        { status: 404 }
      );
    }

    const { data: orgDetails, error: orgDetailsError } = await supabase
      .from("organization_details")
      .select("*")
      .eq("org_id", cotisation.org_id)
      .single();

    if (orgDetailsError || !orgDetails) {
      return NextResponse.json(
        { error: "Détails de l'organisation introuvables" },
        { status: 404 }
      );
    }

    // 5) Vérifier et nettoyer les emails de notification
    const cleanEmail = (email: string | null | undefined): string | undefined => {
      if (!email) return undefined;
      // Supprimer tous les espaces, retours à la ligne, tabulations, etc.
      const cleaned = email.replace(/\s+/g, '').trim();
      if (cleaned.length === 0) return undefined;
      return cleaned;
    };

    const isValidEmail = (email: string | null | undefined): boolean => {
      if (!email) return false;
      const cleaned = cleanEmail(email);
      if (!cleaned) return false;
      // Vérifier le format basique d'un email
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return emailRegex.test(cleaned);
    };

    const emailNotifs = cleanEmail(orgDetails.email_notifs);
    const emailNotifsCC = cleanEmail(orgDetails.email_notifs_cc);

    console.log("[notify-contribution] Email brut:", JSON.stringify(orgDetails.email_notifs));
    console.log("[notify-contribution] Email nettoyé:", emailNotifs);
    console.log("[notify-contribution] CC brut:", JSON.stringify(orgDetails.email_notifs_cc));
    console.log("[notify-contribution] CC nettoyé:", emailNotifsCC);

    if (!emailNotifs || !isValidEmail(emailNotifs)) {
      return NextResponse.json(
        { error: "Email de notification non configuré ou invalide pour cette organisation" },
        { status: 400 }
      );
    }

    // Valider l'email CC s'il existe
    const validatedCcEmail = (emailNotifsCC && isValidEmail(emailNotifsCC)) ? emailNotifsCC : undefined;

    // 6) Récupérer le prénom du contact depuis organization_details
    const firstName = orgDetails.prenom_contact || "Cher client";

    // 7) Extraire le mois de la période pour calculer les dates de prélèvement
    // Format attendu : "Août 2025 Int." ou "Août 2025"
    const periodLabel = cotisation.period_label || "";
    
    // Fonction pour calculer la période de prélèvement
    const calculateCollectionPeriod = (period: string): string => {
      try {
        // Extraire le mois et l'année (ex: "Août 2025" ou "Août 2025 Int.")
        // Utiliser [^\s]+ pour capturer les mois avec accents (Août, Février, Décembre)
        const match = period.match(/^([^\s]+)\s+(\d{4})/);
        if (!match) {
          return "Entre le 15 et le 30 du mois suivant la période";
        }

        const monthName = match[1];
        const year = parseInt(match[2]);
        
        // Mapping des mois français vers numéros
        const monthsMap: { [key: string]: number } = {
          'Janvier': 0, 'Février': 1, 'Mars': 2, 'Avril': 3,
          'Mai': 4, 'Juin': 5, 'Juillet': 6, 'Août': 7,
          'Septembre': 8, 'Octobre': 9, 'Novembre': 10, 'Décembre': 11
        };

        const monthIndex = monthsMap[monthName];
        if (monthIndex === undefined) {
          return "Entre le 15 et le 30 du mois suivant la période";
        }

        // Calculer le mois suivant
        const date = new Date(year, monthIndex, 1);
        date.setMonth(date.getMonth() + 1);
        
        const nextMonth = date.toLocaleDateString('fr-FR', { month: 'long' });
        const nextYear = date.getFullYear();
        
        // En français, les mois sont en minuscules dans une phrase
        return `Entre le 15 et le 30 ${nextMonth} ${nextYear}`;
      } catch (error) {
        console.error("[notify-contribution] Erreur lors du calcul de la période:", error);
        return "Entre le 15 et le 30 du mois suivant la période";
      }
    };

    const collectionPeriod = calculateCollectionPeriod(periodLabel);

    // 8) Récupérer le code employeur
    const codeEmployeur = orgDetails.code_employeur || "N/A";

    // 9) Récupérer toutes les cotisations de la période pour calculer le total
    const { data: allContributions, error: contributionsError } = await supabase
      .from("monthly_contributions")
      .select("amount_due")
      .eq("org_id", cotisation.org_id)
      .eq("period_label", periodLabel);

    if (contributionsError) {
      console.error("[notify-contribution] Erreur lors de la récupération des cotisations:", contributionsError);
    }

    // Calculer le total des cotisations pour la période
    const totalContributions = (allContributions || []).reduce((sum, contrib) => sum + (contrib.amount_due || 0), 0);
    const hasZeroContributions = totalContributions === 0;

    console.log("[notify-contribution] Total des cotisations:", totalContributions);
    console.log("[notify-contribution] hasZeroContributions:", hasZeroContributions);

    // 10) Préparer les données pour l'email
    const emailData = {
      firstName,
      organizationName: organization.name,
      employerCode: codeEmployeur,
      handlerName: "Renaud BREVIERE-ABRAHAM",
      periodLabel: periodLabel,
      collectionPeriod: collectionPeriod,
      hasZeroContributions: hasZeroContributions,
    };

    // 11) Envoyer l'email via le système universel V2
    console.log("[notify-contribution] Envoi de l'email à:", emailNotifs);
    console.log("[notify-contribution] CC:", validatedCcEmail || "Aucun");
    
    await sendUniversalEmailV2({
      type: 'contribution-notification',
      toEmail: emailNotifs!,
      ccEmail: validatedCcEmail,
      data: emailData,
    });

    console.log("[notify-contribution] Email de notification de cotisations envoyé avec succès");

    // 12) Enregistrer la notification dans la table contribution_notifications
    console.log("[notify-contribution] Tentative d'insertion dans contribution_notifications:", {
      org_id: cotisation.org_id,
      period_label: periodLabel,
      notified_by: user.id,
      email_sent_to: emailNotifs,
      email_cc: validatedCcEmail || null,
    });

    const { data: insertedData, error: notificationError } = await supabase
      .from("contribution_notifications")
      .insert({
        org_id: cotisation.org_id,
        period_label: periodLabel,
        notified_by: user.id,
        email_sent_to: emailNotifs,
        email_cc: validatedCcEmail || null,
      })
      .select();

    if (notificationError) {
      console.error("[notify-contribution] ❌ ERREUR lors de l'enregistrement de la notification:", notificationError);
      console.error("[notify-contribution] Détails erreur:", JSON.stringify(notificationError, null, 2));
      // Ne pas faire échouer la requête si l'email a été envoyé
      // mais logger l'erreur
    } else {
      console.log("[notify-contribution] ✅ Notification enregistrée dans la base de données:", insertedData);
    }

    return NextResponse.json({
      success: true,
      message: "Notification envoyée avec succès",
      sentTo: emailNotifs,
      sentCC: validatedCcEmail || null,
    });

  } catch (error: any) {
    console.error("[notify-contribution] Erreur:", error);
    return NextResponse.json(
      { error: "Erreur lors de l'envoi de la notification", details: error?.message },
      { status: 500 }
    );
  }
}
