const express = require('express');
const router = express.Router();
const db = require('../config/db');
const multer = require('multer');
const dh = require('./distinctHelper');
const path = require('path');

var storageLogo = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, path.join(__dirname, '../../Frontend/img/logos'));
    },
    filename: function(req, file, cb) {
        var ext = path.extname(file.originalname).toLowerCase();
        cb(null, 'empresa_' + req.params.id + ext);
    }
});
var uploadLogo = multer({ storage: storageLogo, limits: { fileSize: 2 * 1024 * 1024 }, fileFilter: function(req, file, cb) {
    var allowed = ['.png', '.jpg', '.jpeg', '.gif', '.webp'];
    var ext = path.extname(file.originalname).toLowerCase();
    if (allowed.indexOf(ext) >= 0) cb(null, true);
    else cb(new Error('Solo se permiten imágenes (PNG, JPG, GIF, WebP)'));
}});

var maDbType = (process.env.DB_TYPE || process.env.MODO_ERP || 'mssql').toLowerCase();
var maIsWeb = maDbType === 'mysql' || maDbType === 'web';

// Función auxiliar para sanitizar columna de orden (evita SQL injection)
function columnaValida(col, permitidas) {
    return permitidas.indexOf(col) >= 0 ? col : null;
}

// ============================================================
// BANCOS
// ============================================================

router.get('/bancos', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_banco', 'nombre', 'estado']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE b.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (req.query.id_sucursal) {
            where += ' AND b.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }

        if (buscar) {
            where += ' AND (b.cod_banco LIKE @buscar OR b.nombre LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND b.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND b.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'bancos', alias: 'b', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM bancos b' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT b.id_banco, b.id_sucursal, b.cod_banco, b.nombre, b.estado FROM bancos b' + where + ' ORDER BY b.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT b.id_banco, b.id_sucursal, b.cod_banco, b.nombre, b.estado FROM bancos b' + where + ' ORDER BY b.' + sort + ' ' + 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('[MAESTRAS] Error bancos:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar bancos' });
    }
});

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

        var data = await db.query('SELECT id_banco, id_sucursal, cod_banco, nombre, estado FROM bancos WHERE id_empresa = @id_empresa AND id_banco = @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: 'Banco no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error banco:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar banco' });
    }
});

router.post('/bancos', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var dup = await db.query('SELECT COUNT(*) as cnt FROM bancos WHERE id_empresa = @id_empresa AND cod_banco = @cod', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(4), value: req.body.cod_banco }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de banco ya existe' });
        }
        var idSucursal = req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null;
        var sql = 'INSERT INTO bancos (id_empresa, id_sucursal, cod_banco, nombre, estado) VALUES (@id_empresa, @id_sucursal, @cod_banco, @nombre, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id_sucursal: { type: db.sql.Int, value: idSucursal },
            cod_banco: { type: db.sql.NVarChar(4), value: req.body.cod_banco },
            nombre: { type: db.sql.NVarChar(200), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Banco registrado', data: { id_banco: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear banco:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar banco' });
    }
});

router.put('/bancos/:id', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : (req.query.id_empresa ? parseInt(req.query.id_empresa) : null);
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var dup = await db.query('SELECT COUNT(*) as cnt FROM bancos WHERE id_empresa = @id_empresa AND cod_banco = @cod AND id_banco != @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(4), value: req.body.cod_banco },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de banco ya existe en otro registro' });
        }
        var sql = 'UPDATE bancos SET cod_banco = @cod_banco, nombre = @nombre, estado = @estado, id_sucursal = @id_sucursal WHERE id_empresa = @id_empresa AND id_banco = @id';
        await db.execute(sql, {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            cod_banco: { type: db.sql.NVarChar(4), value: req.body.cod_banco },
            nombre: { type: db.sql.NVarChar(200), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null }
        });
        res.json({ ok: true, mensaje: 'Banco actualizado' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar banco:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar banco' });
    }
});

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

        var ref = await db.query('SELECT COUNT(*) as cnt FROM proveedores WHERE id_empresa = @id_empresa AND id_banco = @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (ref[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'No se puede eliminar: el banco está siendo usado por ' + ref[0].cnt + ' proveedor(es)' });
        }
        await db.execute('DELETE FROM bancos WHERE id_empresa = @id_empresa AND id_banco = @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        res.json({ ok: true, mensaje: 'Banco eliminado' });
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar banco:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar banco' });
    }
});

// ============================================================
// SUNAT CARGOS (catálogo nacional de ocupaciones)
// ============================================================

// ============================================================
// SUNAT CARGOS
// ============================================================
router.get('/sunat-cargos', 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) : 20;
        var sinPaginacion = limit <= 0;
        var sector = req.query.sector || '';
        var sort = columnaValida(req.query.sort, ['codigo', 'nombre']) || 'codigo';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;

        var where = 'WHERE 1=1';
        var params = {};

        if (buscar) {
            where += ' AND (codigo LIKE @buscar OR nombre LIKE @buscar)';
            params.buscar = { type: db.sql.VarChar(100), value: '%' + buscar + '%' };
        }

        if (sector) {
            where += ' AND sector = @sector';
            params.sector = { type: db.sql.VarChar(10), value: sector.toUpperCase() };
        }

        var sqlCount = 'SELECT COUNT(*) as total FROM sunat_cargos ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT id_cargo_sunat, codigo, nombre, sector FROM sunat_cargos ' + where + ' ORDER BY ' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT id_cargo_sunat, codigo, nombre, sector FROM sunat_cargos ' + where + ' ORDER BY ' + sort + ' ' + 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('[MAESTRAS] Error sunat-cargos:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar catálogo SUNAT' });
    }
});

// ============================================================
// CARGOS
// ============================================================

// Asegurar columna cod_sunat en tabla cargos
router.get('/cargos', async function(req, res) {
    if (process.env.MODO_ERP !== 'web') {
        try {
            await db.execute(`
                IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.cargos') AND name = 'cod_sunat')
                ALTER TABLE cargos ADD cod_sunat VARCHAR(10) NULL
            `);
        } catch (_) {}
    }
    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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_cargo', 'nombre', 'estado']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE c.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;
        if (idSucursal) {
            where += ' AND c.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }

        var q = req.query.q || '';
        if (q) buscar = q;

        if (buscar || q) {
            where += ' AND (c.cod_cargo LIKE @buscar OR c.nombre LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + (buscar || q) + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND c.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND c.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'cargos', alias: 'c', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM cargos c' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT c.id_cargo, c.id_sucursal, c.cod_cargo, c.nombre, c.descripcion, c.estado, c.cod_sunat FROM cargos c' + where + ' ORDER BY c.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT c.id_cargo, c.id_sucursal, c.cod_cargo, c.nombre, c.descripcion, c.estado, c.cod_sunat FROM cargos c' + where + ' ORDER BY c.' + sort + ' ' + 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('[MAESTRAS] Error cargos:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar cargos' });
    }
});

router.get('/cargos/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var data = await db.query('SELECT id_cargo, id_empresa, id_sucursal, cod_cargo, nombre, descripcion, estado, cod_sunat FROM cargos WHERE id_cargo = @id AND id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Cargo no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error cargo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar cargo' });
    }
});

router.post('/cargos', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM cargos WHERE cod_cargo = @cod AND id_empresa = @emp', {
            cod: { type: db.sql.NVarChar(10), value: req.body.cod_cargo },
            emp: { type: db.sql.Int, value: parseInt(req.body.id_empresa) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de cargo ya existe para esta empresa' });
        }
        var sql = 'INSERT INTO cargos (id_empresa, id_sucursal, cod_cargo, nombre, descripcion, estado, cod_sunat) VALUES (@id_empresa, @id_sucursal, @cod_cargo, @nombre, @descripcion, @estado, @cod_sunat); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: parseInt(req.body.id_empresa) },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal || null },
            cod_cargo: { type: db.sql.NVarChar(10), value: req.body.cod_cargo },
            nombre: { type: db.sql.NVarChar(100), value: req.body.nombre },
            descripcion: { type: db.sql.NVarChar(200), value: req.body.descripcion || '' },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 },
            cod_sunat: { type: db.sql.VarChar(10), value: req.body.cod_sunat || null }
        });
        res.json({ ok: true, mensaje: 'Cargo registrado', data: { id_cargo: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear cargo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar cargo' });
    }
});

router.put('/cargos/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa || req.body.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM cargos WHERE cod_cargo = @cod AND id_empresa = @emp AND id_cargo != @id', {
            cod: { type: db.sql.NVarChar(10), value: req.body.cod_cargo },
            emp: { type: db.sql.Int, value: parseInt(id_empresa) },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de cargo ya existe para esta empresa' });
        }
        var sql = 'UPDATE cargos SET cod_cargo = @cod_cargo, nombre = @nombre, descripcion = @descripcion, estado = @estado, cod_sunat = @cod_sunat WHERE id_cargo = @id AND id_empresa = @id_empresa';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) },
            cod_cargo: { type: db.sql.NVarChar(10), value: req.body.cod_cargo },
            nombre: { type: db.sql.NVarChar(100), value: req.body.nombre },
            descripcion: { type: db.sql.NVarChar(200), value: req.body.descripcion || '' },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 },
            cod_sunat: { type: db.sql.VarChar(10), value: req.body.cod_sunat || null }
        });
        res.json({ ok: true, mensaje: 'Cargo actualizado' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar cargo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar cargo' });
    }
});

