const express = require('express');
const router = express.Router();
const db = require('../config/db');


// ...


// ...


router.get('/correlativos-documentos', async function(req, res) {
    try {
        var buscar = req.query.buscar || '';
        var page = req.query.page !== undefined ? parseInt(req.query.page) : 1;
        var limit = req.query.limit !== undefined ? parseInt(req.query.limit) : 50;
        var sinPaginacion = limit <= 0;
        var sort = req.query.sort || 'td.codigo';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var idEmpresa = parseInt(req.query.id_empresa) || 0;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var filtros = {};
        try {
            if (req.query.filtros) filtros = JSON.parse(req.query.filtros);
        } catch(e) {}

        var where = ' WHERE cd.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };
        if (req.query.id_sucursal) {
            where += ' AND cd.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }
        if (buscar) {
            where += ' AND (td.codigo LIKE @buscar OR td.nombre LIKE @buscar OR cd.serie LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }
        if (filtros.tipo_doc_codigo) {
            var vals = filtros.tipo_doc_codigo.split('\x01').map(function(v) { return v.trim(); });
            var placeholders = vals.map(function(_, i) { return '@fcodigo' + i; }).join(',');
            vals.forEach(function(v, i) { params['fcodigo' + i] = { type: db.sql.VarChar(10), value: v }; });
            where += ' AND td.codigo IN (' + placeholders + ')';
        }
        if (filtros.tipo_doc_nombre) {
            var vals = filtros.tipo_doc_nombre.split('\x01').map(function(v) { return v.trim(); });
            var placeholders = vals.map(function(_, i) { return '@fnombre' + i; }).join(',');
            vals.forEach(function(v, i) { params['fnombre' + i] = { type: db.sql.NVarChar(100), value: v }; });
            where += ' AND td.nombre IN (' + placeholders + ')';
        }
        if (filtros.serie) {
            var vals = filtros.serie.split('\x01').map(function(v) { return v.trim(); });
            var placeholders = vals.map(function(_, i) { return '@fserie' + i; }).join(',');
            vals.forEach(function(v, i) { params['fserie' + i] = { type: db.sql.VarChar(4), value: v }; });
            where += ' AND cd.serie IN (' + placeholders + ')';
        }
        if (filtros.numero_actual) {
            var vals = filtros.numero_actual.split('\x01').map(function(v) { return v.trim(); });
            var placeholders = vals.map(function(_, i) { return '@fnumero' + i; }).join(',');
            vals.forEach(function(v, i) { params['fnumero' + i] = { type: db.sql.VarChar(7), value: v }; });
            where += ' AND cd.numero_actual IN (' + placeholders + ')';
        }
        if (filtros.usuario_nombre) {
            var vals = filtros.usuario_nombre.split('\x01').map(function(v) { return v.trim(); });
            var placeholders = vals.map(function(_, i) { return '@fusuario' + i; }).join(',');
            vals.forEach(function(v, i) { params['fusuario' + i] = { type: db.sql.NVarChar(100), value: v }; });
            where += ' AND u.usuario IN (' + placeholders + ')';
        }

        var allowedSort = { codigo: 'td.codigo', nombre: 'td.nombre', serie: 'cd.serie', numero_actual: 'cd.numero_actual' };
        var sortCol = allowedSort[sort] || 'td.codigo';

        var joins = ' FROM correlativos_documentos cd INNER JOIN sunat_tipos_doc td ON cd.id_empresa = td.id_empresa AND cd.id_tipo_doc = td.id_tipo_doc LEFT JOIN usuarios u ON cd.id_empresa = u.id_empresa AND cd.id_usuario = u.id_usuario';
        var selectCols = 'cd.id_correlativo, cd.id_tipo_doc, cd.id_empresa, cd.serie, cd.numero_actual, cd.id_usuario, u.usuario AS usuario_nombre, td.codigo AS tipo_doc_codigo, td.nombre AS tipo_doc_nombre, cd.id_sucursal';
        var sqlCount = 'SELECT COUNT(*) as total' + joins + ' ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        if (sinPaginacion) {
            var sqlData = 'SELECT ' + selectCols + joins + ' ' + where + ' ORDER BY ' + sortCol + ' ' + order;
            var data = await db.query(sqlData, params);
            return res.json({ ok: true, data: data, total: total, totalPaginas: totalPaginas, page: page });
        }

        var offset = (page - 1) * limit;
        var sqlData = 'SELECT ' + selectCols + joins + ' ' + where + ' ORDER BY ' + sortCol + ' ' + order + ' OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY';
        params.offset = { type: db.sql.Int, value: offset };
        params.limit = { type: db.sql.Int, value: limit };
        var data = await db.query(sqlData, params);
        res.json({ ok: true, data: data, total: total, totalPaginas: totalPaginas, page: page });
    } catch (error) {
        console.error('[CORRELATIVOS] Error listar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al listar correlativos' });
    }
});

