var express = require('express');
var router = express.Router();
const { body } = require('express-validator');
const authentification = require('../middlewares/authentification');
const VacationController = require('../controllers/vacationController');
const FunctionController = require('../controllers/functionController');
const db = require('../models');
const { Op } = require('sequelize');
const fileController = require('../controllers/fileController');
const multer = require('multer');
const fs = require('fs');
const Docxtemplater = require('docxtemplater');
const path = require('path');
const PizZip = require("pizzip");

const EmployeeModel = db.employee;
const VacationModel = db.vacation;

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( '/', authentification,( req, res, next ) => {
    res.render('home', { req })
})

//  L'id est facultatif
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 EmployeeModel.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 soldes congees
    for(let i = 0; i < allEmployee.length; i++ ) {
        let result = await VacationController.findLatestVacation(allEmployee[i].id);
        
        let canApplicant = await db.adminEmployee.findOne({where : {
            [Op.and]: [
                { isApplicant: true },
                { employeeId: allEmployee[i].id },
                { AdmnistratorId: req.session.admin.id }
            ]
        }})
        
        if(result && canApplicant ) {
            let employee = allEmployee[i]           
            let fonction = await FunctionController.getFunctionEmployee(employee.id);
            if(fonction) {
                employee.fonction = fonction.nameFunction;
            }
            else {
                employee.fonction = '';
            }
            employee.solde = result.totalVacation
            employees.push(employee);
        }                
    }                   
    res.render('pages/forms/vacation', { employees, errors, req});
})

router.post('/demand',
    authentification, 
    body('id').notEmpty(),
    body('matricule').notEmpty(),
    body('name').notEmpty(),
    body('solde').notEmpty(),
    body('start_date').notEmpty(),
    body('end_date').notEmpty(),
    VacationController.requestVacation
);

//  Seul les entiers sont autoriser sur cet parametre
// Params: id vacation
router.get('/:id(\\d+)', authentification, async (req, res) => {
    let errors = null;
    let id = req.params.id;
    let vacation = await VacationModel.findOne({ where: {id: id}});
    if(!vacation) {
        return res.redirect('/');
    }

    //  
    let employee = await db.employee.findOne({ where: { id: vacation.employeeId }});
    if(!employee) {
        return res.redirect('/');
    }    

    //  Ancien congee
    let prevVacation = await VacationModel.findAll({
        where: {
            [Op.and]: [
                { employeeId: employee.id },
                { createdAt : { [Op.lt] : vacation.createdAt }}
            ]            
        },
        order: [['createdAt', 'DESC'],['endDate', 'DESC']],
        limit: 1
      });            
    vacation.oldVacation = prevVacation[0].totalVacation;
    

    //  Interimaire
    if(vacation.interimId) {
        let interim = await db.employee.findOne({ where: { id: vacation.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;
    }

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

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

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

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

    //  Trouver le validateur
    let validateur = await db.admin.findOne({ where: { id: vacation.AdmnistratorId }});
    if(validateur) {                    
        vacation.validateur = validateur;
        vacation.isConfirmed = (vacation.validateur.id > 0) ? true : false;
    }        
    vacation.nbrDays = VacationController.nbrDaysBetweenDates(vacation.startDate, vacation.endDate);
    // heure de départ et de fin 
    let timeToDay = {
      "MT":0.5,
      "MD": 0,
      "SR": 0.5,
    }

    vacation.nbrDays += timeToDay[vacation.startHour] + timeToDay[vacation.endHour];    
    if(vacation) {
        res.render('pages/forms/vacationEdit', {         
            employee,
            vacation,            
            errors,
            req 
        })
    }
});


router.post('/:id(\\d+)', 
    authentification, 
    body('id').notEmpty(),
    body('matricule').notEmpty(),
    body('name').notEmpty(),
    body('solde').notEmpty(),
    body('start_date').notEmpty(),
    body('end_date').notEmpty(),
    VacationController.updateVacation
);

router.post('/reject', authentification, VacationController.reject);

router.delete('/reject/:id(\\d+)', authentification, async (req, res) => {
    const ID = req.params.id;    

    //  CONGE
    let rejected = await db.vacationRejected.findByPk(ID);
    console.log(rejected);
    if (rejected) {
        console.log("kkkkkkkk");
        await rejected.destroy();
        return res.json({ message: "success" });
    }
    
    //  permission
    rejected = await db.permissionRejected.findByPk(ID);
    if (rejected) {
        await rejected.destroy();
        return res.json({ message: "success" });
    }

    //  medical
    rejected = await db.medicalRejected.findByPk(ID);
    if (rejected) {
        await rejected.destroy();
        return res.json({ message: "success" });
    }

    return res.json({message: "done"});
    
})

router.get('/planning', authentification,(req, res) => {
    res.render('pages/admin/planning', { req })
})

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,
            vacationId: req.body.vacationId
        }

        // 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 vacationId = req.body.vacationId;                              
        res.redirect(`/vacation/${vacationId}`);
    });

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

        let vacation = await db.vacation.findByPk(passingFile.vacationId);
        if(vacation) {
            var { startDate, endDate } = vacation;
        }
        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,
        });        
        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",
        });
        let filepath = path.resolve(__dirname, "../public/files/fiche.docx");
        fs.writeFileSync(filepath, buf);
        res.download(filepath, () => {
            console.log('telechargement....')
            fs.unlinkSync(filepath);
        })        

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

