//const pdf = require('html-pdf');

const db = require("../models");
const model = db.factura;
const cliente = db.cliente;
const detalle = db.detalle;
const Op = db.Sequelize.Op;
const util = require("./util");

exports.get = async function (req, res) {

    var query = `select a.id_factura, b.nit, b.nombre, DATE_FORMAT(a.createdAt, '%d/%m/%Y %T')  as fecha, format(a.total, 2) as total, 
                a.estado, upper(c.usuario) as usuario,  
                case 
                    when a.estado = 1 then 'ACTIVA'
                    when a.estado = 2 then 'ANULADA'
                end as estatus,
                case
                    when a.estado = 1 then ''
                    when a.estado = 2 then DATE_FORMAT(a.updatedAt, '%d/%m/%Y %T')
                end as confirmacion
                from factura a
                inner join cliente b on a.id_cliente = b.id_cliente
                inner join usuario c on a.id_usuario = c.id_usuario `;

    const id = req.params.id;

    if (id) query += ` where id_factura = '${id}'  `;
    query += " order by a.id_factura desc";

    await db.sequelize.query(query, { type: db.sequelize.QueryTypes.SELECT })
        .then(data => {
            return res.send({ mensaje: data, perfil: req.session.perfil });
        }).catch(err => {
            res.status(500).send({ message: err.message || "Some error occurred while retrieving tutorials." });
        });

}

exports.findById = async function (req, res) {

    let id = req.params.id;
    await model.findAll({
        where: { id: id }
    })
};

exports.post = async function (req, res) {

    if (!req.body.idCliente) return res.send({ error: "ingrese cliente" });
    if (!req.body.detalles) return res.send({ error: "ingrese productos" });
    if (!req.body.total) return res.send({ error: "ingrese total" });
    if (!req.body.tipo) return res.send({ error: "ingrese tipo" });

    var j = 0;
    var error = "";
    var detalles = req.body.detalles;
    var idCliente = req.body.idCliente;
    var control = getRandomInt(100000, 200000000);
    const t = await db.sequelize.transaction();

    try {

        var existencias = [];

        for (var key in detalles) {
            var dto = detalles[key];
            existencias.push(dto.id);
        }

        var ids = existencias.join();

        var query = `select group_concat(a.id_producto) as ids, replace(group_concat( concat(b.nombre, ' ', a.nombre)), ',', ', ')as agotados
                    from producto a
                    inner join envase b on a.id_envase = b.id_envase 
                    where existencia = 0
                    and id_producto in(${ids})`;

        var real = await cliente.sequelize.query(query, { type: db.sequelize.QueryTypes.SELECT })
            .then(data => {
                return data[0];
            });

        if (real.agotados != null) {
            await t.rollback();
            return res.send({ mensaje: "fallida", error: "Los siguientes productos están agotados: " + real.agotados, agotados: real.ids });
        }

        query = `select 
                    case when count(*) = 0 then 1 else 2 end as tipo
                    from cliente 
                    where upper(nit) = upper('cf')
                    and id_cliente = ` + idCliente;

        var registro = await cliente.sequelize.query(query, { type: db.sequelize.QueryTypes.SELECT })
            .then(data => {
                return data[0];
            });


        var datos = {
            id_cliente: idCliente,
            total: req.body.total,
            estado: 1,
            control: control,
            tipo: registro.tipo,
            autorizacion: "",
        };

        var salida = await GenerateHash(datos);

        //if (salida.error != "") throw salida.error;

        var factura = await model.create({
            id_cliente: idCliente,
            total: req.body.total,
            estado: 1,
            control: control,
            tipo: registro.tipo,
            autorizacion: salida,
            id_usuario: req.session.id_usuario
        }, { transaction: t });

        for (var key in detalles) {
            var dto = detalles[key];

            await detalle.create({
                id_factura: factura.id_factura,
                id_producto: dto.id,
                cantidad: dto.cantidad,
                precio: dto.precio,
                sub_total: dto.subtotal,
                estado: 1
            }, { transaction: t });

            query = `update producto set existencia = existencia - ${dto.cantidad} where id_producto = ` + dto.id;
            db.sequelize.query(query, { type: db.sequelize.QueryTypes.update }, { transaction: t });

            j++;
        }

        await t.commit();

    } catch (err) {
        error = err.message;
        console.log(error);
        await t.rollback();
    }

    if (j > 0)
        return res.send({ mensaje: "exitosa", error: "", id: factura.id_factura, agotados: [] });
    else
        return res.send({ mensaje: "fallida", error: error, agotados: [] });

};


