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


// ...


async function generarCodigoSubfamilia(idEmpresa) {
    var rows = await db.query(
        "SELECT cod_subfamilia FROM subfamilias WHERE id_empresa = @emp AND cod_subfamilia LIKE 'SF%'",
        { emp: { type: db.sql.Int, value: idEmpresa } }
    );
    var maxNum = 0;
    for (var i = 0; i < rows.length; i++) {
        var num = parseInt(rows[i].cod_subfamilia.substring(2), 10);
        if (!isNaN(num) && num > maxNum) maxNum = num;
    }
    return 'SF' + String(maxNum + 1).padStart(4, '0');
}

router.get('/subfamilias', async function(req, res) {
    try {
        var buscar = req.query.buscar || '';
        var page = req.query.page !== undefined ? parseInt(req.query.page) : 1;
        var limit = req.query.limit !== undefined ? parseInt(req.query.limit) : 50;
        var sinPaginacion = limit <= 0;
        var sort = req.query.sort || 's.nombre';
        var order = req.query.order === 'DESC' ? 'DESC' : 'ASC';
        var estado = req.query.estado;
        var idFamilia = req.query.id_familia;

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

        if (!req.query.id_empresa) {
            return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        }
        where += ' AND s.id_empresa = @id_empresa';
        params.id_empresa = { type: db.sql.Int, value: parseInt(req.query.id_empresa) };

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

        if (idFamilia) {
            where += ' AND s.id_familia = @id_familia';
            params.id_familia = { type: db.sql.Int, value: parseInt(idFamilia) };
        }

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

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

        var filtros = null;
        var sqlColMapSub = {
            cod_subfamilia: 's.cod_subfamilia',
            nombre: 's.nombre',
            familia_nombre: 'f.nombre',
            descripcion: 's.descripcion',
            estado: 's.estado'
        };
        try {
            filtros = req.query.filtros ? JSON.parse(req.query.filtros) : null;
        } catch (e) {
            console.error('[SUBFAMILIAS] Error parseando filtros:', e.message, 'Raw:', req.query.filtros);
        }
        if (filtros) {
            var typeMap = {
                estado: function(vals) {
                    return vals.map(function(v) { return { type: db.sql.Bit, value: v.trim().toUpperCase() === 'ACTIVO' ? 1 : 0 }; });
                }
            };
            for (var col in filtros) {
                if (!filtros.hasOwnProperty(col)) continue;
                var rawVals = Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01');
                var sqlCol = sqlColMapSub[col] || 's.' + col;
                var mapper = typeMap[col];
                var phs = rawVals.map(function(_, i) { return '@f_' + col + '_' + i; });
                if (typeof mapper === 'function') {
                    var mapped = mapper(rawVals);
                    mapped.forEach(function(p, i) { params['f_' + col + '_' + i] = p; });
                } else {
                    rawVals.forEach(function(v, i) {
                        params['f_' + col + '_' + i] = { type: db.sql.NVarChar(500), value: v.trim() };
                    });
                }
                where += ' AND ' + sqlCol + ' IN (' + phs.join(',') + ')';
            }
        }

        var joinsSub = 'INNER JOIN familias f ON s.id_empresa = f.id_empresa AND s.id_familia = f.id_familia';
        if (await dh.tryDistinct(req, res, { db, table: 'subfamilias', alias: 's', joins: joinsSub, colMap: sqlColMapSub, where, params, bitColumns: ['estado'] })) return;

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

        var allowedSort = { cod_subfamilia: 's.cod_subfamilia', nombre: 's.nombre', familia_nombre: 'f.nombre', estado: 's.estado' };
        var sortCol = allowedSort[sort] || 's.nombre';

        var selectCols = 's.id_subfamilia, s.cod_subfamilia, s.nombre, s.descripcion, s.id_familia, f.nombre AS familia_nombre, f.cod_familia AS familia_codigo, s.estado, s.fecha_creacion, s.id_sucursal';
        var sqlData;
        if (sinPaginacion) {
            sqlData = 'SELECT ' + selectCols + joins + ' ' + where + ' ORDER BY ' + sortCol + ' ' + order;
        } else {
            var offset = (page - 1) * limit;
            sqlData = 'SELECT ' + selectCols + joins + ' ' + where + ' ORDER BY ' + sortCol + ' ' + order + ' OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY';
            params.offset = { type: db.sql.Int, value: offset };
            params.limit = { type: db.sql.Int, value: limit };
        }

        var data = await db.query(sqlData, params);
        res.json({ ok: true, data: data, total: total, totalPaginas: totalPaginas, page: page });
    } catch (error) {
        console.error('[SUBFAMILIAS] Error al listar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al listar subfamilias' });
    }
});

router.get('/subfamilias/:id', async function(req, res) {
    try {
        var idEmpresa = req.query.id_empresa;
        if (!idEmpresa) {
            return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        }
        var data = await db.query('SELECT s.id_subfamilia, s.id_empresa, s.id_familia, s.cod_subfamilia, s.nombre, s.descripcion, s.estado, s.id_sucursal FROM subfamilias s WHERE s.id_subfamilia = @id AND s.id_empresa = @id_empresa', {
            id: { type: db.sql.Int, value: parseInt(req.params.id) },
            id_empresa: { type: db.sql.Int, value: parseInt(idEmpresa) }
        });
        if (data.length === 0) return res.status(404).json({ ok: false, mensaje: 'Subfamilia no encontrada' });
        res.json({ ok: true, data: data[0] });
    } catch (error) {
        console.error('[SUBFAMILIAS] Error al obtener:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al obtener subfamilia' });
    }
});