router.get('/correlativos-documentos/asignado/:id_usuario/:id_tipo_doc', async function(req, res) {
    try {
        var idUsuario = parseInt(req.params.id_usuario);
        var idTipoDoc = parseInt(req.params.id_tipo_doc);
        var idEmpresa = parseInt(req.query.id_empresa) || 0;

        var data = await db.query(
            'SELECT cd.id_correlativo, cd.id_tipo_doc, cd.id_empresa, cd.serie, cd.numero_actual, cd.id_usuario FROM correlativos_documentos cd WHERE cd.id_tipo_doc = @id_tipo_doc AND cd.id_empresa = @id_empresa AND cd.id_usuario = @id_usuario',
            {
                id_tipo_doc: { type: db.sql.Int, value: idTipoDoc },
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                id_usuario: { type: db.sql.Int, value: idUsuario }
            }
        );
        if (data.length === 0) return res.json({ ok: true, data: null, mensaje: 'No hay correlativo asignado al usuario' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[CORRELATIVOS] Error obtener asignado:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al obtener correlativo asignado' });
    }
});

router.post('/correlativos-documentos/incrementar/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var idEmpresa = parseInt(req.body.id_empresa) || parseInt(req.query.id_empresa) || 0;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var result = await db.query(
            "UPDATE correlativos_documentos SET numero_actual = RIGHT(REPLICATE('0', 7) + CAST(CAST(numero_actual AS INT) + 1 AS VARCHAR(7)), 7) OUTPUT INSERTED.id_correlativo, INSERTED.id_tipo_doc, INSERTED.id_empresa, INSERTED.serie, INSERTED.numero_actual, INSERTED.id_usuario WHERE id_empresa = @id_empresa AND id_correlativo = @id",
            { id_empresa: { type: db.sql.Int, value: idEmpresa }, id: { type: db.sql.Int, value: id } }
        );
        if (result.length === 0) return res.status(404).json({ ok: false, mensaje: 'Correlativo no encontrado' });
        // MySQL adapter cannot return OUTPUT columns for UPDATE — re-read if needed
        if (result[0].id_correlativo === null) {
            result = await db.query(
                'SELECT id_correlativo, id_tipo_doc, id_empresa, serie, numero_actual, id_usuario FROM correlativos_documentos WHERE id_correlativo = @id AND id_empresa = @id_empresa',
                { id: { type: db.sql.Int, value: id }, id_empresa: { type: db.sql.Int, value: idEmpresa } }
            );
            if (result.length === 0) return res.status(404).json({ ok: false, mensaje: 'Correlativo no encontrado' });
        }
        res.json({ ok: true, data: result[0], mensaje: 'Correlativo incrementado' });
    } catch (error) {
        console.error('[CORRELATIVOS] Error incrementar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al incrementar correlativo' });
    }
});

router.get('/correlativos-documentos/:id', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.query.id_empresa) || 0;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var data = await db.query(
            'SELECT cd.id_correlativo, cd.id_tipo_doc, cd.id_empresa, cd.serie, cd.numero_actual, cd.id_usuario, u.usuario AS usuario_nombre, td.codigo AS tipo_doc_codigo, td.nombre AS tipo_doc_nombre, cd.id_sucursal FROM correlativos_documentos cd INNER JOIN sunat_tipos_doc td ON cd.id_empresa = td.id_empresa AND cd.id_tipo_doc = td.id_tipo_doc LEFT JOIN usuarios u ON cd.id_empresa = u.id_empresa AND cd.id_usuario = u.id_usuario WHERE cd.id_empresa = @id_empresa AND cd.id_correlativo = @id',
            { id_empresa: { type: db.sql.Int, value: idEmpresa }, id: { type: db.sql.Int, value: parseInt(req.params.id) } }
        );
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Correlativo no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[CORRELATIVOS] Error obtener:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al obtener correlativo' });
    }
});