router.delete('/cargos/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM empleados WHERE id_empresa = @id_empresa AND id_cargo = @id), 0) as cnt', { id: { type: db.sql.Int, value: id }, id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) } }); total += r1[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE cargos SET estado = 0 WHERE id_cargo = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'El cargo tiene empleados asignados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM cargos WHERE id_cargo = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'Cargo eliminado' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar cargo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar cargo' });
    }
});

// ============================================================
// CATEGORÍAS PROVEEDOR
// ============================================================

router.get('/categorias-proveedor', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_categoria', 'nombre', 'estado']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var where = ' WHERE cp.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (req.query.id_sucursal) {
            where += ' AND cp.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }

        if (buscar) {
            where += ' AND (cp.cod_categoria LIKE @buscar OR cp.nombre LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND cp.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND cp.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'categorias_proveedor', alias: 'cp', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM categorias_proveedor cp' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT cp.id_categoria, cp.cod_categoria, cp.nombre, cp.estado, cp.id_sucursal FROM categorias_proveedor cp' + where + ' ORDER BY cp.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT cp.id_categoria, cp.cod_categoria, cp.nombre, cp.estado, cp.id_sucursal FROM categorias_proveedor cp' + where + ' ORDER BY cp.' + sort + ' ' + 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('[MAESTRAS] Error categorias:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar categorías' });
    }
});

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

        var data = await db.query('SELECT id_categoria, cod_categoria, nombre, estado, id_sucursal FROM categorias_proveedor WHERE id_empresa = @id_empresa AND id_categoria = @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: 'Categoría no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error categoria:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar categoría' });
    }
});

router.post('/categorias-proveedor', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var dup = await db.query('SELECT COUNT(*) as cnt FROM categorias_proveedor WHERE id_empresa = @id_empresa AND cod_categoria = @cod', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(4), value: req.body.cod_categoria }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de categoría ya existe' });
        }
        var sql = 'INSERT INTO categorias_proveedor (id_empresa, id_sucursal, cod_categoria, nombre, estado) VALUES (@id_empresa, @id_sucursal, @cod_categoria, @nombre, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            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 },
            cod_categoria: { type: db.sql.NVarChar(4), value: req.body.cod_categoria },
            nombre: { type: db.sql.NVarChar(200), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Categoría registrada', data: { id_categoria: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear categoria:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar categoría' });
    }
});

router.put('/categorias-proveedor/:id', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : (req.query.id_empresa ? parseInt(req.query.id_empresa) : null);
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var dup = await db.query('SELECT COUNT(*) as cnt FROM categorias_proveedor WHERE id_empresa = @id_empresa AND cod_categoria = @cod AND id_categoria != @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(4), value: req.body.cod_categoria },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de categoría ya existe en otro registro' });
        }
        var sql = 'UPDATE categorias_proveedor SET cod_categoria = @cod_categoria, nombre = @nombre, estado = @estado, id_sucursal = @id_sucursal WHERE id_empresa = @id_empresa AND id_categoria = @id';
        await db.execute(sql, {
            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 },
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            cod_categoria: { type: db.sql.NVarChar(4), value: req.body.cod_categoria },
            nombre: { type: db.sql.NVarChar(200), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Categoría actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar categoria:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar categoría' });
    }
});

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

        var ref = await db.query('SELECT COUNT(*) as cnt FROM proveedores WHERE id_empresa = @id_empresa AND id_categoria = @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (ref[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'No se puede eliminar: la categoría está siendo usada por ' + ref[0].cnt + ' proveedor(es)' });
        }
        await db.execute('DELETE FROM categorias_proveedor WHERE id_empresa = @id_empresa AND id_categoria = @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        res.json({ ok: true, mensaje: 'Categoría eliminada' });
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar categoria:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar categoría' });
    }
});

// ============================================================
// CONDICIONES PAGO
// ============================================================

router.get('/condiciones-pago', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

var ccCodCon = 'cod_condicion';
var ccNomCon = 'nombre';
var ccDiaCon = 'dias';

        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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, [ccCodCon, ccNomCon, ccDiaCon, 'estado']) || ccDiaCon;
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var where = ' WHERE cp.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (req.query.id_sucursal) {
            where += ' AND cp.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }

        if (buscar) {
            where += ' AND (cp.' + ccCodCon + ' LIKE @buscar OR cp.' + ccNomCon + ' LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND cp.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND cp.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'condiciones_pago', alias: 'cp', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM condiciones_pago cp' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var columnas = 'cp.id_condicion, cp.id_sucursal, cp.cod_condicion, cp.nombre, cp.dias, cp.estado';
        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT ' + columnas + ' FROM condiciones_pago cp' + where + ' ORDER BY cp.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ' + columnas + ' FROM condiciones_pago cp' + where + ' ORDER BY cp.' + sort + ' ' + 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('[MAESTRAS] Error condiciones:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar condiciones de pago' });
    }
});

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

var ccCodCon = 'cod_condicion';
var ccNomCon = 'nombre';
var ccDiaCon = 'dias';

        var data = await db.query('SELECT id_condicion, id_sucursal, ' + ccCodCon + ' AS cod_condicion, ' + ccNomCon + ' AS nombre, ' + ccDiaCon + ' AS dias, estado FROM condiciones_pago WHERE id_empresa = @id_empresa AND id_condicion = @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: 'Condición no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error condicion:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar condición de pago' });
    }
});

router.post('/condiciones-pago', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

var ccCodCon = 'cod_condicion';
var ccNomCon = 'nombre';
var ccDiaCon = 'dias';

        var dup = await db.query('SELECT COUNT(*) as cnt FROM condiciones_pago WHERE id_empresa = @id_empresa AND ' + ccCodCon + ' = @cod', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(10), value: req.body.cod_condicion }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de condición de pago ya existe' });
        }
        var idSucursal = req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null;
        var sql = 'INSERT INTO condiciones_pago (id_empresa, id_sucursal, ' + ccCodCon + ', ' + ccNomCon + ', ' + ccDiaCon + ', estado) VALUES (@id_empresa, @id_sucursal, @cod_con, @nom_con, @dia_con, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id_sucursal: { type: db.sql.Int, value: idSucursal },
            cod_con: { type: db.sql.NVarChar(10), value: req.body.cod_condicion },
            nom_con: { type: db.sql.NVarChar(200), value: req.body.nombre },
            dia_con: { type: db.sql.Int, value: parseInt(req.body.dias) || 0 },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Condición de pago registrada', data: { id_condicion: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear condicion:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar condición de pago' });
    }
});

router.put('/condiciones-pago/:id', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : (req.query.id_empresa ? parseInt(req.query.id_empresa) : null);
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

var ccCodCon = 'cod_condicion';
var ccNomCon = 'nombre';
var ccDiaCon = 'dias';

        var dup = await db.query('SELECT COUNT(*) as cnt FROM condiciones_pago WHERE id_empresa = @id_empresa AND ' + ccCodCon + ' = @cod AND id_condicion != @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(10), value: req.body.cod_condicion },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de condición de pago ya existe en otro registro' });
        }
        var sql = 'UPDATE condiciones_pago SET ' + ccCodCon + ' = @cod_con, ' + ccNomCon + ' = @nom_con, ' + ccDiaCon + ' = @dia_con, estado = @estado, id_sucursal = @id_sucursal WHERE id_empresa = @id_empresa AND id_condicion = @id';
        await db.execute(sql, {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            cod_con: { type: db.sql.NVarChar(10), value: req.body.cod_condicion },
            nom_con: { type: db.sql.NVarChar(200), value: req.body.nombre },
            dia_con: { type: db.sql.Int, value: parseInt(req.body.dias) || 0 },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null }
        });
        res.json({ ok: true, mensaje: 'Condición de pago actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar condicion:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar condición de pago' });
    }
});

router.delete('/condiciones-pago/:id', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var id = parseInt(req.params.id);
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM proveedores WHERE id_empresa = @id_empresa AND id_condicion = @id), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, id: { type: db.sql.Int, value: id } }); total += r1[0].cnt; } catch(e) {}
        try { var r2 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM clientes WHERE id_empresa = @id_empresa AND id_condicion = @id), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, id: { type: db.sql.Int, value: id } }); total += r2[0].cnt; } catch(e) {}
        try { var r3 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM cab_orden_compra WHERE id_empresa = @id_empresa AND id_condicion = @id), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, id: { type: db.sql.Int, value: id } }); total += r3[0].cnt; } catch(e) {}
        try { var r4 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM formas_pago WHERE id_empresa = @id_empresa AND id_condicion = @id), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, id: { type: db.sql.Int, value: id } }); total += r4[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE condiciones_pago SET estado = 0 WHERE id_empresa = @id_empresa AND id_condicion = @id', {
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                id: { type: db.sql.Int, value: id }
            });
            res.json({ ok: true, mensaje: 'La condición de pago tiene registros asociados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM condiciones_pago WHERE id_empresa = @id_empresa AND id_condicion = @id', {
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                id: { type: db.sql.Int, value: id }
            });
            res.json({ ok: true, mensaje: 'Condición de pago eliminada' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar condicion:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar condición de pago' });
    }
});