function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}


function writeTxt() {

    // specify the path to the file, and create a buffer with characters we want to write
    let path = './assets/ghetto_gospel.txt';
    let buffer = new Buffer('Those who wish to follow me\nI welcome with my hands\nAnd the red sun sinks at last', 'utf-8');

    // open the file in writing mode, adding a callback function where we do the actual writing
    fs.open(path, 'w', function (err, fd) {
        if (err) {
            throw 'could not open file: ' + err;
        }

        // write the contents of the buffer, from position 0 to the end, to the file descriptor returned in opening our file
        fs.write(fd, buffer, 0, buffer.length, null, function (err) {
            if (err) throw 'error writing file: ' + err;
            fs.close(fd, function () {
                console.log('wrote the file successfully');
            });
        });
    });

}


exports.put = async function (req, res) {

    if (!req.body.nit) return res.send({ error: "ingrese nit" });
    if (!req.body.nombre) return res.send({ error: "ingrese nombre" });
    if (!req.body.telefono) return res.send({ error: "ingrese telefono" });
    if (!req.body.direccion) return res.send({ error: "ingrese direccion" });
    if (!req.body.email) return res.send({ error: "ingrese email" });
    if (!req.body.id) return res.send({ error: "ingrese id" });

    const id = req.body.id;
    var nit = req.body.nit;
    var condition = nit ? { nit: { [Op.like]: `%${nit}%` }, id_cliente: { [Op.not]: id } } : null;

    var registros = await model.findAll({ where: condition })
        .then(data => {
            return data.length;
        })
        .catch(err => {
            return res.status(500).send({ message: err.message || "Some error occurred while retrieving tutorials." });
        });

    if (registros > 0)
        return res.send({ error: "ya existe cliente con ese nit" });

    await model.update(
        {
            nit: req.body.nit,
            nombre: req.body.nombre.toUpperCase(),
            telefono: req.body.telefono,
            direccion: req.body.direccion,
            email: req.body.email,
            estado: req.body.estado,
            id_usuario: req.session.id_usuario
        },
        {
            where: { id_cliente: id }
        }
    )
        .then(data => {
            res.send({ mensaje: "Registro actualizado exitosamente", error: "" });
        })
        .catch(err => {
            res.send(err);
        })
};


exports.delete = async function (req, res) {

    if (!req.body.id) return res.send({ error: "ingrese id" });
    let id = req.body.id;

    await model.destroy({
        where: { id_cliente: id }
    })
        .then(data => {
            res.status(200).send({ mensaje: "Registro elimiando exitosamente", error: "" });
        })
        .catch(err => {
            res.send(err);
        })
};



