// app/api/staff/amendments/generate-pdf/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createSbServer } from "@/lib/supabaseServer";
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

// Fonction de formatage d'une date en "DD/MM/YYYY"
function formatDate(dateStr: string | null | undefined): string {
  if (!dateStr) return "";
  const date = new Date(dateStr);
  if (isNaN(date.getTime())) return dateStr;
  const dd = String(date.getDate()).padStart(2, '0');
  const mm = String(date.getMonth() + 1).padStart(2, '0');
  const yyyy = date.getFullYear();
  return `${dd}/${mm}/${yyyy}`;
}

// Fonction de polling pour vérifier le statut du document PDFMonkey
async function pollDocumentStatus(documentId: string, pdfMonkeyUrl: string, pdfMonkeyApiKey: string) {
  const url = `${pdfMonkeyUrl}/${documentId}`;
  let attempts = 0;
  const maxAttempts = 10;
  let status = "pending";
  
  while (status !== "success" && attempts < maxAttempts) {
    console.log(`Polling PDFMonkey (tentative ${attempts + 1}/${maxAttempts})...`);
    
    const response = await fetch(url, {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${pdfMonkeyApiKey}`
      }
    });
    
    if (!response.ok) {
      throw new Error(`Erreur PDFMonkey: ${response.status} ${response.statusText}`);
    }
    
    const data = await response.json();
    status = data.document.status;
    console.log("Statut du document:", status);
    
    if (status === "success") {
      return data.document;
    }
    
    if (status === "failure") {
      throw new Error("PDFMonkey document generation failed");
    }
    
    await new Promise(resolve => setTimeout(resolve, 3000));
    attempts++;
  }
  
  throw new Error("PDFMonkey polling timed out");
}

// Slugifier un texte
function slugify(text: string): string {
  return text
    .toLowerCase()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

export async function POST(request: NextRequest) {
  try {
    const sb = createSbServer();
    
    // Vérification de l'authentification et du staff
    const { data: { user }, error: authError } = await sb.auth.getUser();
    if (authError || !user) {
      return NextResponse.json(
        { error: "Authentification requise" },
        { status: 401 }
      );
    }

    const { data: staffUser } = await sb
      .from("staff_users")
      .select("is_staff")
      .eq("user_id", user.id)
      .maybeSingle();

    if (!staffUser?.is_staff) {
      return NextResponse.json(
        { error: "Accès refusé - réservé au staff" },
        { status: 403 }
      );
    }

    // Variables d'environnement
    const pdfMonkeyUrl = process.env.PDFMONKEY_URL;
    const pdfMonkeyApiKey = process.env.PDFMONKEY_API_KEY;
    
    if (!pdfMonkeyUrl || !pdfMonkeyApiKey) {
      return NextResponse.json(
        { error: "Configuration PDFMonkey manquante" },
        { status: 500 }
      );
    }

    // Configuration S3
    const s3Client = new S3Client({
      region: process.env.AWS_REGION || "eu-west-3",
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
      },
    });

    // Récupération des données du body
    const body = await request.json();
    const { contractId, amendmentData } = body;

    if (!contractId || !amendmentData) {
      return NextResponse.json(
        { error: "Données manquantes" },
        { status: 400 }
      );
    }

    // Récupération du contrat
    const { data: contract, error: contractError } = await sb
      .from("cddu_contracts")
      .select("*")
      .eq("id", contractId)
      .single();

    if (contractError || !contract) {
      return NextResponse.json(
        { error: "Contrat non trouvé" },
        { status: 404 }
      );
    }

    console.log("📋 [generate-pdf] Contrat récupéré - date_signature:", contract.date_signature);
    console.log("📋 [generate-pdf] Champs date du contrat:", {
      date_signature: contract.date_signature,
      date_signature_contrat: contract.date_signature_contrat,
      date_signature_contrat_employeur: contract.date_signature_contrat_employeur,
      date_signature_contrat_salarie: contract.date_signature_contrat_salarie
    });

    // Récupération des données de l'organisation
    const { data: orgDetails, error: orgError } = await sb
      .from("organization_details")
      .select("*")
      .eq("org_id", contract.org_id)
      .single();

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

    // Récupération du nom de la structure
    const { data: organization } = await sb
      .from("organizations")
      .select("name")
      .eq("id", contract.org_id)
      .single();

    // Récupération des données du salarié
    const { data: salarie, error: salarieError } = await sb
      .from("salaries")
      .select("*")
      .eq("id", contract.employee_id)
      .single();

    if (salarieError || !salarie) {
      return NextResponse.json(
        { error: "Salarié non trouvé" },
        { status: 404 }
      );
    }

    // Déterminer les éléments avenantés
    const elementsAvenantes = amendmentData.elements || [];
    const typeAvenant = amendmentData.type_avenant || "modification";
    
    console.log("🔍 [generate-pdf] Type d'avenant reçu:", typeAvenant);
    console.log("🔍 [generate-pdf] amendmentData:", JSON.stringify(amendmentData, null, 2));
    
    let elementsText = "";
    if (elementsAvenantes.includes("objet")) elementsText += "Objet,";
    if (elementsAvenantes.includes("duree")) elementsText += "Durée de l'engagement,";
    if (elementsAvenantes.includes("lieu_horaire")) elementsText += "Lieu et horaires,";
    if (elementsAvenantes.includes("remuneration")) elementsText += "Rémunération,";
    elementsText = elementsText.replace(/,$/, ""); // Retirer la virgule finale
    
    // Si c'est une annulation, on n'affiche pas d'éléments spécifiques
    if (typeAvenant === "annulation") {
      elementsText = "Annulation du contrat";
    }

    // Préparer les données pour le PDF (valeurs du contrat ou de l'avenant)
    const professionData = amendmentData.objet_data || {};
    const dureeData = amendmentData.duree_data || {};
    const remunerationData = amendmentData.remuneration_data || {};

    // Déterminer la catégorie professionnelle
    const profession = professionData.profession_label || contract.profession || "";
    let employee_catpro = contract.categorie_pro || "Artiste";
    if (profession === "Metteur en scène") {
      employee_catpro = "Metteur en scène";
    }

    // Préparer les détails de cachets - convertir en nombres
    const cachetsRepresentations = parseInt(dureeData.nb_representations || contract.cachets_representations || 0);
    const cachetsRepetitions = parseInt(dureeData.nb_repetitions || contract.cachets_repetitions || 0);
    const heures = parseFloat(dureeData.nb_heures || contract.nb_heures || 0);
    const heuresParJour = parseFloat(contract.nombre_d_heures_par_jour || 0);

    let detailsCachets = "";
    if (cachetsRepresentations > 0) {
      detailsCachets += `${cachetsRepresentations} cachet${cachetsRepresentations > 1 ? 's' : ''} de représentation`;
    }
    if (cachetsRepetitions > 0) {
      if (detailsCachets) detailsCachets += ", ";
      detailsCachets += `${cachetsRepetitions} service${cachetsRepetitions > 1 ? 's' : ''} de répétition`;
    }
    if (!detailsCachets && heures > 0) {
      detailsCachets = `${heures} heure${heures > 1 ? 's' : ''}`;
    }

    // Dates travaillées
    let datesTravaillees = "";
    if (dureeData.dates_representations) {
      datesTravaillees += dureeData.dates_representations;
    }
    // Pour les répétitions, utiliser dates_repetitions_heures si disponible, sinon dates_repetitions
    if (dureeData.dates_repetitions_heures) {
      if (datesTravaillees) datesTravaillees += " ; ";
      datesTravaillees += dureeData.dates_repetitions_heures;
    } else if (dureeData.dates_repetitions) {
      if (datesTravaillees) datesTravaillees += " ; ";
      datesTravaillees += dureeData.dates_repetitions;
    }
    if (dureeData.jours_travail) {
      if (datesTravaillees) datesTravaillees += " ; ";
      datesTravaillees += dureeData.jours_travail;
    }
    if (!datesTravaillees) {
      // Utiliser les dates du contrat original
      if (contract.jours_representations) datesTravaillees += contract.jours_representations;
      if (contract.jours_repetitions) {
        if (datesTravaillees) datesTravaillees += " ; ";
        datesTravaillees += contract.jours_repetitions;
      }
      if (contract.jours_travail) {
        if (datesTravaillees) datesTravaillees += " ; ";
        datesTravaillees += contract.jours_travail;
      }
    }

    // Panier repas
    const panierRepas = contract.panier_repas === "Oui" ? 1 : "";
    const panierRepasCCN = contract.panier_repas === "Oui" ? "Oui" : "Non";
    const montantPanierRepas = contract.montant_panier_repas || "20,20";

    // CCN
    const ccn = contract.convention_collective || "Convention Collective Nationale du Spectacle Vivant Privé";

    // Construction du payload pour PDFMonkey
    const dataPayload = {
      annulation: typeAvenant === "annulation" ? "Oui" : "Non",
      structure_name: organization?.name || orgDetails.structure || "",
      structure_adresse: orgDetails.adresse || "",
      structure_cpville: orgDetails.cp || "",
      structure_ville: orgDetails.ville || "",
      structure_siret: orgDetails.siret || "",
      structure_licence: orgDetails.licence_spectacles || "",
      structure_signataire: `${orgDetails.prenom_signataire || ""} ${orgDetails.nom_signataire || ""}`.trim(),
      structure_signatairequalite: orgDetails.qualite_signataire || "",
      delegation: orgDetails.delegation_signature ? "Oui" : "Non",
      employee_civ: salarie.civilite || "",
      employee_firstname: salarie.prenom || "",
      employee_lastname: salarie.nom || "",
      employee_dob: formatDate(salarie.date_naissance),
      employee_cob: salarie.lieu_de_naissance || "",
      employee_address: salarie.adresse || "",
      employee_ss: salarie.nir || "",
      employee_cs: salarie.conges_spectacles || "",
      employee_profession: profession,
      employee_catpro: employee_catpro,
      spectacle: professionData.production_name || contract.production_name || "",
      numobjet: professionData.production_numero_objet || contract.objet_spectacle || "",
      debut_contrat: formatDate(dureeData.date_debut || contract.start_date),
      fin_contrat: formatDate(dureeData.date_fin || contract.end_date),
      date_avenant: formatDate(amendmentData.date_signature),
      dates_travaillees: datesTravaillees,
      details_cachets: detailsCachets,
      salaire_brut: remunerationData.gross_pay 
        ? parseFloat(remunerationData.gross_pay.toString()).toLocaleString('fr-FR', { 
            minimumFractionDigits: 2, 
            maximumFractionDigits: 2 
          })
        : contract.gross_pay 
          ? parseFloat(contract.gross_pay.toString()).toLocaleString('fr-FR', { 
              minimumFractionDigits: 2, 
              maximumFractionDigits: 2 
            })
          : "",
      precisions_salaire: remunerationData.precisions_salaire || contract.precisions_salaire || "",
      signature_contrat: formatDate(contract.date_signature),
      CCN: ccn,
      effet_avenant: formatDate(amendmentData.date_effet),
      elements_avenant: elementsText,
      panierrepas: panierRepas,
      panierrepasccn: panierRepasCCN,
      montantpanierrepas: montantPanierRepas,
      cachets: {
        representations: cachetsRepresentations,
        repetitions: cachetsRepetitions,
        heures: heures,
        heuresparjour: heuresParJour
      },
      dates_representations_detail: dureeData.dates_representations || contract.jours_representations || "",
      dates_repetitions_detail: dureeData.dates_repetitions_heures || dureeData.dates_repetitions || contract.jours_repetitions || "",
      imageUrl: orgDetails.logo || ""
    };

    console.log("🚀 [generate-pdf] Type avenant pour PDFMonkey:", typeAvenant);
    console.log("🚀 [generate-pdf] Valeur annulation:", typeAvenant === "annulation" ? "Oui" : "Non");
    console.log("Payload PDFMonkey:", JSON.stringify(dataPayload, null, 2));

    // Appel à PDFMonkey pour générer le PDF
    const templateId = "BC5E26D6-4A3B-45F8-8376-25F83C17A413";
    const pdfResponse = await fetch(pdfMonkeyUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${pdfMonkeyApiKey}`
      },
      body: JSON.stringify({
        document: {
          document_template_id: templateId,
          payload: dataPayload,
          status: "pending"
        }
      })
    });

    if (!pdfResponse.ok) {
      const errorText = await pdfResponse.text();
      console.error("Erreur PDFMonkey:", errorText);
      return NextResponse.json(
        { error: "Erreur lors de la génération du PDF", details: errorText },
        { status: 500 }
      );
    }

    const pdfData = await pdfResponse.json();
    const documentId = pdfData.document.id;

    console.log("Document PDFMonkey créé:", documentId);

    // Polling pour attendre que le PDF soit prêt
    const completedDocument = await pollDocumentStatus(documentId, pdfMonkeyUrl, pdfMonkeyApiKey);

    // Télécharger le PDF depuis PDFMonkey
    const pdfUrl = completedDocument.download_url;
    const pdfBuffer = await fetch(pdfUrl).then(res => res.arrayBuffer());

    // Upload vers S3
    const orgSlug = slugify(organization?.name || orgDetails.structure || "organisation");
    const filename = `avenant_${contract.contract_number}_${Date.now()}.pdf`;
    const s3Key = `avenants/${orgSlug}/${filename}`;

    await s3Client.send(
      new PutObjectCommand({
        Bucket: "odentas-docs",
        Key: s3Key,
        Body: Buffer.from(pdfBuffer),
        ContentType: "application/pdf",
      })
    );

    console.log("PDF uploadé sur S3:", s3Key);

    // Générer un lien présigné pour GET (visualisation)
    const presignedUrl = await getSignedUrl(
      s3Client,
      new GetObjectCommand({
        Bucket: "odentas-docs",
        Key: s3Key,
      }),
      { expiresIn: 3600 } // 1 heure
    );

    return NextResponse.json({
      success: true,
      s3Key,
      presignedUrl,
      filename
    });

  } catch (error: any) {
    console.error("Erreur lors de la génération du PDF:", error);
    return NextResponse.json(
      { error: "Erreur serveur", details: error.message },
      { status: 500 }
    );
  }
}