// ============================================================
// EMPRESAS
// ============================================================

router.get('/empresas', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['razon_social', 'nombre_comercial', 'ruc', 'estado']) || 'razon_social';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var where = 'WHERE 1=1';
        var params = {};

        if (buscar) {
            where += ' AND (razon_social LIKE @buscar OR nombre_comercial LIKE @buscar OR ruc LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND ' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'empresas', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM empresas ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT id_empresa, ruc, razon_social, nombre_comercial, direccion, telefono, email_empresa AS email, estado FROM empresas ' + where + ' ORDER BY ' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT id_empresa, ruc, razon_social, nombre_comercial, direccion, telefono, email_empresa AS email, estado FROM empresas ' + where + ' ORDER BY ' + sort + ' ' + 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('[MAESTRAS] Error empresas:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar empresas' });
    }
});

router.get('/empresas/:id', async function(req, res) {
    try {
        var data = await db.query('SELECT id_empresa, ruc, razon_social, nombre_comercial, direccion, telefono, email_empresa AS email, logo, estado FROM empresas WHERE id_empresa = @id', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Empresa no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error empresa:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar empresa' });
    }
});

router.post('/empresas', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM empresas WHERE ruc = @ruc', {
            ruc: { type: db.sql.VarChar(20), value: req.body.ruc }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El RUC ya está registrado en otra empresa' });
        }
        var sql = 'INSERT INTO empresas (ruc, razon_social, nombre_comercial, direccion, telefono, email_empresa, estado) VALUES (@ruc, @razon_social, @nombre_comercial, @direccion, @telefono, @email, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            ruc: { type: db.sql.VarChar(20), value: req.body.ruc },
            razon_social: { type: db.sql.NVarChar(150), value: req.body.razon_social },
            nombre_comercial: { type: db.sql.NVarChar(100), value: req.body.nombre_comercial || '' },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || '' },
            telefono: { type: db.sql.VarChar(30), value: req.body.telefono || '' },
            email: { type: db.sql.VarChar(150), value: req.body.email_empresa || '' },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Empresa registrada', data: { id_empresa: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear empresa:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar empresa' });
    }
});

router.put('/empresas/:id', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM empresas WHERE ruc = @ruc AND id_empresa != @id', {
            ruc: { type: db.sql.VarChar(20), value: req.body.ruc },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El RUC ya está registrado en otra empresa' });
        }
        var sql = 'UPDATE empresas SET ruc = @ruc, razon_social = @razon_social, nombre_comercial = @nombre_comercial, direccion = @direccion, telefono = @telefono, email_empresa = @email, estado = @estado WHERE id_empresa = @id';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            ruc: { type: db.sql.VarChar(20), value: req.body.ruc },
            razon_social: { type: db.sql.NVarChar(150), value: req.body.razon_social },
            nombre_comercial: { type: db.sql.NVarChar(100), value: req.body.nombre_comercial || '' },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || '' },
            telefono: { type: db.sql.VarChar(30), value: req.body.telefono || '' },
            email: { type: db.sql.VarChar(150), value: req.body.email_empresa || '' },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Empresa actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar empresa:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar empresa' });
    }
});

router.delete('/empresas/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM proveedores WHERE id_empresa = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r1[0].cnt; } catch(e) {}
        try { var r2 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM vendedores WHERE id_empresa = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r2[0].cnt; } catch(e) {}
        try { var r3 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM usuarios WHERE id_empresa = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r3[0].cnt; } catch(e) {}
        try { var r4 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM empleados WHERE id_empresa = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r4[0].cnt; } catch(e) {}
        try { var r5 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM articulos WHERE id_empresa = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r5[0].cnt; } catch(e) {}
        try { var r6 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM clientes WHERE id_empresa = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r6[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE empresas SET estado = 0 WHERE id_empresa = @id', {
                id: { type: db.sql.Int, value: id }
            });
            res.json({ ok: true, mensaje: 'La empresa tiene registros asociados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM empresas WHERE id_empresa = @id', {
                id: { type: db.sql.Int, value: id }
            });
            res.json({ ok: true, mensaje: 'Empresa eliminada' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar empresa:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar empresa' });
    }
});

router.post('/empresas/:id/logo', uploadLogo.single('logo'), async function(req, res) {
    try {
        if (!req.file) return res.status(400).json({ ok: false, mensaje: 'No se recibió ningún archivo' });
        var filename = req.file.filename;
        var logoUrl = '/img/logos/' + filename;
        await db.execute('UPDATE empresas SET logo = @logo WHERE id_empresa = @id', {
            logo: { type: db.sql.VarChar(500), value: logoUrl },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        res.json({ ok: true, mensaje: 'Logo subido correctamente', data: { logo: logoUrl } });
    } catch (error) {
        console.error('[MAESTRAS] Error subir logo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al subir logo' });
    }
});

router.delete('/empresas/:id/logo', async function(req, res) {
    try {
        await db.execute('UPDATE empresas SET logo = NULL WHERE id_empresa = @id', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        res.json({ ok: true, mensaje: 'Logo eliminado' });
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar logo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar logo' });
    }
});

// ============================================================
// TIPO DOCUMENTO
// ============================================================

router.get('/tipo-documento', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['codigo', 'descripcion', 'longitud', 'activo']) || 'codigo';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = 'WHERE id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (req.query.id_sucursal) {
            where += ' AND id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }

        if (buscar) {
            where += ' AND (codigo LIKE @buscar OR descripcion LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND activo = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND ' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'tipo_documento', where, params, bitColumns: ['activo'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM tipo_documento ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT codigo, descripcion, activo, longitud, id_sucursal FROM tipo_documento ' + where + ' ORDER BY ' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT codigo, descripcion, activo, longitud, id_sucursal FROM tipo_documento ' + where + ' ORDER BY ' + sort + ' ' + 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('[MAESTRAS] Error tipo_documento:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar tipos de documento' });
    }
});

router.get('/tipo-documento/:codigo', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var data = await db.query('SELECT codigo, descripcion, activo, longitud, id_sucursal FROM tipo_documento WHERE id_empresa = @id_empresa AND codigo = @cod', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(50), value: req.params.codigo }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Tipo de documento no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error tipo_documento:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar tipo de documento' });
    }
});

router.post('/tipo-documento', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var codigo = (req.body.codigo || '').toString().trim().toUpperCase();
        if (codigo.length > 2) return res.status(400).json({ ok: false, mensaje: 'El código no puede tener más de 2 caracteres' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM tipo_documento WHERE id_empresa = @id_empresa AND codigo = @cod', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(50), value: codigo }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de documento ya existe' });
        }
        var longitud = parseInt(req.body.longitud) || 0;
        var sql = 'INSERT INTO tipo_documento (id_empresa, id_sucursal, codigo, descripcion, activo, longitud) VALUES (@id_empresa, @id_sucursal, @codigo, @descripcion, @activo, @longitud)';
        await db.execute(sql, {
            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 },
            codigo: { type: db.sql.NVarChar(50), value: codigo },
            descripcion: { type: db.sql.NVarChar(80), value: req.body.descripcion },
            activo: { type: db.sql.Bit, value: req.body.activo !== undefined ? (req.body.activo ? 1 : 0) : 1 },
            longitud: { type: db.sql.Int, value: longitud }
        });
        res.json({ ok: true, mensaje: 'Tipo de documento registrado', data: { codigo: codigo } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear tipo_documento:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar tipo de documento' });
    }
});

router.put('/tipo-documento/:codigo', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var codigo = (req.body.codigo || '').toString().trim().toUpperCase();
        if (codigo.length > 2) return res.status(400).json({ ok: false, mensaje: 'El código no puede tener más de 2 caracteres' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM tipo_documento WHERE id_empresa = @id_empresa AND codigo = @cod AND codigo != @cod_actual', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(50), value: codigo },
            cod_actual: { type: db.sql.NVarChar(50), value: req.params.codigo }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de documento ya existe en otro registro' });
        }
        var longitud = parseInt(req.body.longitud) || 0;
        var sql = 'UPDATE tipo_documento SET codigo = @codigo, descripcion = @descripcion, activo = @activo, longitud = @longitud, id_sucursal = @id_sucursal WHERE id_empresa = @id_empresa AND codigo = @cod_actual';
        await db.execute(sql, {
            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 },
            codigo: { type: db.sql.NVarChar(50), value: codigo },
            cod_actual: { type: db.sql.NVarChar(50), value: req.params.codigo },
            descripcion: { type: db.sql.NVarChar(80), value: req.body.descripcion },
            activo: { type: db.sql.Bit, value: req.body.activo ? 1 : 0 },
            longitud: { type: db.sql.Int, value: longitud }
        });
        res.json({ ok: true, mensaje: 'Tipo de documento actualizado' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar tipo_documento:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar tipo de documento' });
    }
});