exports.download = async function (req, res) {

    if (!req.body.id) return res.send({ error: "ingrese id" });
    if (isNaN(req.body.id)) return res.send({ error: "ingrese valor numúmerico en id " + req.body.id });

    try {

        let id = req.body.id;
        var fs = require('fs');
        let ejs = require('ejs');

        //'%d/%m/%Y %h:%m:%s'

        var query = `select a.id_factura as id, b.nit, b.nombre, b.direccion, DATE_FORMAT(a.createdAt, '%d/%m/%Y %T')  as fecha, format(a.total, 2) as total, 
                    a.autorizacion, a.control, DATE_FORMAT(a.updatedAt, '%d/%m/%Y %T')  as confirmacion,
                    case
                        when a.estado = 1 then 'ACTIVA'
                        when a.estado = 2 then 'ANULADA'
                    end as estatus
                    from factura a
                    inner join cliente b on a.id_cliente = b.id_cliente
                    where id_factura = '${id}' `;

        var datos = await db.sequelize.query(query, { type: db.sequelize.QueryTypes.SELECT })
            .then(data => {
                return data[0];
            }).catch(err => {
                return null;
            });

        query = `select c.id_producto, b.cantidad as cantidad, concat(c.nombre, ' ', d.nombre) as descripcion, format(b.precio, 2) as precio, format(b.sub_total, 2)  as subtotal
            from factura a
            inner join detalle b on a.id_factura = b.id_factura
            inner join producto c on b.id_producto = c.id_producto
            inner join envase d on d.id_envase = c.id_envase
            where a.id_factura = '${id}' `;

        var detalles = await db.sequelize.query(query, { type: db.sequelize.QueryTypes.SELECT })
            .then(data => {
                return data;
            }).catch(err => {
                return null;
            });


        query = `select * from perfil `;

        var perfil = await db.sequelize.query(query, { type: db.sequelize.QueryTypes.SELECT })
            .then(data => {
                return data[0];
            }).catch(err => {
                return null;
            });

        if (perfil == null)
            return res.send({ error: "Ingrese configuración de factura" });

        if (perfil.logo == null)
            return res.send({ error: "Ingrese logo en configuración de factura" });

        var template = "./templates/factura.html";
        let logo = "./public" + perfil.logo;
        let base64 = fs.readFileSync(logo, { encoding: 'base64' });

        //var url =  "http://bwipjs-api.metafloor.com/?bcid=qrcode&text=https://nivel.openfox.org/qr/?id=3?el=1254787";
        //var qr = "http://bwipjs-api.metafloor.com/?bcid=qrcode&text=" + encodeURI(req.protocol + '://' + req.get('host') + '/qr?id=' + datos.id + '-' + datos.control);

        var url = encodeURI(req.protocol + '://' + req.get('host') + '/qr?id=' + datos.id + '-' + datos.control);
        var qr = await util.GenerarQR(url);

        var empresa = {
            nombre: perfil.nombre,
            direccion: perfil.direccion,
            slogan: perfil.slogan,
            logo: "data:image/jpeg;base64," + base64,
            tamanio: perfil.tamanio,
            qr: qr
        };

        var encabezado = {
            id: datos.id,
            factura: "FACTURA " + datos.id,
            fecha: datos.fecha,
            nombre: datos.nombre,
            nit: datos.nit,
            direccion: datos.direccion,
            total: "TOTAL Q " + datos.total,
            certificado: datos.autorizacion,
            estatus: datos.estatus,
            confirmacion: datos.confirmacion
        };

         var html = await ejs.renderFile(template, { empresa: empresa, encabezado: encabezado, detalle: detalles }, { async: true });
        //var salida = await util.generatePDF(html);
        var nombre = "factura-" + id + ".pdf";
        return res.send({ error: "", html: html, nombre: nombre });
        //return res.send({ nombre: nombre, error: salida.error, base64: salida.base64 });
        //return res.send({ error: "", base64: buffer.toString('base64'), nombre: nombre });

    } catch (err) {
        return res.send({ error: err.message });
    }
};


// async function generatePDF(html) {

//     const pdf = require("html-pdf");

//     return new Promise((resolve, reject) => {
//         try {
//             const options = {
//                 format: 'Letter',
//                 timeout: 30000
//             };

//             pdf.create(html, options).toBuffer((err, buffer) => {
//                 if (err) {
//                     reject(err);
//                 } else {
//                     const base64 = buffer.toString('base64');
//                     resolve(base64);
//                 }
//             });
//         } catch (err) {
//             reject(err);
//         }
//     });
// }