router.delete('/delete-passing-file/:id(\\d+)', async (req, res) => {
    let id = req.params.id;
    let passFile = await db.passingFile.findByPk(id);
    if(passFile) {

        await db.personnel.destroy({ where: {
            passingFileId: passFile.id
        }});

        await db.material.destroy({ where: {
            passingFileId: passFile.id
        }});

        await db.task.destroy({ where: {
            passingFileId: passFile.id
        }});

        await db.signature.destroy({ where: {
            passingFileId: passFile.id
        }});
        await passFile.destroy();
    }
    res.status(200).json({ message: "success"});
})

router.get('/saisi/:id(\\d+)', authentification, async (req, res) => {
     let errors = null;
     let employees = [];          
    //  Trouver tout les emplo
    var allEmployee = await EmployeeModel.findAll();   
    const employee = await db.employee.findByPk(req.params.id);
    employees = allEmployee;    
    res.render('pages/forms/vacationSaisi', { employees, employee, errors, req});
})

router.post('/saisi', authentification, async (req, res) => {
    let {start, start_hour, end, end_date, id, solde } = req.body;
    solde = solde.replace(',','.');       
    await VacationModel.create({
        totalVacation: solde,
        startDate: start ? start : null,
        startHour: start_hour, 
        endDate: end,
        endHour: end_date,
        applicantId: 2,
        createdAt: start ? start : end,
        updatedAt: start ? start : end,
        employeeId: id,
        AdmnistratorId: 2
    })
    res.redirect(`/vacation/historic/${id}`);
})

router.post('/planning/add', authentification, VacationController.saveOnePlanning);
router.post('/planning/edit/:id(\\d+)', authentification, VacationController.editOnePlanning);

router.get('/historic/:idEmployee(\\d+)', authentification, VacationController.historiquePerso);
router.delete('/:id(\\d+)', authentification, async (req, res) => {
    const ID = req.params.id;
    // verifier
    const vacation = await db.vacation.findByPk(ID);
    if (!vacation) return 0;

    await vacation.destroy();
    return res.send();
})

router.post('/edit/:idEmployee(\\d+)', authentification, async (req, res) => {
    const ID = req.body.id;
    const employee = await db.employee.findByPk(req.params.idEmployee);
    // return res.json(req.params);
    //  Verifier
    const vacation = await db.vacation.findByPk(ID);
    if (!vacation || !employee) return res.redirect('/');

    await vacation.update(req.body);
    return res.redirect(`/vacation/historic/${employee.id}`);

})

module.exports = router;