router.delete('/tipo-documento/:codigo', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var cod = req.params.codigo;
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM proveedores WHERE id_empresa = @id_empresa AND tipo_documento = @cod), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, cod: { type: db.sql.NVarChar(50), value: cod } }); total += r1[0].cnt; } catch(e) {}
        try { var r2 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM clientes WHERE id_empresa = @id_empresa AND tipo_documento = @cod), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, cod: { type: db.sql.NVarChar(50), value: cod } }); total += r2[0].cnt; } catch(e) {}
        try { var r3 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM empleados WHERE id_empresa = @id_empresa AND tipo_documento = @cod), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, cod: { type: db.sql.NVarChar(50), value: cod } }); total += r3[0].cnt; } catch(e) {}
        try { var r4 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM choferes WHERE id_empresa = @id_empresa AND tipo_documento = @cod), 0) as cnt', { id_empresa: { type: db.sql.Int, value: idEmpresa }, cod: { type: db.sql.NVarChar(50), value: cod } }); total += r4[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE tipo_documento SET activo = 0 WHERE id_empresa = @id_empresa AND codigo = @cod', {
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                cod: { type: db.sql.NVarChar(50), value: cod }
            });
            res.json({ ok: true, mensaje: 'El tipo de documento tiene registros asociados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM tipo_documento WHERE id_empresa = @id_empresa AND codigo = @cod', {
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                cod: { type: db.sql.NVarChar(50), value: cod }
            });
            res.json({ ok: true, mensaje: 'Tipo de documento eliminado' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar tipo_documento:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar tipo de documento' });
    }
});

// ============================================================
// VENDEDORES
// ============================================================

router.get('/vendedores', async function(req, res) {
    if (process.env.MODO_ERP !== 'web') {
        try {
            var vCols = ['id_sucursal', 'tipo_documento', 'num_documento', 'email', 'telefono', 'comision_porcentaje'];
            for (var i = 0; i < vCols.length; i++) {
                try { await db.execute('ALTER TABLE vendedores ADD ' + vCols[i] + ' ' + (vCols[i] === 'comision_porcentaje' ? 'DECIMAL(5,2) DEFAULT 0' : 'NULL')); } catch (_) {}
            }
        } catch (_) {}
    }
    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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_vendedor', 'nombre', 'email', 'estado']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE v.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;
        if (idSucursal) {
            where += ' AND v.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }

        if (buscar) {
            where += ' AND (v.cod_vendedor LIKE @buscar OR v.nombre LIKE @buscar OR v.email LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND v.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND v.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'vendedores', alias: 'v', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM vendedores v ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        var selectCols = 'v.id_vendedor, v.id_sucursal, v.cod_vendedor, v.nombre, v.tipo_documento, v.num_documento, v.email, v.telefono, v.comision_porcentaje, v.estado';
        if (sinPaginacion) {
            sqlData = 'SELECT ' + selectCols + ' FROM vendedores v ' + where + ' ORDER BY v.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ' + selectCols + ' FROM vendedores v ' + where + ' ORDER BY v.' + sort + ' ' + 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('[MAESTRAS] Error vendedores:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar vendedores' });
    }
});

router.get('/vendedores/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var data = await db.query('SELECT v.id_vendedor, v.id_empresa, v.id_sucursal, v.cod_vendedor, v.nombre, v.tipo_documento, v.num_documento, v.email, v.telefono, v.comision_porcentaje, v.estado FROM vendedores v WHERE v.id_vendedor = @id AND v.id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Vendedor no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error vendedor:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar vendedor' });
    }
});

router.post('/vendedores', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM vendedores WHERE cod_vendedor = @cod AND id_empresa = @emp', {
            cod: { type: db.sql.NVarChar(7), value: req.body.cod_vendedor },
            emp: { type: db.sql.Int, value: parseInt(req.body.id_empresa) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de vendedor ya existe para esta empresa' });
        }
        var sql = 'INSERT INTO vendedores (id_empresa, id_sucursal, cod_vendedor, nombre, tipo_documento, num_documento, email, telefono, comision_porcentaje, estado) VALUES (@id_empresa, @id_sucursal, @cod_vendedor, @nombre, @tipo_documento, @num_documento, @email, @telefono, @comision_porcentaje, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: parseInt(req.body.id_empresa) },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal || null },
            cod_vendedor: { type: db.sql.NVarChar(7), value: req.body.cod_vendedor },
            nombre: { type: db.sql.NVarChar(150), value: req.body.nombre },
            tipo_documento: { type: db.sql.NVarChar(2), value: req.body.tipo_documento || null },
            num_documento: { type: db.sql.NVarChar(20), value: req.body.num_documento || null },
            email: { type: db.sql.NVarChar(100), value: req.body.email || null },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || null },
            comision_porcentaje: { type: db.sql.Decimal(5,2), value: req.body.comision_porcentaje || 0 },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Vendedor registrado', data: { id_vendedor: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear vendedor:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar vendedor' });
    }
});

router.put('/vendedores/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa || req.body.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM vendedores WHERE cod_vendedor = @cod AND id_empresa = @emp AND id_vendedor != @id', {
            cod: { type: db.sql.NVarChar(7), value: req.body.cod_vendedor },
            emp: { type: db.sql.Int, value: parseInt(id_empresa) },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de vendedor ya existe para esta empresa' });
        }
        var sql = 'UPDATE vendedores SET cod_vendedor = @cod_vendedor, nombre = @nombre, tipo_documento = @tipo_documento, num_documento = @num_documento, email = @email, telefono = @telefono, comision_porcentaje = @comision_porcentaje, estado = @estado WHERE id_vendedor = @id AND id_empresa = @id_empresa';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) },
            cod_vendedor: { type: db.sql.NVarChar(7), value: req.body.cod_vendedor },
            nombre: { type: db.sql.NVarChar(150), value: req.body.nombre },
            tipo_documento: { type: db.sql.NVarChar(2), value: req.body.tipo_documento || null },
            num_documento: { type: db.sql.NVarChar(20), value: req.body.num_documento || null },
            email: { type: db.sql.NVarChar(100), value: req.body.email || null },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || null },
            comision_porcentaje: { type: db.sql.Decimal(5,2), value: req.body.comision_porcentaje || 0 },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Vendedor actualizado' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar vendedor:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar vendedor' });
    }
});

router.delete('/vendedores/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM clientes WHERE id_empresa = @id_empresa AND id_vendedor = @id), 0) as cnt', { id: { type: db.sql.Int, value: id }, id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) } }); total += r1[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE vendedores SET estado = 0 WHERE id_vendedor = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'El vendedor tiene clientes asociados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM vendedores WHERE id_vendedor = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'Vendedor eliminado' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar vendedor:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar vendedor' });
    }
});

// ============================================================
// EMPLEADOS
// ============================================================

router.get('/empleados', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_empleado', 'nombre', 'email', 'cargo', 'area', 'fecha_nacimiento', 'estado_civil', 'estado', 'id_area']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE e.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (buscar) {
            where += ' AND (e.cod_empleado LIKE @buscar OR e.nombre LIKE @buscar OR e.email LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND e.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND e.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'empleados', alias: 'e', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM empleados e ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        var selectCols = 'e.id_empleado, e.cod_empleado, e.nombre, e.tipo_documento, td.descripcion AS tipo_documento_nombre, e.num_documento, e.email, e.telefono, e.cargo, e.area, e.direccion, e.fecha_nacimiento, e.estado_civil, e.fecha_ingreso, e.id_cargo, e.id_area, e.estado';
        var fromJoin = ' FROM empleados e LEFT JOIN tipo_documento td ON e.tipo_documento = td.codigo AND td.id_empresa = @id_empresa';
        if (sinPaginacion) {
            sqlData = 'SELECT ' + selectCols + fromJoin + where + ' ORDER BY e.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ' + selectCols + fromJoin + where + ' ORDER BY e.' + sort + ' ' + 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('[MAESTRAS] Error empleados:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar empleados' });
    }
});

router.get('/empleados/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var data = await db.query('SELECT e.id_empleado, e.id_empresa, e.cod_empleado, e.nombre, e.tipo_documento, td.descripcion AS tipo_documento_nombre, e.num_documento, e.email, e.telefono, e.cargo, e.area, e.direccion, e.fecha_nacimiento, e.estado_civil, e.fecha_ingreso, e.id_cargo, e.id_area, e.estado FROM empleados e LEFT JOIN tipo_documento td ON e.tipo_documento = td.codigo AND td.id_empresa = @id_empresa WHERE e.id_empleado = @id AND e.id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Empleado no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error empleado:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar empleado' });
    }
});