// async function generatePDF(htmlContent) {
//     try {
//         const browser = await puppeteer.launch({
//             //headless: true, // Modo headless (sin interfaz gráfica)
//             args: ['--no-sandbox', '--disable-setuid-sandbox'], // Opciones adicionales para contenedores
//             headless: "new"
//         });

//         // const browser = await puppeteer.launch({
//         //     headless: "new",
//         //     args: ['--enable-gpu'],
//         //   });

//         const page = await browser.newPage();

//         // Establecer el contenido HTML de la página
//         await page.setContent(htmlContent);

//         // Generar el PDF y obtener el contenido en formato de buffer
//         const pdfBuffer = await page.pdf({ format: 'letter' });

//         // Cerrar el navegador
//         await browser.close();

//         return pdfBuffer;
//     } catch (error) {
//         console.error('Error generando el PDF:', error);
//         throw error;
//     }
// }



// async function generatePDF(htmlContent) {
//     const browser = await puppeteer.launch({ headless: "new" });
//     const page = await browser.newPage();

//     // Establecer el contenido HTML de la página
//     await page.setContent(htmlContent);

//     // Generar el PDF y obtener el contenido en formato de buffer
//     const pdfBuffer = await page.pdf({ format: 'letter' });

//     // Cerrar el navegador
//     await browser.close();

//     return pdfBuffer;
// }


exports.cancel = async function (req, res) {

    if (!req.body.id) return res.send({ error: "ingrese id" });
    if (isNaN(req.body.id)) return res.send({ error: "ingrese valor numúmerico en id: " + req.body.id });

    var id = req.body.id;

    var registro = await model.findAll({ where: { id_factura: id } })
        .then(data => {
            return data[0];
        })
        .catch(err => {
            return res.status(500).send({ message: err.message || "Some error occurred while retrieving tutorials." });
        });

    if (registro == null)
        return res.send({ error: "No existe factura con ese identificador" });

    var mensaje = "";
    var error = "";

    var salida = await CertificarFactura(registro);

    if (salida.error != "") return res.send({ mensaje: mensaje, error: salida.error });

    await model.update(
        {
            estado: 2
        },
        {
            where: { id_factura: id }
        }
    )
        .then(data => {
            res.send({ mensaje: "Registro actualizado exitosamente", error: "" });
        })
        .catch(err => {
            res.send({ mensaje: "", error: err.message });
        })
}


async function CertificarFactura(info) {

    //console.log(info);

    //var buff = Buffer.from(JSON.stringify({"hello":"world"})).toString("base64");
    //var kk = Buffer.from(info).toString("base64");
    var salida = { error: "", base64: "" };

    try {

        salida.base64 = `Autorizado según resolucion 1054-2020 SAT Autorización 54787-2020 Certificador: XXXXXX S.A. Firma Electronica:
                dodujd98e7opeoeihdiue849ddfdfderefyhsirirru545ekdidsydhdoldpdorideieurorp77==`;

    } catch (err) {
        salida.error = err.mensaje;
    }

    return salida;
}


async function GenerateHash(obj1) {
    const jsonString = JSON.stringify(obj1);
    var hash = require('crypto').createHash('sha256').update(jsonString, 'utf8').digest('hex');
    return `Autorizado según resolucion 1054-2020 SAT Autorización 54787-2020 Certificador: XXXXXX S.A. Firma Electronica: ${hash}`;
}



async function AnularFactura(info) {

    //console.log(info);

    //var buff = Buffer.from(JSON.stringify({"hello":"world"})).toString("base64");
    //var kk = Buffer.from(info).toString("base64");
    var salida = { error: "", base64: "" };

    try {

        salida.base64 = `Autorizado según resolucion 1054-2020 SAT Autorización 54787-2020 Certificador: XXXXXX S.A. Firma Electronica:
                dodujd98e7opeoeihdiue849ddfdfderefyhsirirru545ekdidsydhdoldpdorideieurorp77==`;

    } catch (err) {
        salida.error = err.mensaje;
    }

    return salida;
}
