var express = require('express');
var router = express.Router();
const authentification = require('../middlewares/authentification');
const DB = require('../models/index');
const { Op } = require('sequelize');
const moment = require('moment');
const FunctionController = require('../controllers/functionController');
const MedicalController = require('../controllers/medicalController');
const FileController = require('../controllers/fileController');

const fs = require('fs');
const Docxtemplater = require('docxtemplater');
const path = require('path');
const PizZip = require("pizzip");
const multer = require('multer');

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, 'public/files/');
    },
    filename: function (req, file, cb) {
      cb(null, file.originalname);
    }
  });
  
  const upload = multer({ storage: storage, preservePath: true });

router.get('/demand/:id?', authentification, async(req, res) => {
    //  Id de l'employee 
    const id = req.params.id || null;
    let errors = null;
    let employees = [];
    
    //  Pour le simple demande
    if (!id) {    
        //  Trouver tout les employees
        var allEmployee = await DB.employee.findAll();  
        for(let i = 0; i < allEmployee.length; i++) {
            allEmployee[i].interims = [];
            if(allEmployee[i]) {
                let interims = await DB.interim.findAll({ where:{ employeeId: allEmployee[i].id }});
                for(let j = 0; j < interims.length; j++) {
                    let interim = await DB.employee.findOne({ where: { id: interims[j].interimId}});
                    if(interim) {
                        allEmployee[i].interims.push(interim)
                    }
                }
            }       
        }              
    }
    //  Pour le demande personnaliser d'un employee
    else {
        var allEmployee = [];
        result = await DB.employee.findOne({ where: { id: id }});
        //  Leur interimaire
        if(result) {
            result.interims = [];
            let interims = await DB.interim.findAll({ where:{ employeeId: result.id }});
            for(let j = 0; j < interims.length; j++) {
                let interim = await DB.employee.findOne({ where: { id: interims[j].interimId}});
                if(interim) {
                    result.interims.push(interim)
                }
            }            
            allEmployee.push(result);
        }
    }
    //  Trouver leurs repos de l'annee
    for( i = 0; i < allEmployee.length; i++ ) {        
        
        let canApplicant = await DB.adminEmployee.findOne({where : {
            [Op.and]: [
                { isApplicant: true },
                { employeeId: allEmployee[i].id },
                { AdmnistratorId: req.session.admin.id }
            ]
        }});
        
        if( canApplicant ) {            
            let employee = allEmployee[i];
            employee.permission = await MedicalController.getMedicalOnYear(employee.id, new moment());
            let fonction = await FunctionController.getFunctionEmployee(employee.id);
            if(fonction) {
                employee.fonction = fonction.nameFunction;
            }
            else {
                employee.fonction = '';
            }            
            employees.push(employee);
        }                
    }                   
    res.render('pages/forms/medical.ejs', { employees, errors, req });
});

router.post('/demand', authentification, 
    upload.single('pieceJust'),
    async (req, res) => {        
        await MedicalController.requestMedical(req, res);
    })

router.get('/:id(\\d+)', authentification, async (req, res) => {
    let errors = null;
    let id = req.params.id;
    let medical = await DB.medical.findByPk(id);        
    if(!medical) {
        return res.redirect('/');
    }
    let employee = await DB.employee.findByPk(medical.employeeId);
    if(!employee) {
        return res.redirect('/');
    } 
    
    //  Piece justificative
    let piece = await DB.medicalJustificative.findOne({ where: { medicalId: medical.id } });    
    if(piece) {
        medical.piece = piece;
    }
    else {
        medical.piece = null;
    }

    //  Interimaire
    if(medical.interimId) {
        let interim = await DB.employee.findByPk(medical.interimId);
        if(interim) {
            employee.name_interim = interim.name_employee + ' ' + interim.last_name_employee;            
            let fonction = await FunctionController.getFunctionEmployee(interim.id);
            if(fonction) {
                employee.fonction_interim = fonction.nameFunction;
            }
            else {
                employee.fonction_interim = '';
            }
        }
    }

    // fonction de l'employee
    let fonction = await FunctionController.getFunctionEmployee(employee.id);
    if(fonction) {
        employee.fonction = fonction.nameFunction;
    }
    else {
        employee.fonction = '';
    }

    //  Fiche de passation
    let passingFile = await DB.passingFile.findOne({
        where: { medicalId: medical.id },
        order: [['createdAt','DESC']]
    });
    if(passingFile) {
        medical.passingFile = passingFile;
        //  Taches
        let tasks = await DB.task.findAll({ where:{ passingFileId: passingFile.id }});
        if(tasks.length > 0) {
            medical.passingFile.tasks = tasks;
        }

        //  Personnels
        let personnels = await DB.personnel.findAll({ where: { passingFileId: passingFile.id }});
        if(personnels.length > 0) {
            medical.passingFile.personnels = personnels;
        }        

        //  Materiels
        let materials = await DB.material.findAll({ where: { passingFileId: passingFile.id }});
        if(materials.length > 0) {
            medical.passingFile.materials = materials;
        }

        //  signatures
        let signatures = await DB.signature.findAll({ where: { passingFileId: passingFile.id }});
        if(signatures.length > 0) {
            medical.passingFile.signatures = signatures;
        }        
    }
    else {
        medical.passingFile = null;
    }

    //  Trouver le validateur
    let validateur = await DB.admin.findOne({ where: { id: medical.AdmnistratorId }});
    if(validateur) {                    
        medical.validateur = validateur;
        medical.isConfirmed = (medical.validateur.id > 0) ? true : false;
    }        
    medical.nbrDays = MedicalController.nbrDaysBetweenDates(medical.startDate, medical.endDate);
    if(medical) {
        res.render('pages/forms/medical.edit.ejs', {         
            employee,
            medical,            
            errors,
            req 
        })
    }
})