router.post('/empleados', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM empleados WHERE cod_empleado = @cod AND id_empresa = @emp', {
            cod: { type: db.sql.NVarChar(7), value: req.body.cod_empleado },
            emp: { type: db.sql.Int, value: parseInt(req.body.id_empresa) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de empleado ya existe para esta empresa' });
        }
        var sql = 'INSERT INTO empleados (id_empresa, cod_empleado, nombre, tipo_documento, num_documento, email, telefono, cargo, id_cargo, area, id_area, direccion, fecha_nacimiento, estado_civil, fecha_ingreso, estado) VALUES (@id_empresa, @cod_empleado, @nombre, @tipo_documento, @num_documento, @email, @telefono, @cargo, @id_cargo, @area, @id_area, @direccion, @fecha_nacimiento, @estado_civil, @fecha_ingreso, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: parseInt(req.body.id_empresa) },
            cod_empleado: { type: db.sql.NVarChar(7), value: req.body.cod_empleado },
            nombre: { type: db.sql.NVarChar(150), value: req.body.nombre },
            tipo_documento: { type: db.sql.NVarChar(50), value: req.body.tipo_documento || null },
            num_documento: { type: db.sql.NVarChar(20), value: req.body.num_documento || '' },
            email: { type: db.sql.NVarChar(100), value: req.body.email || '' },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || '' },
            cargo: { type: db.sql.NVarChar(100), value: req.body.cargo || '' },
            id_cargo: { type: db.sql.Int, value: req.body.id_cargo || null },
            area: { type: db.sql.NVarChar(100), value: req.body.area || '' },
            id_area: { type: db.sql.Int, value: req.body.id_area || null },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || '' },
            fecha_nacimiento: { type: db.sql.Date, value: req.body.fecha_nacimiento || null },
            estado_civil: { type: db.sql.NVarChar(20), value: req.body.estado_civil || '' },
            fecha_ingreso: { type: db.sql.Date, value: req.body.fecha_ingreso || null },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Empleado registrado', data: { id_empleado: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear empleado:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar empleado' });
    }
});

router.put('/empleados/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa || req.body.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM empleados WHERE cod_empleado = @cod AND id_empresa = @emp AND id_empleado != @id', {
            cod: { type: db.sql.NVarChar(7), value: req.body.cod_empleado },
            emp: { type: db.sql.Int, value: parseInt(id_empresa) },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de empleado ya existe para esta empresa' });
        }
        var sql = 'UPDATE empleados SET cod_empleado = @cod_empleado, nombre = @nombre, tipo_documento = @tipo_documento, num_documento = @num_documento, email = @email, telefono = @telefono, cargo = @cargo, id_cargo = @id_cargo, area = @area, id_area = @id_area, direccion = @direccion, fecha_nacimiento = @fecha_nacimiento, estado_civil = @estado_civil, fecha_ingreso = @fecha_ingreso, estado = @estado WHERE id_empleado = @id AND id_empresa = @id_empresa';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) },
            cod_empleado: { type: db.sql.NVarChar(7), value: req.body.cod_empleado },
            nombre: { type: db.sql.NVarChar(150), value: req.body.nombre },
            tipo_documento: { type: db.sql.NVarChar(50), value: req.body.tipo_documento || null },
            num_documento: { type: db.sql.NVarChar(20), value: req.body.num_documento || '' },
            email: { type: db.sql.NVarChar(100), value: req.body.email || '' },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || '' },
            cargo: { type: db.sql.NVarChar(100), value: req.body.cargo || '' },
            id_cargo: { type: db.sql.Int, value: req.body.id_cargo || null },
            area: { type: db.sql.NVarChar(100), value: req.body.area || '' },
            id_area: { type: db.sql.Int, value: req.body.id_area || null },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || '' },
            fecha_nacimiento: { type: db.sql.Date, value: req.body.fecha_nacimiento || null },
            estado_civil: { type: db.sql.NVarChar(20), value: req.body.estado_civil || '' },
            fecha_ingreso: { type: db.sql.Date, value: req.body.fecha_ingreso || null },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Empleado actualizado' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar empleado:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar empleado' });
    }
});

router.delete('/empleados/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });

        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM guias_remision WHERE id_empleado = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r1[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE empleados SET estado = 0 WHERE id_empleado = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'El empleado tiene movimientos asociados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM empleados WHERE id_empleado = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'Empleado eliminado' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar empleado:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar empleado' });
    }
});

// ============================================================
// CHOFERES
// ============================================================

router.get('/choferes', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_chofer', 'nombre', 'estado']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE ch.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (req.query.id_sucursal) {
            where += ' AND ch.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }

        if (buscar) {
            where += ' AND (ch.cod_chofer LIKE @buscar OR ch.nombre LIKE @buscar OR ch.email LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND ch.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND ch.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'choferes', alias: 'ch', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM choferes ch ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        var selectCols = 'ch.id_chofer, ch.id_sucursal, ch.cod_chofer, ch.nombre, ch.tipo_documento, td.descripcion AS tipo_documento_nombre, ch.num_documento, ch.email, ch.telefono, ch.licencia_conducir, ch.categoria_licencia, ch.direccion, ch.fecha_nacimiento, ch.fecha_vencimiento_licencia, ch.estado';
        var fromJoin = ' FROM choferes ch LEFT JOIN tipo_documento td ON ch.tipo_documento = td.codigo AND td.id_empresa = @id_empresa';
        if (sinPaginacion) {
            sqlData = 'SELECT ' + selectCols + fromJoin + where + ' ORDER BY ch.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ' + selectCols + fromJoin + where + ' ORDER BY ch.' + sort + ' ' + 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('[MAESTRAS] Error choferes:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar choferes' });
    }
});

router.get('/choferes/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var data = await db.query('SELECT ch.id_chofer, ch.id_empresa, ch.cod_chofer, ch.nombre, ch.tipo_documento, td.descripcion AS tipo_documento_nombre, ch.num_documento, ch.email, ch.telefono, ch.licencia_conducir, ch.categoria_licencia, ch.direccion, ch.fecha_nacimiento, ch.fecha_vencimiento_licencia, ch.estado FROM choferes ch LEFT JOIN tipo_documento td ON ch.tipo_documento = td.codigo AND td.id_empresa = @id_empresa WHERE ch.id_chofer = @id AND ch.id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Chofer no encontrado' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error chofer:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar chofer' });
    }
});

router.post('/choferes', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM choferes WHERE cod_chofer = @cod AND id_empresa = @emp', {
            cod: { type: db.sql.NVarChar(10), value: req.body.cod_chofer },
            emp: { type: db.sql.Int, value: parseInt(req.body.id_empresa) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de chofer ya existe para esta empresa' });
        }
        var sql = 'INSERT INTO choferes (id_empresa, id_sucursal, cod_chofer, nombre, tipo_documento, num_documento, email, telefono, licencia_conducir, categoria_licencia, direccion, fecha_nacimiento, fecha_vencimiento_licencia, estado) VALUES (@id_empresa, @id_sucursal, @cod_chofer, @nombre, @tipo_documento, @num_documento, @email, @telefono, @licencia, @cat_licencia, @direccion, @fecha_nacimiento, @fecha_vencimiento_licencia, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: parseInt(req.body.id_empresa) },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null },
            cod_chofer: { type: db.sql.NVarChar(10), value: req.body.cod_chofer },
            nombre: { type: db.sql.NVarChar(150), value: req.body.nombre },
            tipo_documento: { type: db.sql.NVarChar(50), value: req.body.tipo_documento || null },
            num_documento: { type: db.sql.NVarChar(20), value: req.body.num_documento || '' },
            email: { type: db.sql.NVarChar(100), value: req.body.email || '' },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || '' },
            licencia: { type: db.sql.NVarChar(30), value: req.body.licencia_conducir || '' },
            cat_licencia: { type: db.sql.NVarChar(10), value: req.body.categoria_licencia || '' },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || '' },
            fecha_nacimiento: { type: db.sql.Date, value: req.body.fecha_nacimiento || null },
            fecha_vencimiento_licencia: { type: db.sql.Date, value: req.body.fecha_vencimiento_licencia || null },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Chofer registrado', data: { id_chofer: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear chofer:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar chofer' });
    }
});

router.put('/choferes/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa || req.body.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM choferes WHERE cod_chofer = @cod AND id_empresa = @emp AND id_chofer != @id', {
            cod: { type: db.sql.NVarChar(10), value: req.body.cod_chofer },
            emp: { type: db.sql.Int, value: parseInt(id_empresa) },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de chofer ya existe para esta empresa' });
        }
        var sql = 'UPDATE choferes SET cod_chofer = @cod_chofer, nombre = @nombre, tipo_documento = @tipo_documento, num_documento = @num_documento, email = @email, telefono = @telefono, licencia_conducir = @licencia, categoria_licencia = @cat_licencia, direccion = @direccion, fecha_nacimiento = @fecha_nacimiento, fecha_vencimiento_licencia = @fecha_vencimiento_licencia, estado = @estado, id_sucursal = @id_sucursal WHERE id_chofer = @id AND id_empresa = @id_empresa';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null },
            cod_chofer: { type: db.sql.NVarChar(10), value: req.body.cod_chofer },
            nombre: { type: db.sql.NVarChar(150), value: req.body.nombre },
            tipo_documento: { type: db.sql.NVarChar(50), value: req.body.tipo_documento || null },
            num_documento: { type: db.sql.NVarChar(20), value: req.body.num_documento || '' },
            email: { type: db.sql.NVarChar(100), value: req.body.email || '' },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || '' },
            licencia: { type: db.sql.NVarChar(30), value: req.body.licencia_conducir || '' },
            cat_licencia: { type: db.sql.NVarChar(10), value: req.body.categoria_licencia || '' },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || '' },
            fecha_nacimiento: { type: db.sql.Date, value: req.body.fecha_nacimiento || null },
            fecha_vencimiento_licencia: { type: db.sql.Date, value: req.body.fecha_vencimiento_licencia || null },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Chofer actualizado' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar chofer:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar chofer' });
    }
});