router.post('/subfamilias', async function(req, res) {
    try {
        var nombre = (req.body.nombre || '').toString().trim().toUpperCase();
        var descripcion = (req.body.descripcion || '').toString().trim().toUpperCase();
        var idFamilia = parseInt(req.body.id_familia);
        var estado = req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1;
        var idEmpresa = parseInt(req.body.id_empresa);
        var idSucursal = req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null;

        if (!nombre) { return res.status(400).json({ ok: false, mensaje: 'El nombre es requerido' }); }
        if (!idFamilia) { return res.status(400).json({ ok: false, mensaje: 'La familia es requerida' }); }
        if (!idEmpresa) { return res.status(400).json({ ok: false, mensaje: 'Empresa requerida' }); }

        var cod = await generarCodigoSubfamilia(idEmpresa);

        var result = await db.query(
            'INSERT INTO subfamilias (id_empresa, id_sucursal, id_familia, cod_subfamilia, nombre, descripcion, estado) VALUES (@id_empresa, @id_sucursal, @id_familia, @cod, @nombre, @descripcion, @estado); SELECT SCOPE_IDENTITY() as id',
            {
                id_empresa: { type: db.sql.Int, value: idEmpresa },
                id_sucursal: { type: db.sql.Int, value: idSucursal },
                id_familia: { type: db.sql.Int, value: idFamilia },
                cod: { type: db.sql.NVarChar(6), value: cod },
                nombre: { type: db.sql.NVarChar(100), value: nombre },
                descripcion: { type: db.sql.NVarChar(200), value: descripcion || null },
                estado: { type: db.sql.Bit, value: estado }
            }
        );
        res.json({ ok: true, mensaje: 'Subfamilia creada', data: { id_subfamilia: result[0].id, cod_subfamilia: cod } });
    } catch (error) {
        console.error('[SUBFAMILIAS] Error al crear:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al crear subfamilia' });
    }
});

router.put('/subfamilias/:id', async function(req, res) {
    try {
        var id = parseInt(req.params.id);
        var idEmpresa = req.query.id_empresa || req.body.id_empresa;
        if (!idEmpresa) {
            return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        }
        idEmpresa = parseInt(idEmpresa);
        var nombre = (req.body.nombre || '').toString().trim().toUpperCase();
        var descripcion = (req.body.descripcion || '').toString().trim().toUpperCase();
        var idFamilia = parseInt(req.body.id_familia);
        var estado = req.body.estado !== undefined ? (req.body.estado ? 1 : 0) : 1;
        var idSucursal = req.body.id_sucursal ? parseInt(req.body.id_sucursal) : null;

        if (!nombre) { return res.status(400).json({ ok: false, mensaje: 'El nombre es requerido' }); }
        if (!idFamilia) { return res.status(400).json({ ok: false, mensaje: 'La familia es requerida' }); }

        await db.execute(
            'UPDATE subfamilias SET id_familia = @id_familia, nombre = @nombre, descripcion = @descripcion, estado = @estado, id_sucursal = @id_sucursal WHERE id_subfamilia = @id AND id_empresa = @id_empresa',
            {
                id_familia: { type: db.sql.Int, value: idFamilia },
                nombre: { type: db.sql.NVarChar(100), value: nombre },
                descripcion: { type: db.sql.NVarChar(200), value: descripcion || null },
                estado: { type: db.sql.Bit, value: estado },
                id_sucursal: { type: db.sql.Int, value: idSucursal },
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: idEmpresa }
            }
        );
        res.json({ ok: true, mensaje: 'Subfamilia actualizada' });
    } catch (error) {
        console.error('[SUBFAMILIAS] Error al actualizar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al actualizar subfamilia' });
    }
});

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

        // Verificar si tiene artículos asociados
        var refs = await db.query('SELECT COUNT(*) as cnt FROM articulos WHERE id_subfamilia = @id AND id_empresa = @id_empresa AND estado = 1', {
            id: { type: db.sql.Int, value: id },
            id_empresa: { type: db.sql.Int, value: parseInt(idEmpresa) }
        });

        if (refs[0].cnt > 0) {
            // Tiene artículos → solo desactivar
            await db.execute('UPDATE subfamilias SET estado = 0 WHERE id_subfamilia = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(idEmpresa) }
            });
            res.json({ ok: true, mensaje: 'Subfamilia desactivada (tiene artículos asociados)' });
        } else {
            // Sin artículos → eliminar físicamente
            await db.execute('DELETE FROM subfamilias WHERE id_subfamilia = @id AND id_empresa = @id_empresa', {
                id: { type: db.sql.Int, value: id },
                id_empresa: { type: db.sql.Int, value: parseInt(idEmpresa) }
            });
            res.json({ ok: true, mensaje: 'Subfamilia eliminada permanentemente' });
        }
    } catch (error) {
        console.error('[SUBFAMILIAS] Error al eliminar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al eliminar subfamilia' });
    }
});

module.exports = router;