//  Mise a jour, Confirmation ou rejection
router.post('/:id(\\d+)', 
    authentification,     
    MedicalController.update
);

router.post('/piece', authentification, 
    upload.single('pieceJust'),
    async (req, res) => {
        if(req.file && req.body.medicalId) {
            const { fieldname, filename, path, mimetype } = req.file;        
            let r = await DB.medicalJustificative.create({
                filename,
                path,
                mimetype,
                medicalId: req.body.medicalId
            });        
            return res.redirect(`/medical/${req.body.medicalId}`);
        }
        res.redirect('/');
    });

router.get('/piece/:id(\\d+)', authentification, async(req, res) => {
    const ID = req.params.id || null;
    let piece = await DB.medicalJustificative.findByPk(ID);    
    if(piece) {        
        piece.path = piece.path.replace("public",'../../');
        console.log(piece.path);
        res.send(`<iframe src="${piece.path}" width="100%" height="100%" border="none" alt="CV" ></iframe>`)
    }
    else {
        res.redirect('/');
    }    
});

router.delete('/delete-piece-just/:id(\\d+)', authentification,     
    async (req, res) => {
        const ID = req.params.id;
        let piece = await DB.medicalJustificative.findByPk(ID);
        if(piece) {
            piece.destroy();
            return res.json({ message: 'sucess delete' });
        }
        res.redirect('/');
    })

router.post('/passingFile',
    authentification,    
    async (req, res) => {    
        let data = {
            poste: req.body.fonction,
            direction: req.body.direction,
            holder: req.body.titulaire,
            interim: req.body.interimaire,
            medicalId: req.body.medicalId
        }

        // Passation de service
        try {
            var passFile = await DB.passingFile.create(data);
        }
        catch(err) {
            console.log(err);
            return res.send(err);
        }

        //  Tache
        let task = req.body.taches;
        let deliverable = req.body.livrables;
        let reference = req.body.referentiels;

        if(task && deliverable && reference) {            
            if( Array.isArray(task) && Array.isArray(deliverable) && Array.isArray(reference) ) {
                for(let i = 0; i < task.length && i < deliverable.length && i < reference.length; i++) {                    
                    if(task[i] && deliverable[i] && reference[i]) {
                        let rslt = await DB.task.create({
                            description : task[i], 
                            deliverable : deliverable[i],
                            reference : reference[i],
                            passingFileId: passFile.id                
                        });
                    }
                }
            }
            else {                
                let rslt = await DB.task.create({
                    description : task, 
                    deliverable, 
                    reference,
                    passingFileId: passFile.id
                });                
            }
        }

        //  Personnel
        let noms = req.body.noms;
        let fonctions = req.body.fonctions;

        if(noms && fonctions) {            
            if( Array.isArray(noms) && Array.isArray(fonctions) ) {
                for(let i = 0; i < noms.length && i < fonctions.length ; i++) {
                    if(noms[i] && fonctions[i]) {
                        let rslt = await DB.personnel.create({
                            name_and_last: noms[i],
                            fonction: fonctions[i],
                            passingFileId: passFile.id                
                        });
                    }
                }
            }
            else {                
                let rslt = await DB.personnel.create({
                    name_and_last: noms,
                    fonction: fonctions,
                    passingFileId: passFile.id
                });                
            }
        }

        //  Materiels
        let description = req.body.descriptions;
        let quantity = req.body.quantities;
        let state = req.body.etats;
        console.log(description);
        console.log(quantity);
        console.log(state)

        if(description && quantity && state) {            
            if( Array.isArray(description) && Array.isArray(quantity) && Array.isArray(state)) {
                for(let i = 0; i < description.length && i < quantity.length && i < state.length; i++) {
                    if(description[i] && quantity[i] && state[i]) {
                        let rslt = await DB.material.create({
                            description: description[i],
                            quantity: quantity[i],
                            state: state[i],
                            passingFileId: passFile.id                
                        });
                    }
                }
            }
            else {                
                let rslt = await DB.material.create({
                    description: description,
                    quantity: quantity,
                    state: state,
                    passingFileId: passFile.id
                });                
            }
        }

        // Signatures
        let doc_type = req.body.typeDocs;
        let responsability_level = req.body.responsabilites;

        if(doc_type && responsability_level) {            
            if( Array.isArray(doc_type) && Array.isArray(responsability_level) ) {
                for(let i = 0; i < doc_type.length && i < responsability_level.length ; i++) {
                    if(doc_type[i] && responsability_level[i]) {
                        let rslt = await DB.signature.create({
                            doc_type: doc_type[i],
                            responsability_level: responsability_level[i],
                            passingFileId: passFile.id                
                        });
                    }
                }
            }
            else {                
                let rslt = await DB.signature.create({
                    doc_type: doc_type,
                    responsability_level: responsability_level,
                    passingFileId: passFile.id                                    
                });                
            }
        }


        let medicalId = req.body.medicalId;                              
        res.redirect(`/medical/${medicalId}`);
    });