router.delete('/choferes/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM guias_remision WHERE id_empresa = @id_empresa AND id_chofer = @id), 0) as cnt', { id: { type: db.sql.Int, value: id }, id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) } }); total += r1[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE choferes SET estado = 0 WHERE id_chofer = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'El chofer tiene guías asociadas, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM choferes WHERE id_chofer = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'Chofer eliminado' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar chofer:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar chofer' });
    }
});

// ============================================================
// UNIDADES DE MEDIDA
// ============================================================

router.get('/unidades-medida', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_sunat', 'nombre', 'estado']) || 'cod_sunat';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = 'WHERE id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (req.query.id_sucursal) {
            where += ' AND id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: parseInt(req.query.id_sucursal) };
        }

        if (buscar) {
            where += ' AND (cod_sunat LIKE @buscar OR nombre LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND ' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'unidad_medida', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM unidad_medida ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT id_unidad, cod_sunat, nombre, estado, id_sucursal FROM unidad_medida ' + where + ' ORDER BY ' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT id_unidad, cod_sunat, nombre, estado, id_sucursal FROM unidad_medida ' + where + ' ORDER BY ' + sort + ' ' + 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('[MAESTRAS] Error unidad_medida:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar unidades de medida' });
    }
});

router.get('/unidades-medida/:id', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var data = await db.query('SELECT id_unidad, cod_sunat, nombre, estado, id_sucursal FROM unidad_medida WHERE id_empresa = @id_empresa AND id_unidad = @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: 'Unidad no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error unidad_medida:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar unidad de medida' });
    }
});

router.post('/unidades-medida', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM unidad_medida WHERE id_empresa = @id_empresa AND cod_sunat = @cod', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(3), value: req.body.cod_sunat }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código SUNAT ya existe' });
        }
        var sql = 'INSERT INTO unidad_medida (id_empresa, id_sucursal, cod_sunat, nombre, estado) VALUES (@id_empresa, @id_sucursal, @cod_sunat, @nombre, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            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 },
            cod_sunat: { type: db.sql.NVarChar(3), value: req.body.cod_sunat },
            nombre: { type: db.sql.NVarChar(100), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Unidad de medida registrada', data: { id_unidad: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear unidad_medida:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar unidad de medida' });
    }
});

router.put('/unidades-medida/:id', async function(req, res) {
    try {
        var idEmpresa = req.body.id_empresa ? parseInt(req.body.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM unidad_medida WHERE id_empresa = @id_empresa AND cod_sunat = @cod AND id_unidad != @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            cod: { type: db.sql.NVarChar(3), value: req.body.cod_sunat },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código SUNAT ya existe en otro registro' });
        }
        var sql = 'UPDATE unidad_medida SET cod_sunat = @cod_sunat, nombre = @nombre, estado = @estado, id_sucursal = @id_sucursal WHERE id_empresa = @id_empresa AND id_unidad = @id';
        await db.execute(sql, {
            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 },
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            cod_sunat: { type: db.sql.NVarChar(3), value: req.body.cod_sunat },
            nombre: { type: db.sql.NVarChar(100), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Unidad de medida actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar unidad_medida:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar unidad de medida' });
    }
});

router.delete('/unidades-medida/:id', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });
        var id = parseInt(req.params.id);
        await db.execute('DELETE FROM unidad_medida WHERE id_empresa = @id_empresa AND id_unidad = @id', {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            id: { type: db.sql.Int, value: id }
        });
        res.json({ ok: true, mensaje: 'Unidad de medida eliminada' });
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar unidad_medida:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar unidad de medida' });
    }
});

// ============================================================
// UBIGEO — CRUD y auxiliares
// ============================================================

router.get('/ubigeo/departamentos', async function(req, res) {
    try {
        var data = await db.query("SELECT DISTINCT departamento FROM ubigeo ORDER BY departamento");
        res.json({ ok: true, data: data.map(function(r) { return r.departamento; }) });
    } catch (error) {
        console.error('[MAESTRAS] Error deptos:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar departamentos' });
    }
});

router.get('/ubigeo/provincias', async function(req, res) {
    try {
        var where = 'WHERE 1=1';
        var params = {};
        if (req.query.departamento) {
            where += ' AND departamento = @dep';
            params.dep = { type: db.sql.NVarChar(60), value: req.query.departamento };
        }
        var data = await db.query("SELECT DISTINCT provincia FROM ubigeo " + where + " ORDER BY provincia", params);
        res.json({ ok: true, data: data.map(function(r) { return r.provincia; }) });
    } catch (error) {
        console.error('[MAESTRAS] Error provincias:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar provincias' });
    }
});

router.get('/ubigeo', 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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_ubigeo', 'departamento', 'provincia', 'distrito']) || 'departamento, provincia, distrito';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var where = 'WHERE 1=1';
        var params = {};

        if (buscar) {
            where += ' AND (cod_ubigeo LIKE @buscar OR departamento LIKE @buscar OR provincia LIKE @buscar OR distrito LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }

        if (req.query.departamento) {
            where += ' AND departamento = @dep';
            params.dep = { type: db.sql.NVarChar(60), value: req.query.departamento };
        }

        if (req.query.provincia) {
            where += ' AND provincia = @prov';
            params.prov = { type: db.sql.NVarChar(60), value: req.query.provincia };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND ' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        var sqlCount = 'SELECT COUNT(*) as total FROM ubigeo ' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = total > 0 ? Math.ceil(total / Math.abs(limit)) : 0;

        var sqlData;
        var selectCols = 'cod_ubigeo, departamento, provincia, distrito';
        if (sinPaginacion) {
            sqlData = 'SELECT ' + selectCols + ' FROM ubigeo ' + where + ' ORDER BY ' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ' + selectCols + ' FROM ubigeo ' + where + ' ORDER BY ' + sort + ' ' + 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('[MAESTRAS] Error ubigeo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar ubigeo' });
    }
});

// ============================================================
// GET /api/ubigeo/buscar?q= — Búsqueda textual (usado por Proveedores)
// Debe ir antes de /:codigo para no ser capturado como parámetro
// ============================================================
router.get('/ubigeo/buscar', async function(req, res) {
    try {
        var q = (req.query.q || '').trim();
        if (q.length < 2) {
            return res.json({ ok: true, data: [] });
        }
        var sqlStr = `
            SELECT cod_ubigeo, departamento, provincia, distrito
            FROM ubigeo
            WHERE (departamento LIKE '%' + @q + '%'
                OR provincia LIKE '%' + @q + '%'
                OR distrito LIKE '%' + @q + '%')
            ORDER BY departamento, provincia, distrito
        `;
        var data = await db.query(sqlStr, {
            q: { type: db.sql.NVarChar(200), value: q }
        });
        res.json({ ok: true, data: data });
    } catch (error) {
        console.error('[UBIGEO] Error buscar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al buscar ubigeo' });
    }
});

// ============================================================
// GET /api/ubigeo/buscar-departamentos?q= — Autocomplete departamentos
// ============================================================
router.get('/ubigeo/buscar-departamentos', async function(req, res) {
    try {
        var q = (req.query.q || '').trim();
        var where = 'WHERE 1=1';
        var params = {};
        if (q) {
            where += ' AND departamento LIKE @q';
            params.q = { type: db.sql.NVarChar(70), value: '%' + q + '%' };
        }
        var data = await db.query('SELECT DISTINCT TOP 15 departamento FROM ubigeo ' + where + ' ORDER BY departamento', params);
        res.json({ ok: true, data: data.map(function(r) { return r.departamento; }) });
    } catch (error) {
        console.error('[UBIGEO] Error buscar deptos:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al buscar departamentos' });
    }
});

// ============================================================
// GET /api/ubigeo/buscar-provincias?departamento=X&q= — Autocomplete provincias
// ============================================================
router.get('/ubigeo/buscar-provincias', async function(req, res) {
    try {
        var q = (req.query.q || '').trim();
        var depto = req.query.departamento || '';
        var where = 'WHERE activo = 1';
        var params = {};
        if (depto) {
            where += ' AND departamento = @dep';
            params.dep = { type: db.sql.NVarChar(60), value: depto };
        }
        if (q) {
            where += ' AND provincia LIKE @q';
            params.q = { type: db.sql.NVarChar(70), value: '%' + q + '%' };
        }
        var data = await db.query('SELECT DISTINCT TOP 15 provincia FROM ubigeo ' + where + ' ORDER BY provincia', params);
        res.json({ ok: true, data: data.map(function(r) { return r.provincia; }) });
    } catch (error) {
        console.error('[UBIGEO] Error buscar provincias:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al buscar provincias' });
    }
});

// ============================================================
// GET /api/ubigeo/buscar-distritos?departamento=X&provincia=Y&q= — Autocomplete distritos
// ============================================================
router.get('/ubigeo/buscar-distritos', async function(req, res) {
    try {
        var q = (req.query.q || '').trim();
        var depto = req.query.departamento || '';
        var prov = req.query.provincia || '';
        var where = 'WHERE 1=1';
        var params = {};
        if (depto) {
            where += ' AND departamento = @dep';
            params.dep = { type: db.sql.NVarChar(60), value: depto };
        }
        if (prov) {
            where += ' AND provincia = @prov';
            params.prov = { type: db.sql.NVarChar(60), value: prov };
        }
        if (q) {
            where += ' AND distrito LIKE @q';
            params.q = { type: db.sql.NVarChar(70), value: '%' + q + '%' };
        }
        var data = await db.query('SELECT TOP 15 cod_ubigeo, distrito FROM ubigeo ' + where + ' ORDER BY distrito', params);
        res.json({ ok: true, data: data });
    } catch (error) {
        console.error('[UBIGEO] Error buscar distritos:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al buscar distritos' });
    }
});

