const express = require("express");
const router = express.Router();
const fs = require("fs");
const PizZip = require("pizzip");
const Docxtemplater = require("docxtemplater");
const logger = require("../utils/logger");
const path = require("path");
const moment = require("moment");
const parcoursService = require("../services/parcoursService");
const contratService = require("../services/contratService");
const globalService = require("../services/globalService");

require("moment/locale/fr");
moment.locale("fr");

router.post("/rc/projet/:numParcours", async (req, res) => {
  const content = fs.readFileSync(
    path.resolve("src/templates/template-projet-rc.docx"),
    "binary"
  );

  const zip = new PizZip(content);
  const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
  const numParcours = req.params.numParcours.toUpperCase();

  const parcours = await parcoursService.getParcoursByNumParcours(numParcours);
  const contrat = await contratService.getContratById(parcours.contrat);
  const client = contrat?.["@expand"]?.client || {};
  const intermediaire = contrat?.["@expand"]?.intermediaire || {};
  const rc = contrat?.["@expand"]?.enCours || {};

  const listAssAdd = [];

  try {
    rc.assureAdditionnel.forEach((objet) => {
      listAssAdd.push(
        objet.nom +
          " - Adresse : " +
          objet.adresse +
          " - Siret : " +
          objet.siret
      );
    });
  } catch (error) { }

  // Conditions zone
  hasMondeEntier = false;
  hasZone1 = false;
  hasZone2 = false;
  hasZone3 = false;
  hasZone4 = false;
  hasZone5 = false;
  hasZone6 = false;
  hasActiviteButNotMultimodal = false; // Attention trick pour les zones géographiques dans le cas de multimodal
  hasZone456 = false;

  // Cas monde entier
  if (
    rc.zone1 &&
    rc.zone2 &&
    rc.zone3 &&
    rc.zone4 &&
    rc.zone5 &&
    rc.zone6 &&
    (rc.actVoiturier ||
      rc.actLoueur ||
      rc.actDouane ||
      rc.actDemPar ||
      rc.actDemParDom ||
      rc.actDemParAdv ||
      rc.actDemEntr ||
      rc.actDemInterne ||
      rc.actGardeMeuble ||
      rc.actEntDep ||
      rc.actPrestaLog ||
      rc.actLevageur)
  ) {
    hasMondeEntier = true;
  }

  // Cas date du jour d'édition
  let dateNow;

  dateNow = moment().format("DD MMMM YYYY");

  // Cas une ou plusieurs zone(s) spécifique(s) + cas zone456
  if (hasMondeEntier == false && (rc.actVoiturier || rc.actLoueur || rc.actDouane || rc.actDemPar || rc.actDemParDom || rc.actDemParAct || rc.actDemEntr || rc.actDemInterne || rc.actGardeMeuble || rc.actEntDep || rc.actPrestaLog || rc.actLevageur ||  rc.actDemParAdv)) {
    if (rc.zone1) {
      hasZone1 = true;
    }
    if (rc.zone2) {
      hasZone2 = true;
    }
    if (rc.zone3) {
      hasZone3 = true;
    }
    if (rc.zone4) {
      hasZone4 = true;
      hasZone456 = true;
    }
    if (rc.zone5) {
      hasZone5 = true;
      hasZone456 = true;
    }
    if (rc.zone6) {
      hasZone6 = true;
      hasZone456 = true;
    }
  }

  // Cas Activité multimodal + Au minimum une zone
  if (rc.actMultimodal) {
    if (hasZone1 || hasZone2 || hasZone3 || hasZone456 || hasMondeEntier) {
      hasActiviteButNotMultimodal = true;
    }
  }

  if (rc.actMultimodal || hasMondeEntier) {
    hasMondeEntierOrMultimodal = true;
    hasNotMondeEntierOrMultimodal = false;
  } else {
    hasMondeEntierOrMultimodal = false;
    hasNotMondeEntierOrMultimodal = true;
  }

  // Conditions Extensions RCC
  let extRCC = false;

  if ( rc.extRCCModifCalArrim == true || rc.extRCCFerroutage == true || rc.extRCCFraisRecons == true || rc.extRCCConfie == true || rc.extRCCTPPC == true || rc.extRCCRegie == true || rc.extRCCSansMontageDemontage == true ) {
    extRCC = true;
  }

  // Conditions Extensions RCC
  let extRCE = false;

  if ( rc.extRCEMontageDemontage == true || rc.extRCEBraDebra == true) {
    extRCE = true;
  }

  // Conditions Activitées
  let hasActiviteDemenageurGardeMeuble = false;
  if ( rc.actDemPar == true || rc.actDemEntr == true || rc.actDemParDom == true || rc.actDemParAdv == true || rc.actDemInterne) {
    hasActiviteDemenageurGardeMeuble = true;
  }

  let oneOfActiviteDemenageurParticulier = false;
  if ( rc.actDemPar == true || rc.actDemParDom == true || rc.actDemParAdv == true ) {
    oneOfActiviteDemenageurParticulier = true;
  }

  let coorDem = "";
  if ( (rc.actDemPar == true || rc.actDemParDom == true || rc.actDemParAdv == true) && (rc.actDemEntr == true || rc.actDemInterne == true) && rc.actGardeMeuble == true) {
    coorDem = ",";
  } else if ( (rc.actDemPar == true || rc.actDemParDom == true || rc.actDemParAdv == true) && (rc.actDemEntr == true || rc.actDemInterne == true) && rc.actGardeMeuble == false ) {
    coorDem = " et";
  }

  // Variables numériques
  const franchiseTarif = "250";

  try {
    doc.render({
      // Client
      nomClient: client.nom,
      adrClient: client.adresse,
      postalClient: client.codePostal,
      villeClient: client.ville,
      numClient: client.numClient,

      // Intermédiaire
      nomInter: intermediaire.nom,
      adrInter: intermediaire.adresse,
      postalInter: intermediaire.codePostal,
      villeInter: intermediaire.ville,
      oriasInter: intermediaire.numOrias,
      hasOrias: intermediaire.numOrias == "" ? false : true,
      numInter: intermediaire.numTelephone,
      mailInter: intermediaire.mail,
      hasMail: intermediaire.mail ? true : false,

      // Contrat
      numSaisine: contrat.numSaisine,
      numContrat: contrat.numContrat,
      numProjet: contrat.numSaisine ? contrat.numSaisine : contrat.numContrat,
      hasCP: contrat.type == "AN" || contrat.type == "TEMPORAIRE" ? true : false,
      hasRemplacement: contrat.type == "REMPLACEMENT" ? true : false,
      hasPJ: rc.pj,
      hasParticipationResultat: rc.participationResultat,
      hasRCE: rc.autresRC,
      hasExtRCC: extRCC,
      hasExtRCE: extRCE,
      hasAssAdd: listAssAdd.length > 0 ? true : false,
      listAssAdd: listAssAdd,
      listDesiVehicule: rc.designationVehicule,
      hasForfaitaire: rc.typeCot == "forfaitaire" ? true : false,
      hasRevisable: rc.typeCot == "revisable" ? true : false,
      hasCourtier: intermediaire.type == "COURTIER" ? true : false,
      hasAgent: intermediaire.type == "COURTIER" ? false : true,
      hasAgentMutualiste: intermediaire.type == "AGENT MUTUALISTE" ? true : false,

      // Temporalité contrat
      dateJour: dateNow,
      typeFractionnement: rc.tempo,
      hasTypeTemporaire: contrat.type == "TEMPORAIRE" ? true : false,
      hasTypeAutreTempo: contrat.type == "AN" || contrat.type == "REMPLACEMENT" ? true : false,
      dateDebutEffet: rc.dateEffet == "00/00/0000" ? "A PRECISER" : rc.dateEffet,
      dateFinEffet: rc.dateFin == "00/00/0000" ? "A PRECISER" : rc.dateFin,
      dateEcheance: rc.dateEcheance == "00/00" ? "A PRECISER" : rc.dateEcheance,

      // Activite
      hasActiviteVoiturier: rc.actVoiturier,
      garActiviteVoiturier: globalService.customFormatNumber(rc.valueActVoiturier, false),
      hasActiviteLoueur: rc.actLoueur,
      garActiviteLoueur: globalService.customFormatNumber(rc.valueActLoueur, false),
      hasActiviteMultimodal: rc.actMultimodal,
      garActiviteMultimodal: globalService.customFormatNumber(rc.valueActMultimodal, false),
      hasActiviteDouane: rc.actDouane,
      garActiviteDouane: globalService.customFormatNumber(rc.valueActDouane, false),
      hasOneOfActiviteDemenageurParticulier: oneOfActiviteDemenageurParticulier,
      hasActiviteDemenageurParticulier: rc.actDemPar,
      garActiviteDemenageurParticulier: globalService.customFormatNumber(rc.valueActDemPar, false),
      hasActiviteDPEtendue: rc.actDemParDom,
      garActiviteDPEtendue: globalService.customFormatNumber(rc.valueActDemParDom, false),
      hasActiviteDemenageurParticulierAdvalorem: rc.actDemParAdv,
      garActiviteDemenageurParticulierAdvalorem: globalService.customFormatNumber(rc.valueActDemParAdv, false),
      hasActiviteDemenageurEntreprises: rc.actDemEntr,
      garActiviteDemenageurEntreprises: globalService.customFormatNumber(rc.valueActDemEntr, false),
      hasActiviteDemenageurInterne: rc.actDemInterne,
      garActiviteDemenageurInterne: globalService.customFormatNumber(rc.valueActDemInterne, false),
      hasActiviteGardeMeubles: rc.actGardeMeuble,
      garActiviteGardeMeubles: globalService.customFormatNumber(rc.valueActGardeMeuble, false),
      hasActiviteEntrepositaireDepositaire: rc.actEntDep,
      garActiviteEntrepositaireDepositaire: globalService.customFormatNumber(rc.valueActEntDep, false),
      hasActivitePrestataireLogistique: rc.actPrestaLog,
      garActivitePrestataireLogistique: globalService.customFormatNumber(rc.valueActPrestaLog, false),
      hasActiviteManutentionnaireLevageur: rc.actLevageur,
      garActiviteManutentionnaireLevageur: globalService.customFormatNumber(rc.valueActLevageur, false),
      hasActiviteTransitaire: rc.actTransitaire,
      garActiviteTransitaire: globalService.customFormatNumber(rc.valueActTransitaire, false),
      hasActiviteDemenageurGardeMeuble: hasActiviteDemenageurGardeMeuble,
      varCoorDem: coorDem,

      // Marchandises
      hasMarchandiseOrdinaire: rc.marOrdinaire,
      hasMarchandiseVehiculesRoulants: rc.marRoulant,
      hasMarchandiseEngins: rc.marEngins,
      hasMarchandiseVehiculesRoulantsDemenagement: rc.marRoulantDem,
      hasMarchandiseMobiliersUsages: rc.marMobilerUsag,
      hasMarchandisePerissables: rc.marPerissable,
      hasMarchandiseAnimauxVivants: rc.marAnimaux,
      hasMarchandiseCiterne: rc.marCiterne,
      hasMarchandiseBeton: rc.marBeton,
      hasMarchandiseExceptionnels: rc.marExceptionnels,
      hasMarchandiseVrac: rc.marVrac,

      // Zone
      hasMondeEntier: hasMondeEntier,
      hasZone1: hasZone1,
      hasZone2: hasZone2,
      hasZone3: hasZone3,
      hasZone4: hasZone4,
      hasZone5: hasZone5,
      hasZone6: hasZone6,
      hasActiviteButNotMultimodal: hasActiviteButNotMultimodal,
      hasMondeEntierOrMultimodal: hasMondeEntierOrMultimodal,
      hasNotMondeEntierOrMultimodal: hasNotMondeEntierOrMultimodal,
      hasZone456: hasZone456,

      // Extensions de garanties RCC
      hasExtModifCallageArrimage: rc.extRCCModifCalArrim,
      hasExtFerroutage: rc.extRCCFerroutage,
      hasExtReconstitution: rc.extRCCFraisRecons,
      hasExtConfies: rc.extRCCConfie,
      hasCCValeurDecla: rc.typeExtConfies == "VALEUR DECLAREE" || rc.typeExtConfies == "" ? true : false,
      hasCCAdValo: rc.typeExtConfies == "ADVALOREM" ? true : false,
      hasExtTPPC: rc.extRCCTPPC,
      hasExtRegie: rc.extRCCRegie,
      hasExtSansMontageDemontage: rc.extRCCSansMontageDemontage,

      // Extensions de garanties RCC
      hasExtBranchementDebranchement: rc.extRCEBraDebra,
      hasExtMontageDemontage: rc.extRCEMontageDemontage,

      // Advalo
      grMultimodal: rc.grilleMultimodal,
      grTerrestre: rc.grilleTerrestre,
      grAerien: rc.grilleAerien,

      // Variables numérique
      franchiseTarif: franchiseTarif,
      cotisationRCCHT: globalService.customFormatNumber(rc.cotRCCHT, true),
      tauxRCCHT: globalService.customFormatNumber(rc.tauxRCCHT, true, true),
      cotisationRCCTTC: globalService.customFormatNumber(rc.cotRCCTTC, true),
      tauxRCCTTC: globalService.customFormatNumber(rc.tauxRCCTTC, true, true),
      cotisationRCEHT: globalService.customFormatNumber(rc.cotRCEHT, true),
      tauxRCEHT: globalService.customFormatNumber(rc.tauxRCEHT, true, true),
      cotisationRCETTC: globalService.customFormatNumber(rc.cotRCETTC, true),
      tauxRCETTC: globalService.customFormatNumber(rc.tauxRCETTC, true, true),
      PJHT: globalService.customFormatNumber(rc.cotPJHT, true),
      PJTTC: globalService.customFormatNumber(rc.cotPJTTC, true),
      cotisationMini: globalService.customFormatNumber(rc.cotIrreductible, true),
      cotisationTotale: globalService.customFormatNumber(rc.cotTotalTTC, true),
      fraisRepFraction: globalService.customFormatNumber(rc.cotFraisTTC, true),
      ca: globalService.customFormatNumber(rc.ca, true),
    });
  } catch (error) {
    const e = {
      message: error.message,
      name: error.name,
      stack: error.stack,
      properties: error.properties,
    };
    logger.log('error', JSON.stringify({ error: e }));

    // Envoyez une réponse d'erreur si le rendu échoue
    return res.status(500).send("Erreur lors de la génération du document");
  }

  const buf = doc.getZip().generate({ type: "nodebuffer" });

  const currentDate = new Date();

  // Formatage de la date au format "JJ-MM-AAAA-HH-MM-SS"
  const day = String(currentDate.getDate()).padStart(2, "0");
  const month = String(currentDate.getMonth() + 1).padStart(2, "0");
  const year = currentDate.getFullYear();
  const hours = String(currentDate.getHours()).padStart(2, "0");
  const minutes = String(currentDate.getMinutes()).padStart(2, "0");
  const seconds = String(currentDate.getSeconds()).padStart(2, "0");
  const formattedDate = `${day}-${month}-${year}-${hours}-${minutes}-${seconds}`;

  // Génération du nom de fichier
  const sanitizedClientNom = client.nom
    .replace(/[^\w\s.-]/gi, "")
    .replace(/\s+/g, "-");
  const filename = `Projet-${contrat.produit}-${parcours.numParcours}-${sanitizedClientNom}-${formattedDate}`;

  // Définit le type de contenu et un nom de fichier par défaut pour le téléchargement
  res.setHeader(
    "Content-Type",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
  );

  res.setHeader(
    "Content-Disposition",
    "attachment; filename=" + filename + ".docx"
  );

  // Envoie le buffer au client, déclenchant le téléchargement
  res.send(buf);
});

module.exports = router;
