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 userService = require("../services/userService");
const globalService = require("../services/globalService");
const moduloTPPC = require("../constantes/json-modulateur-tppc");

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


function getSelectedFranchise(franchiseId, tarif) {
	switch (franchiseId) {
		case "150":
			return tarif.franchise150
		case "300":
			return tarif.franchise300
		case "mini150":
			return tarif.franchiseMini150
		case "mini300":
			return tarif.franchiseMini300
	}
}

function getSelectedFranchiseTitre(franchiseId) {
	switch (franchiseId) {
		case "150":
			return "150 €"
		case "300":
			return "300 €"
		case "mini150":
			return "5 % avec 150 € minimum et 1 000 € maximum"
		case "mini300":
			return "10 % avec 300 € minimum et 2 000 € maximum"
	}
}

//generate Projet TPPC
router.post("/tppc/projet/:numParcours", async (req, res) => {
	// TODO Attention conditionner en fonction du type de CP

	const content = fs.readFileSync(
		path.resolve("src/templates/template-projet-tppc.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 tppc = contrat?.["@expand"]?.enCours || {};
	const projet = tppc?.["@expand"]?.projet || {};
	const tarif = tppc?.["@expand"]?.tarif || null;
	const listAssAdd = [];

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

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

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

	const hasExtGar = tppc.marCiternes || tppc.marDenreesSousTemp || tppc.marAnimaux || tppc.marFranchise || tppc.marEnExpo;

	let sinistre = projet.antSin;
	let aucunSinistre = false;
	let unSeulSinistre = false;
	let plusSinistre = false;

	if (sinistre === 0) {
		aucunSinistre = true;
	} else if (sinistre == 1) {
		unSeulSinistre = true;
	} else {
		plusSinistre = true;
	}

	const hasTemporaire = contrat.type === "TEMPORAIRE";
	const hasMensuel = projet.tempo === "mensuel";

	let formatTarifFlotte = null;

	if (tppc.tarFlotte) {
		formatTarifFlotte = tppc.tarFlotte.map((item) => {

			item.primeVehComTarif = parseFloat(item.primeVehComTarif)
			item.capitalTarif = parseFloat(item.capitalTarif)
			item.primeHTComTarif = parseFloat(item.primeHTComTarif)
			
			return {
				typeTarif: item.typeVehTarif,
				capitalTarif: globalService.customFormatNumber(item.capitalTarif,true),
				primeTarif: globalService.customFormatNumber(item.primeVehComTarif, true),
				nbVehiculesTarif: item.nbVehiculesTarif,
				primeHTTarif: globalService.customFormatNumber(item.primeHTComTarif, true),
			};
		});
	}


	let formatListDesiVehicule = null;

	if (projet.designationVehicule) {
		formatListDesiVehicule = projet.designationVehicule.map((item) => {

			item.capital = parseFloat(item.capital)

			return {
				marque: item.marque,
				genre: item.genre,
				type: item.type,
				immat: item.immat,
				capital: globalService.customFormatNumber(item.capital, true),
			};
		});
	}

	const selectedFranchiseTitre = tarif ? getSelectedFranchiseTitre(tarif.franchiseId) : "A DÉFINIR"
	const hasADefinir = tarif ? false : true
	 
	try {
		doc.render({
			//conditionnel
			hasTemporaire: hasTemporaire,
			hasMensuel: hasMensuel,
			plusSinistre: plusSinistre,
			unSeulSinistre: unSeulSinistre,
			aucunSinistre: aucunSinistre,

			// Client
			nomClient: client.nom,
			adrClient: client.adresse,
			postalClient: client.codePostal,
			villeClient: client.ville,
			numClient: client.numClient,

			// Intermédiaire
			nomInter: intermediaire.nom,
			hasInterMutualist: intermediaire.type == "AGENT MUTUALISTE" ? true : false,
			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,
			hasAssAdd: listAssAdd.length > 0 ? true : false,
			listAssAdd: listAssAdd,
			listDesiVehicule: formatListDesiVehicule,
			listeTarifFlotte: formatTarifFlotte,
			hasCotForfaitaire: projet.typeCot == "forfaitaire" ? true : false,
			hasRev: projet.typeCot == "revisable" ? true : false,
			hasCotCA: projet.typeRev == "CotCA" ? true : false,
			hasFlotteOuverte: projet.typeRev == "FlotteOuverte" ? true : false,
			hasCourtier: intermediaire.type == "COURTIER" ? true : false,
			hasAgent: intermediaire.type == "COURTIER" ? false : true,
			actAssuree: tppc.actAssuree,

			//Les garanties
			hasGarIAC: tppc.garanties.includes('IAC'),
			hasGarHIAC: tppc.garanties.includes('HIAC'),
			hasGarVol: tppc.garanties.includes('Vol'),

			//Ext Garantie
			hasGarCit: tppc.marCiternes,
			hasGarFrigo: tppc.marDenreesSousTemp,
			hasGarAniViv: tppc.marAnimaux,
			hasVehiculeTransp: tppc.marFranchise,
			hasGarMarExp: tppc.marEnExpo,
			nombreExp: tppc.nbExpo,
			franchiseMarExpo : tppc.franchiseMarExpo == "500" ? "500€" : "10% minimum 150€ maximum 1000€",
			hasExtGar: hasExtGar,
			hasADefinir : hasADefinir,

			//Antécedent de sinitre
			antSinistre: projet.antSin,
			nombreVehicule: tppc.nbVehic,

			// Informations sur les cotisations
			cotCapitalVeh:tppc.cotCapVeh,
			CA: globalService.customFormatNumber(projet.ca, true),
			cotTauxTax: globalService.customFormatNumber(projet.cotTauxTax, true, true),
			cotAnnuelleHT: globalService.customFormatNumber(tppc.primeHT, true),
			cotAnnuelleTTC: globalService.customFormatNumber(projet.tarifComTTC, true),
			cotIrrMini: globalService.customFormatNumber(projet.cotIrreductible, true),

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

			// Franchise
			selectedFranchiseTitle: selectedFranchiseTitre,
		});
	} 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);
});

//generate declinaison tarifaire TPPC
router.post("/tppc/tarif/:numParcours", async (req, res) => {
	// TODO Attention conditionner en fonction du type de CP

	const content = fs.readFileSync(
		path.resolve("src/templates/template-declinaison-tarifaire-tppc.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 tppc = contrat?.["@expand"]?.enCours || {};
	const tarif = tppc?.["@expand"]?.tarif || {};
	const user = await userService.getUserById(parcours.dernierUtilisateur);

	var formatTarifFlotte = null;
	const selectedFranchiseTitre = getSelectedFranchiseTitre(tarif.franchiseId)
	const selectedFranchise = getSelectedFranchise(tarif.franchiseId, tarif)

	const tarif150 = tarif.franchise150.proposition
	const tarif300 = tarif.franchise300.proposition
	const tarifMini150 = tarif.franchiseMini150.proposition
	const tarifMini300 = tarif.franchiseMini300.proposition
	const tarifParVeh =  tppc.primeHT / tppc.nbVehic

	if (tppc.tarFlotte) {
		formatTarifFlotte = tppc.tarFlotte.map((item) => {
			item.primeVehModRefTarif = parseFloat(item.primeVehModRefTarif)
			item.capitalTarif = parseFloat(item.capitalTarif)
			item.primeVehTarif = parseFloat(item.primeVehTarif)
			item.primeHTModRefTarif = parseFloat(item.primeHTModRefTarif)
				
			return {
				typeVehTarif: item.typeVehTarif,
				capitalTarif: globalService.customFormatNumber(item.capitalTarif, false, false) + " €",
				primeVehTarif: globalService.customFormatNumber(item.primeVehTarif, false, false) + " €",
				garTarif: item.garTarif,
				typeMarTarif: moduloTPPC.objModMar[item.typeMarTarif].tarif,
				primeVehModRefTarif: globalService.customFormatNumber(item.primeVehModRefTarif) + " €",
				nbVehiculesTarif: item.nbVehiculesTarif,
				primeHTModRefTarif: globalService.customFormatNumber(item.primeHTModRefTarif, true, false) + " €",
			};
		});
	}
	var marAssuree = []

	if (tppc.marOrdinaires) {
		marAssuree.push(moduloTPPC.objModMar.marOrdinaires.tarif)
	}
	if (tppc.marBennes) {
		marAssuree.push(moduloTPPC.objModMar.marBennes.tarif)
	}
	if (tppc.marDenreesHorsTemp) {
		marAssuree.push(moduloTPPC.objModMar.marDenreesHorsTemp.tarif)
	}
	if (tppc.marAuto) {
		marAssuree.push(moduloTPPC.objModMar.marAuto.tarif)
	}
	if (tppc.marRisques) {
		marAssuree.push(moduloTPPC.objModMar.marRisques.tarif)
	}
	if (tppc.marEngins) {
		marAssuree.push(moduloTPPC.objModMar.marEngins.tarif)
	}
	if (tppc.marCiternes) {
		marAssuree.push(moduloTPPC.objModMar.marCiternes.tarif)
	}
	if (tppc.marAnimaux) {
		marAssuree.push(moduloTPPC.objModMar.marAnimaux.tarif)
	}
	if (tppc.marDenreesSousTemp) {
		marAssuree.push(moduloTPPC.objModMar.marDenreesSousTemp.tarif)
	}

	marAssuree = marAssuree.join(', ')
	
	try {
		doc.render({

			matricule : user.matricule,
			hasContrat: contrat.numContrat || false,
			numContrat: contrat.numContrat,
			hasSaisine: contrat.numSaisine || false,
			numSaisine: contrat.numSaisine,
			nomClient: client.nom,

			actAssuree: tppc.actAssuree,
			montantSin: tarif.montantSinistre,
			franchiseSelected: selectedFranchiseTitre,

			tarFlotte: formatTarifFlotte,

			tarif150: tarif150,
			tarif300: tarif300,
			tarifMini150: tarifMini150,
			tarifMini300: tarifMini300,

			marAssuree: marAssuree,

			tarifSelected: selectedFranchise.proposition,
			tarifCommercial: tppc.primeHT,
			tarifParVeh: tarifParVeh,

			isEnsemble: tarif.typeContrat == "ensemble",
			isDetaillee: tarif.typeContrat == "detaillee",

			//Les garanties
			hasHIAC: tppc.garanties.includes('HIAC'),
			hasVol: tppc.garanties.includes('Vol'),
			nbVehic: tppc.nbVehic,

			// Informations sur les cotisations
			cotCapVeh: tppc.cotCapVeh
		});
	} 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 = `Tarif-${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;