// ============================================================
// GET /api/ubigeo/resolver/:codUbigeo — Resolver código a nombres
// ============================================================
router.get('/ubigeo/resolver/:codUbigeo', async function(req, res) {
    try {
        var data = await db.query('SELECT departamento, provincia, distrito FROM ubigeo WHERE cod_ubigeo = @cod_ubigeo', {
            cod_ubigeo: { type: db.sql.Char(6), value: req.params.codUbigeo }
        });
        if (data.length === 0) {
            return res.json({ ok: false, mensaje: 'Código ubigeo no encontrado' });
        }
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[UBIGEO] Error resolver:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al resolver ubigeo' });
    }
});

router.get('/ubigeo/:codigo', async function(req, res) {
    try {
        var data = await db.query('SELECT cod_ubigeo, departamento, provincia, distrito FROM ubigeo WHERE cod_ubigeo = @cod', {
            cod: { type: db.sql.NVarChar(50), value: req.params.codigo }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Ubicación no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error ubigeo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar ubicación' });
    }
});

router.post('/ubigeo', async function(req, res) {
    try {
        var cod = (req.body.cod_ubigeo || '').trim();
        var dep = (req.body.departamento || '').trim().toUpperCase();
        var prov = (req.body.provincia || '').trim().toUpperCase();
        var dist = (req.body.distrito || '').trim().toUpperCase();
        var activo = req.body.activo !== undefined ? (req.body.activo ? 1 : 0) : 1;

        if (!cod) return res.status(400).json({ ok: false, mensaje: 'El código ubigeo es requerido' });
        if (!dep || !prov || !dist) return res.status(400).json({ ok: false, mensaje: 'Departamento, provincia y distrito son requeridos' });

        var existe = await db.query('SELECT cod_ubigeo FROM ubigeo WHERE cod_ubigeo = @cod', {
            cod: { type: db.sql.NVarChar(50), value: cod }
        });
        if (existe.length > 0) return res.status(400).json({ ok: false, mensaje: 'El código ubigeo ya existe' });

        await db.execute('INSERT INTO ubigeo (cod_ubigeo, departamento, provincia, distrito, activo) VALUES (@cod, @dep, @prov, @dist, @activo)', {
            cod: { type: db.sql.NVarChar(50), value: cod },
            dep: { type: db.sql.NVarChar(60), value: dep },
            prov: { type: db.sql.NVarChar(60), value: prov },
            dist: { type: db.sql.NVarChar(60), value: dist },
            activo: { type: db.sql.Bit, value: activo }
        });
        res.json({ ok: true, mensaje: 'Ubicación creada' });
    } catch (error) {
        console.error('[MAESTRAS] Error crear ubigeo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al crear ubicación' });
    }
});

router.put('/ubigeo/:codigo', async function(req, res) {
    try {
        var sql = 'UPDATE ubigeo SET departamento = @dep, provincia = @prov, distrito = @dist, activo = @activo WHERE cod_ubigeo = @cod';
        await db.execute(sql, {
            cod: { type: db.sql.NVarChar(50), value: req.params.codigo },
            dep: { type: db.sql.NVarChar(60), value: req.body.departamento },
            prov: { type: db.sql.NVarChar(60), value: req.body.provincia },
            dist: { type: db.sql.NVarChar(60), value: req.body.distrito },
            activo: { type: db.sql.Bit, value: req.body.activo ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Ubicación actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar ubigeo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar ubicación' });
    }
});

router.delete('/ubigeo/:codigo', async function(req, res) {
    try {
        var refs = await db.query('SELECT COUNT(*) as total FROM proveedores WHERE cod_ubigeo = @cod', {
            cod: { type: db.sql.NVarChar(50), value: req.params.codigo }
        });
        if (refs[0].total > 0) {
            return res.status(400).json({ ok: false, mensaje: 'No se puede eliminar: ' + refs[0].total + ' proveedor(es) usan esta ubicación' });
        }
        await db.execute('DELETE FROM ubigeo WHERE cod_ubigeo = @cod', {
            cod: { type: db.sql.NVarChar(50), value: req.params.codigo }
        });
        res.json({ ok: true, mensaje: 'Ubicación eliminada' });
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar ubigeo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar ubicación' });
    }
});

// ============================================================
// ÁREAS
// ============================================================

// Auto-migración: crear tabla areas y columna id_area en empleados
router.get('/areas', async function(req, res) {
    if (process.env.MODO_ERP !== 'web') {
        try {
            await db.execute(`
                IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.areas') AND type = 'U')
                CREATE TABLE areas (
                    id_area INT IDENTITY(1,1) PRIMARY KEY,
                    id_empresa INT NOT NULL,
                    cod_area VARCHAR(6) NOT NULL,
                    nombre VARCHAR(100) NOT NULL,
                    estado BIT DEFAULT 1
                )
            `);
            await db.execute(`
                IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.empleados') AND name = 'id_area')
                ALTER TABLE empleados ADD id_area INT NULL
            `);
        } catch (_) {}
    }
    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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['cod_area', 'nombre', 'estado']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE ar.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;
        if (idSucursal) {
            where += ' AND ar.id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }

        var q = req.query.q || '';
        if (q) buscar = q;

        if (buscar || q) {
            where += ' AND (ar.cod_area LIKE @buscar OR ar.nombre LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + (buscar || q) + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND ar.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        if (filtros) {
            for (var col in filtros) {
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                where += ' AND ar.' + col + ' IN (' + placeholders.join(',') + ')';
                vals.forEach(function(v, i) {
                    params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: v.trim() };
                });
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'areas', alias: 'ar', where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM areas ar' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT ar.id_area, ar.id_sucursal, ar.cod_area, ar.nombre, ar.estado FROM areas ar' + where + ' ORDER BY ar.' + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ar.id_area, ar.id_sucursal, ar.cod_area, ar.nombre, ar.estado FROM areas ar' + where + ' ORDER BY ar.' + sort + ' ' + 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('[MAESTRAS] Error areas:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar áreas' });
    }
});

router.get('/areas/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var data = await db.query('SELECT id_area, id_empresa, id_sucursal, cod_area, nombre, estado FROM areas WHERE id_area = @id AND id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Área no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error area:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar área' });
    }
});

router.post('/areas', async function(req, res) {
    try {
        var dup = await db.query('SELECT COUNT(*) as cnt FROM areas WHERE cod_area = @cod AND id_empresa = @emp', {
            cod: { type: db.sql.NVarChar(6), value: req.body.cod_area },
            emp: { type: db.sql.Int, value: parseInt(req.body.id_empresa) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de área ya existe para esta empresa' });
        }
        var sql = 'INSERT INTO areas (id_empresa, id_sucursal, cod_area, nombre, estado) VALUES (@id_empresa, @id_sucursal, @cod_area, @nombre, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: parseInt(req.body.id_empresa) },
            id_sucursal: { type: db.sql.Int, value: req.body.id_sucursal || null },
            cod_area: { type: db.sql.NVarChar(6), value: req.body.cod_area },
            nombre: { type: db.sql.NVarChar(100), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Área registrada', data: { id_area: result[0].id } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear area:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar área' });
    }
});

router.put('/areas/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa || req.body.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var dup = await db.query('SELECT COUNT(*) as cnt FROM areas WHERE cod_area = @cod AND id_empresa = @emp AND id_area != @id', {
            cod: { type: db.sql.NVarChar(6), value: req.body.cod_area },
            emp: { type: db.sql.Int, value: parseInt(id_empresa) },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de área ya existe en otro registro' });
        }
        var sql = 'UPDATE areas SET cod_area = @cod_area, nombre = @nombre, estado = @estado WHERE id_area = @id AND id_empresa = @id_empresa';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) },
            cod_area: { type: db.sql.NVarChar(6), value: req.body.cod_area },
            nombre: { type: db.sql.NVarChar(100), value: req.body.nombre },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Área actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar area:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar área' });
    }
});

router.delete('/areas/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var total = 0;
        try { var r1 = await db.query('SELECT ISNULL((SELECT COUNT(*) FROM empleados WHERE id_empresa = @id_empresa AND id_area = @id), 0) as cnt', { id: { type: db.sql.Int, value: id }, id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) } }); total += r1[0].cnt; } catch(e) {}
        if (total > 0) {
            await db.execute('UPDATE areas SET estado = 0 WHERE id_area = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'El área tiene empleados asignados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM areas WHERE id_area = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'Área eliminada' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar area:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar área' });
    }
});

// ============================================================
// SUCURSALES
// ============================================================