router.post('/correlativos-documentos', async function(req, res) {
    try {
        var idTipoDoc = parseInt(req.body.id_tipo_doc);
        var idEmpresa = parseInt(req.body.id_empresa);
        var serie = (req.body.serie || '').trim().toUpperCase();
        var numeroActual = (req.body.numero_actual || '').toString().replace(/[^0-9]/g, '') || '0';
        var idUsuario = req.body.id_usuario ? parseInt(req.body.id_usuario) : null;

        if (!idTipoDoc) return res.status(400).json({ ok: false, mensaje: 'El tipo de documento es requerido' });
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'La empresa es requerida' });
        if (!serie) return res.status(400).json({ ok: false, mensaje: 'La serie es requerida' });
        if (numeroActual === '0') return res.status(400).json({ ok: false, mensaje: 'El número actual no puede ser 0' });
        if (numeroActual.length > 7) return res.status(400).json({ ok: false, mensaje: 'El número actual no puede tener más de 7 dígitos' });

        var dup = await db.query(
            'SELECT COUNT(*) as cnt FROM correlativos_documentos WHERE id_tipo_doc = @id_tipo_doc AND id_empresa = @id_empresa AND serie = @serie AND (id_usuario = @id_usuario OR (id_usuario IS NULL AND @id_usuario IS NULL))',
            {
                id_tipo_doc: { type: db.sql.Int, value: idTipoDoc },
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                serie: { type: db.sql.VarChar(4), value: serie },
                id_usuario: { type: db.sql.Int, value: idUsuario }
            }
        );
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'Ya existe un correlativo para esta serie, empresa y usuario' });
        }

        var result = await db.query(
            'INSERT INTO correlativos_documentos (id_tipo_doc, id_empresa, id_sucursal, serie, numero_actual, id_usuario) VALUES (@id_tipo_doc, @id_empresa, @id_sucursal, @serie, @numero_actual, @id_usuario); SELECT SCOPE_IDENTITY() as id',
            {
                id_tipo_doc: { type: db.sql.Int, value: idTipoDoc },
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null },
                serie: { type: db.sql.VarChar(4), value: serie },
                numero_actual: { type: db.sql.VarChar(7), value: numeroActual },
                id_usuario: { type: db.sql.Int, value: idUsuario }
            }
        );
        res.json({ ok: true, mensaje: 'Correlativo registrado', data: { id_correlativo: result[0].id } });
    } catch (error) {
        console.error('[CORRELATIVOS] Error crear:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar correlativo' });
    }
});

router.put('/correlativos-documentos/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var idTipoDoc = parseInt(req.body.id_tipo_doc);
        var idEmpresa = parseInt(req.body.id_empresa);
        var serie = (req.body.serie || '').trim().toUpperCase();
        var numeroActual = (req.body.numero_actual || '').toString().replace(/[^0-9]/g, '') || '0';
        var idUsuario = req.body.id_usuario ? parseInt(req.body.id_usuario) : null;

        if (!idTipoDoc) return res.status(400).json({ ok: false, mensaje: 'El tipo de documento es requerido' });
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'La empresa es requerida' });
        if (!serie) return res.status(400).json({ ok: false, mensaje: 'La serie es requerida' });
        if (numeroActual === '0') return res.status(400).json({ ok: false, mensaje: 'El número actual no puede ser 0' });
        if (numeroActual.length > 7) return res.status(400).json({ ok: false, mensaje: 'El número actual no puede tener más de 7 dígitos' });

        var dup = await db.query(
            'SELECT COUNT(*) as cnt FROM correlativos_documentos WHERE id_tipo_doc = @id_tipo_doc AND id_empresa = @id_empresa AND serie = @serie AND (id_usuario = @id_usuario OR (id_usuario IS NULL AND @id_usuario IS NULL)) AND id_correlativo != @id',
            {
                id_tipo_doc: { type: db.sql.Int, value: idTipoDoc },
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                serie: { type: db.sql.VarChar(4), value: serie },
                id_usuario: { type: db.sql.Int, value: idUsuario },
                id: { type: db.sql.Int, value: id }
            }
        );
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'Ya existe un correlativo para esta serie, empresa y usuario' });
        }

        await db.execute(
            'UPDATE correlativos_documentos SET id_tipo_doc = @id_tipo_doc, serie = @serie, numero_actual = @numero_actual, id_usuario = @id_usuario, id_sucursal = @id_sucursal WHERE id_empresa = @id_empresa AND id_correlativo = @id',
            {
                id_tipo_doc: { type: db.sql.Int, value: idTipoDoc },
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null },
                serie: { type: db.sql.VarChar(4), value: serie },
                numero_actual: { type: db.sql.VarChar(7), value: numeroActual },
                id_usuario: { type: db.sql.Int, value: idUsuario },
                id: { type: db.sql.Int, value: id }
            }
        );
        res.json({ ok: true, mensaje: 'Correlativo actualizado' });
    } catch (error) {
        console.error('[CORRELATIVOS] Error actualizar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar correlativo' });
    }
});

router.delete('/correlativos-documentos/:id', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.query.id_empresa) || 0;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        await db.execute('DELETE FROM correlativos_documentos WHERE id_empresa = @id_empresa AND id_correlativo = @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        res.json({ ok: true, mensaje: 'Correlativo eliminado' });
    } catch (error) {
        console.error('[CORRELATIVOS] Error eliminar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar correlativo' });
    }
});

module.exports = router;