router.delete('/delete-passing-file/:id(\\d+)', async (req, res) => {
    let id = req.params.id;
    let passFile = await DB.passingFile.findByPk(id);
    if(passFile) {
        passFile.destroy();
    }
    res.status(200).json({ message: "success"});
})

router.get('/export-passingFile/:id(\\d+)', async (req, res) => {            
    let id = req.params.id;
    const passingFile = await FileController.getPassingFile(id);
    if(passingFile) {            

        let permission = await DB.permission.findByPk(passingFile.permissionId);
        if(permission) {
            var { startDate, endDate } = permission;
        }
        else {
            var { startDate, endDate } = '';
        }

        let tasks = await DB.task.findAll({where: { passingFileId: passingFile.id }});
        let personnels = await DB.personnel.findAll({where: { passingFileId: passingFile.id }});
        let materials = await DB.material.findAll({where: { passingFileId: passingFile.id }});
        let signatures = await DB.signature.findAll({where: { passingFileId: passingFile.id }});

        // Load the docx file as binary content
        const content = fs.readFileSync(
            path.join(__dirname, "../public/files/model.docx"),
            "binary"
        );

        const zip = new PizZip(content);

        const doc = new Docxtemplater(zip, {
            paragraphLoop: true,
            linebreaks: true,
        });

        // Render the document (Replace {first_name} by John, {last_name} by Doe, ...)
        console.log(personnels)
        doc.render({
                poste: passingFile.poste,
                direction: passingFile.direction,
                startDate: startDate,
                endDate: endDate,
                holder: passingFile.holder,
                interim: passingFile.interim,
                tasks: tasks,      
                personnels: personnels,
                materials: materials,
                signatures: signatures
            });

        const buf = doc.getZip().generate({
            type: "nodebuffer",
            // compression: DEFLATE adds a compression step.
            // For a 50MB output document, expect 500ms additional CPU time
            compression: "DEFLATE",
        });

        // buf is a nodejs Buffer, you can either write it to a
        // file or res.send it with express for example.
        let filepath = path.resolve(__dirname, "../public/files/fiche.docx");
        fs.writeFileSync(filepath, buf);
        res.download(filepath, () => {
            console.log('telechargement....')
            fs.unlinkSync(filepath);
        })
        console.log('Fichier PDF généré avec succès !');

    }
    else {
        res.redirect('/');
    }    
});

router.post('/reject', authentification, async (req, res) => {
    let idMedical = parseInt(req.body.idMedical);
    let rejectReason = req.body.reject;
  
    let medical = await DB.medical.findByPk(idMedical);
      
    if(medical) {

      let applicant = await DB.admin.findOne({ where: {id : medical.applicantId }});
      let employee = await DB.employee.findOne({ where: { id: medical.employeeId }})
      if(applicant) {
        let email = applicant.email;
        const MAIL = process.env.ENV == 'prod' ? process.env.MAIL : process.env.MAIL_LOCAL;
        
        //  Trouver le rejecteur
        let rejector = await DB.admin.findOne({ where: { id: req.session.admin.id }});
        if(rejector) {                    
          employee.rejector = rejector;                
          const mailOptions = {          
              from: MAIL,
              to: email,
              subject: 'Demande de repos maladie',
              text: 
              `${employee.name_employee} ${employee.last_name_employee}
matricule:${employee.matricule}
Repos maladie rejeté par ${rejector.firstName} ${rejector.lastName}.`          
          };        
          console.log(email);
        }
      }
    }
  
    try {
        // console.log(DB.permissionRejected)
      let rejected = await DB.medicalRejected.create({ 
          employeeId: medical.employeeId,   
          startDate: medical.startDate,
          endDate: medical.endDate,           
          rejectReason: rejectReason,
          rejectedBy: req.session.admin.id
      });    
      await medical.destroy();
    
    res.send('rejecter')
    }
    catch(err) {
        console.log(err);
        res.send('not rejected')
    }
})

module.exports = router;

 