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("/fac/projet/:numParcours", async (req, res) => {
    const content = fs.readFileSync(
        path.resolve("src/templates/template-projet-fac.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 fac = contrat?.["@expand"]?.enCours || {};

    const moyenTransportList = ["terrestre", "maritime", "aerien", "postal", "fluvial"]
    const selectedTransportList = []

    try {
        moyenTransportList.forEach((transport) => {
            if (fac[transport] !== "") {
                selectedTransportList.push(transport)
            }
        })
    } catch (error) { }

    
    var transportListVirguleEt
    
    if (selectedTransportList.length > 1) {
        transportListVirguleEt = selectedTransportList
        .slice(0, selectedTransportList.length - 1)
        .join(', ')
        + ' et ' + selectedTransportList[selectedTransportList.length - 1]
    } else {
        transportListVirguleEt = selectedTransportList.toString()
    }

    
    //au féminin
    const transportListOuEt = selectedTransportList.join(" et/ou ")
        .replace('fluvial', "fluviale")
        .replace('postal', 'postale')
        .replace('aerien', 'aerienne')


    const listAssAdd = [];

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

    const risqueTransport = {
        "achat": "des contrats d'achat",
        "vente": "des contrats de vente",
        "sav": "des opérations de SAV",
        "demo": "des démonstrations",
        "transfert": "des transferts inter-usines"
    }

    Object.keys(risqueTransport).forEach((risque) => {
        if (!fac.risqueTransport.includes(risque)) {
            delete risqueTransport[risque]
        }
    })

    const listRisqueTransport = Object.keys(risqueTransport).map((key) => risqueTransport[key])

    const mondeEntier = (fac.zone1 && fac.zone2 && fac.zone3 && fac.zone4 && fac.zone5 && fac.zone6)
    const hasZone456 = (fac.zone4 || fac.zone5 || fac.zone6)

    const hasGarOptAuto = fac.garOpt.includes('auto')
    const hasGarOptEmballage = fac.garOpt.includes('emballage')
    const hasGarOptEtiquette = fac.garOpt.includes('etiquette')
    const hasGarOptTemperature = fac.garOpt.includes('temperature')
    const hasGarOptMarque = fac.garOpt.includes('marque')
    const hasTPPC = fac.typeTPPC !== ""
    const hasMarchandiseExposition = !(fac.marExpo == "" || fac.marExpo == 0)

    const condition4 = (hasGarOptAuto || hasGarOptEmballage || hasGarOptEtiquette || hasGarOptMarque || hasTPPC || hasMarchandiseExposition)
    const hasGarOpt = fac.garOpt.length > 0
    const condition2 = hasGarOpt || hasTPPC || hasMarchandiseExposition

    const anneeProchaine = moment().add(1, 'years').format('YYYY')
    const dateFin = (fac.dateFin == "00/00" || fac.dateFin == "00/00/0000") ? "A PRECISER" : fac.dateFin
    const dateEffet = (fac.dateEffet == "00/00" || fac.dateEffet == "00/00/0000") ? "A PRECISER" : fac.dateEffet
    const dateEcheance = (fac.dateEcheance == "00/00" || fac.dateEcheance == "00/00/0000") ? "A PRECISER" : fac.dateEcheance + '/' + anneeProchaine

    const renderObject = {
        nomClient: client.nom,
        adrClient: client.adresse,
        postalClient: client.codePostal,
        villeClient: client.ville,
        numClient: client.numClient,

        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,
        numProjet: contrat.numSaisine ? contrat.numSaisine : contrat.numContrat,

        hasCP: (contrat.type == "AN" || contrat.type == "TEMPORAIRE"),
        hasRemplacement: (contrat.type == "REMPLACEMENT"),
        hasRGAuto: (fac.risqueGuerre == "auto"),
        hasRGDemande: (fac.risqueGuerre == 'demande'),
        hasRG: (fac.risqueGuerre == 'demande' || fac.risqueGuerre == 'auto'),
        hasEtendue: (fac.typeGarantieRG == "etendue"),
        hasWaterborne: (fac.typeGarantieRG == "waterborne"),
        hasProgrammeInternational: fac.programmeInternational,

        hasAssuresAdditionnels: listAssAdd.length > 0,
        listAssAdd: listAssAdd,
        hasTemporaire: contrat.type == "TEMPORAIRE",
        actAssure: fac.actAssure,
        typeMar: fac.typeMar,

        listMoyenTransportEtOu: transportListOuEt,
        listMoyenTransportVirguleEt: transportListVirguleEt,

        listRisqueTransport: listRisqueTransport,

        depart: fac.lieuDepart,
        arrivee: fac.lieuArrivee,
        dateJour: moment().format("DD MMMM YYYY"),
        dateEffet: dateEffet,
        dateFin: dateFin,
        dateEcheance: dateEcheance,

        hasMarchandiseExposition: hasMarchandiseExposition,
        hasMondeEntier: mondeEntier,
        hasZone1: fac.zone1,
        hasZone2: fac.zone2,
        hasZone3: fac.zone3,
        hasZone4: fac.zone4,
        hasZone5: fac.zone5,
        hasZone6: fac.zone6,
        hasZone456: hasZone456,
        hasTPPC: hasTPPC,
        hasTPPCTousRisques: fac.typeTPPC.includes('tousRisques'),
        hasTPPCFlotteND: fac.typeTPPC.includes('flotteND'),

        capitalMax: fac.capitalMax,
        franchiseTransport: fac.franchiseTransport,
        condition4: condition4,
        hasGarOpt: hasGarOpt,
        condition2: condition2,
        hasGarOptAuto: hasGarOptAuto,
        hasGarOptEmballage: hasGarOptEmballage,
        hasGarOptEtiquette: hasGarOptEtiquette,
        hasGarOptMarque: hasGarOptMarque,
        hasGarOptTemperature: hasGarOptTemperature,
        capitalTPPC: fac.capitalTPPC,
        franchiseExpo: fac.franchiseExpo,
        hasCG: fac.valeurAssuree.includes('cg'),
        hasDerogation: fac.valeurAssuree.includes('derogation'),
        hasVaBasePrix: fac.valeurAssureeBase.includes('prix'),
        hasVaBaseAchat: fac.valeurAssureeBase.includes('achat'),
        hasVaBaseVente: fac.valeurAssureeBase.includes('vente'),

        hasAerienTousRisques: fac.aerien.includes('tousRisques'),
        hasAerienEventMaj: fac.aerien.includes('eventMaj'),
        hasMaritimeTousRisques: fac.maritime.includes('tousRisques'),
        hasMaritimeEventMaj: fac.maritime.includes('eventMaj'),
        hasTerrestreTousRisques: fac.terrestre.includes('tousRisques'),
        hasTerrestreEventMaj: fac.terrestre.includes('eventMaj'),
        hasPostalTousRisques: fac.postal.includes('tousRisques'),
        hasPostalEventMaj: fac.postal.includes('eventMaj'),
        hasFluvialTousRisques: fac.fluvial.includes('tousRisques'),
        hasFluvialEventMaj: fac.fluvial.includes('eventMaj'),
        hasFranchiseTransport: fac.franchiseTransport !== "" && fac.franchiseTransport !== 0,

        cotRO: globalService.customFormatNumber(fac.cotRO),
        cotRG: globalService.customFormatNumber(fac.cotRG),
        cotProvRO: globalService.customFormatNumber(fac.cotProvRO),
        cotProvRG: globalService.customFormatNumber(fac.cotProvRG),
        cotComptant: globalService.customFormatNumber(fac.cotComptant),
        tauxCotRO: globalService.customFormatNumber(fac.tauxCotRO, true),
        tauxCotRG: globalService.customFormatNumber(fac.tauxCotRG, true),
        cotAnnuelle: globalService.customFormatNumber(fac.cotAnnuelleHT),
        cotIrred: globalService.customFormatNumber(fac.cotIrred),
        capitalTPPC: globalService.customFormatNumber(fac.capitalTPPC),
        capitalExpo: globalService.customFormatNumber(fac.capitalExpo),
        franchiseTPPC: globalService.customFormatNumber(fac.franchiseTPPC),
        chiffreAffaires: globalService.customFormatNumber(fac.ca),

        hasMensuel: (fac.tempo == "mensuel"),
        hasChiffreAffaires: (fac.typeContrat == "chiffreAffaires"),
        hasAvisAliments: (fac.typeContrat == "avisAliments"),
        hasPartResultat: fac.participationResultat,
        hasAgentMutualiste: (intermediaire.type == "AGENT MUTUALISTE"),
        hasAgent: (intermediaire.type == "AGENT MUTUALISTE" || intermediaire.type == "AGENT NON MUTUALISTE"),
        hasCourtier: (intermediaire.type == "COURTIER"),
        tempo: fac.tempo,
    }

    try {
        doc.render(renderObject)
    } 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 formattedDate = moment().format('DD-MM-YYYY-HH-mm-ss')

    // 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;