router.get('/sucursales', async function(req, res) {
    if (process.env.MODO_ERP !== 'web') {
        try {
            await db.execute(`
                IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.sucursales') AND type = 'U')
                CREATE TABLE sucursales (
                    id_sucursal INT IDENTITY(1,1) PRIMARY KEY,
                    id_empresa INT NOT NULL,
                    codigo VARCHAR(20) NOT NULL,
                    nombre VARCHAR(200) NOT NULL,
                    direccion VARCHAR(200) NULL,
                    telefono VARCHAR(20) NULL,
                    estado BIT DEFAULT 1
                )
            `);
        } catch (_) {}
    }
    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) : 10;
        var sinPaginacion = limit <= 0;
        var sort = columnaValida(req.query.sort, ['codigo', 'nombre', 'direccion', 'telefono', 'estado', 'id_empresa', 'empresa_razon']) || 'nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;

        var idEmpresa = req.query.id_empresa ? parseInt(req.query.id_empresa) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' });

        var where = ' WHERE s.id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        var q = req.query.q || '';
        if (q) buscar = q;

        if (buscar || q) {
            where += ' AND (s.codigo LIKE @buscar OR s.nombre LIKE @buscar)';
            params.buscar = { type: db.sql.NVarChar(100), value: '%' + (buscar || q) + '%' };
        }

        if (req.query.estado !== undefined && req.query.estado !== '') {
            where += ' AND s.estado = @estado';
            params.estado = { type: db.sql.Bit, value: parseInt(req.query.estado) };
        }

        var colMapSuc = {
            empresa_razon: 'e.razon_social',
            codigo: 's.codigo',
            nombre: 's.nombre',
            direccion: 's.direccion',
            telefono: 's.telefono',
            estado: 's.estado'
        };

        if (filtros) {
            for (var col in filtros) {
                var sqlCol = colMapSuc[col] || 's.' + col;
                var vals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var opsRe = /^(>=|<=|>|<|=)\s*(.+)/;
                var hasOps = vals.some(function(v) { return opsRe.test(String(v).trim()); });
                if (hasOps) {
                    vals.forEach(function(v, i) {
                        var m = opsRe.exec(String(v).trim());
                        if (!m) return;
                        var op = m[1], val = m[2].trim();
                        var pname = 'f_' + col + '_' + i;
                        where += ' AND ' + sqlCol + ' ' + op + ' @' + pname;
                        params[pname] = { type: db.sql.NVarChar(100), value: val };
                    });
                } else {
                    var placeholders = vals.map(function(v, i) { return '@f_' + col + '_' + i; });
                    where += ' AND ' + sqlCol + ' IN (' + placeholders.join(',') + ')';
                    vals.forEach(function(v, i) {
                        if (col === 'estado') {
                            params['f_' + col + '_' + i] = { type: db.sql.Bit, value: String(v).trim() === '1' || String(v).trim() === 'true' ? 1 : 0 };
                        } else {
                            params['f_' + col + '_' + i] = { type: db.sql.NVarChar(100), value: String(v).trim() };
                        }
                    });
                }
            }
        }

        if (await dh.tryDistinct(req, res, { db, table: 'sucursales', alias: 's', joins: 'LEFT JOIN empresas e ON s.id_empresa = e.id_empresa', colMap: colMapSuc, where, params, bitColumns: ['estado'] })) return;

        var sqlCount = 'SELECT COUNT(*) as total FROM sucursales s LEFT JOIN empresas e ON s.id_empresa = e.id_empresa' + where;
        var countResult = await db.query(sqlCount, params);
        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / Math.abs(limit));

        var orderPrefix = ['id_empresa', 'empresa_razon'].indexOf(sort) >= 0 ? '' : 's.';

        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT s.id_sucursal, s.codigo, s.nombre, s.direccion, s.telefono, s.estado, s.id_empresa, e.razon_social AS empresa_razon FROM sucursales s LEFT JOIN empresas e ON s.id_empresa = e.id_empresa' + where + ' ORDER BY ' + orderPrefix + sort + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT s.id_sucursal, s.codigo, s.nombre, s.direccion, s.telefono, s.estado, s.id_empresa, e.razon_social AS empresa_razon FROM sucursales s LEFT JOIN empresas e ON s.id_empresa = e.id_empresa' + where + ' ORDER BY ' + orderPrefix + sort + ' ' + 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('[MAESTRAS] Error sucursales:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar sucursales' });
    }
});

router.get('/sucursales/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        var data = await db.query('SELECT id_sucursal, codigo, nombre, direccion, telefono, estado, id_empresa FROM sucursales WHERE id_sucursal = @id AND id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Sucursal no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[MAESTRAS] Error sucursal:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al consultar sucursal' });
    }
});

router.post('/sucursales', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.body.id_empresa);
        var codigo = req.body.codigo ? req.body.codigo.trim() : '';
        if (!codigo) {
            var codigos = await db.query('SELECT codigo FROM sucursales WHERE id_empresa = @emp', {
                emp: { type: db.sql.Int, value: idEmpresa }
            });
            var maxNum = 0;
            codigos.forEach(function(r) {
                var n = parseInt(r.codigo, 10);
                if (!isNaN(n) && n > maxNum) maxNum = n;
            });
            codigo = ('000' + (maxNum + 1)).slice(-3);
        }
        var dup = await db.query('SELECT COUNT(*) as cnt FROM sucursales WHERE codigo = @cod AND id_empresa = @emp', {
            cod: { type: db.sql.NVarChar(20), value: codigo },
            emp: { type: db.sql.Int, value: idEmpresa }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de sucursal ya existe para esta empresa' });
        }
        var sql = 'INSERT INTO sucursales (id_empresa, codigo, nombre, direccion, telefono, estado) VALUES (@id_empresa, @codigo, @nombre, @direccion, @telefono, @estado); SELECT SCOPE_IDENTITY() as id';
        var result = await db.query(sql, {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            codigo: { type: db.sql.NVarChar(20), value: codigo },
            nombre: { type: db.sql.NVarChar(200), value: req.body.nombre },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || null },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || null },
            estado: { type: db.sql.Bit, value: req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1 }
        });
        res.json({ ok: true, mensaje: 'Sucursal registrada', data: { id_sucursal: result[0].id, codigo: codigo } });
    } catch (error) {
        console.error('[MAESTRAS] Error crear sucursal:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al registrar sucursal' });
    }
});

router.put('/sucursales/:id', async function(req, res) {
    try {
        var id_empresa = req.query.id_empresa || req.body.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        if (!req.body.codigo) {
            var current = await db.query('SELECT codigo FROM sucursales WHERE id_sucursal = @id AND id_empresa = @emp', {
                id: { type: db.sql.Int, value: parseInt(req.params.id) },
                emp: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            req.body.codigo = current[0] ? current[0].codigo : '';
        }
        var dup = await db.query('SELECT COUNT(*) as cnt FROM sucursales WHERE codigo = @cod AND id_empresa = @emp AND id_sucursal != @id', {
            cod: { type: db.sql.NVarChar(20), value: req.body.codigo },
            emp: { type: db.sql.Int, value: parseInt(id_empresa) },
            id: { type: db.sql.Int, value: parseInt(req.params.id) }
        });
        if (dup[0].cnt > 0) {
            return res.status(400).json({ ok: false, mensaje: 'El código de sucursal ya existe en otro registro' });
        }
        var sql = 'UPDATE sucursales SET codigo = @codigo, nombre = @nombre, direccion = @direccion, telefono = @telefono, estado = @estado WHERE id_sucursal = @id AND id_empresa = @id_empresa';
        await db.execute(sql, {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) },
            codigo: { type: db.sql.NVarChar(20), value: req.body.codigo },
            nombre: { type: db.sql.NVarChar(200), value: req.body.nombre },
            direccion: { type: db.sql.NVarChar(200), value: req.body.direccion || null },
            telefono: { type: db.sql.NVarChar(20), value: req.body.telefono || null },
            estado: { type: db.sql.Bit, value: req.body.estado ? 1 : 0 }
        });
        res.json({ ok: true, mensaje: 'Sucursal actualizada' });
    } catch (error) {
        console.error('[MAESTRAS] Error actualizar sucursal:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar sucursal' });
    }
});

router.delete('/sucursales/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var id_empresa = req.query.id_empresa;
        if (!id_empresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });

        var total = 0;
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM articulos WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM cab_pedido WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM cab_orden_compra WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM guias_remision WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM movimiento_almacen WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM cab_saldos_iniciales WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM correlativos_documentos WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM usuarios WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM proveedores WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM clientes WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM vendedores WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM choferes WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM empleados WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}
        try { var r = await db.query('SELECT COALESCE((SELECT COUNT(*) FROM bancos WHERE id_sucursal = @id), 0) as cnt', { id: { type: db.sql.Int, value: id } }); total += r[0].cnt; } catch(e) {}

        if (total > 0) {
            await db.execute('UPDATE sucursales SET estado = 0 WHERE id_sucursal = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'La sucursal tiene registros asociados, se ha desactivado' });
        } else {
            await db.execute('DELETE FROM sucursales WHERE id_sucursal = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(id_empresa) }
            });
            res.json({ ok: true, mensaje: 'Sucursal eliminada' });
        }
    } catch (error) {
        console.error('[MAESTRAS] Error eliminar sucursal:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar sucursal' });
    }
});

module.exports = router;
