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

router.get('/costos-iniciales', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.query.id_empresa);
        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });

        var page = parseInt(req.query.page) || 1;
        var limit = parseInt(req.query.limit) || 50;
        var offset = (page - 1) * limit;
        var buscar = req.query.buscar || '';
        var filtroFamilia = req.query.familia || '';

        var where = 'WHERE a.id_empresa = @id_empresa';
        var countParams = {
            id_empresa: { type: db.sql.Int, value: idEmpresa }
        };
        var dataParams = {
            id_empresa: { type: db.sql.Int, value: idEmpresa },
            offset: { type: db.sql.Int, value: offset },
            limit: { type: db.sql.Int, value: limit }
        };

        if (idSucursal) {
            where += ' AND a.id_sucursal = @id_sucursal';
            countParams.id_sucursal = { type: db.sql.Int, value: idSucursal };
            dataParams.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }

        if (buscar) {
            where += ' AND (a.nombre LIKE @buscar OR a.cod_articulo LIKE @buscar)';
            countParams.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
            dataParams.buscar = { type: db.sql.NVarChar(100), value: '%' + buscar + '%' };
        }
        if (filtroFamilia) {
            where += ' AND a.id_familia = @familia';
            countParams.familia = { type: db.sql.Int, value: filtroFamilia };
            dataParams.familia = { type: db.sql.Int, value: filtroFamilia };
        }

        var countSql = 'SELECT COUNT(*) as total FROM articulos a ' + where;
        var dataSql = `
            SELECT a.id_articulo, a.cod_articulo, a.nombre,
                   ISNULL(a.stock, 0) as stock,
                   ISNULL(a.costo_promedio, 0) as costo_promedio,
                   ISNULL(a.costo_anterior, 0) as costo_anterior,
                   a.id_familia,
                   f.descripcion as familia_nombre
            FROM articulos a
            LEFT JOIN familias f ON a.id_familia = f.id_familia
            ${where}
            ORDER BY a.nombre
            OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY
        `;

        var result = await db.query(dataSql, dataParams);
        var countResult = await db.query(countSql, countParams);

        var total = countResult[0].total;
        var totalPaginas = Math.ceil(total / limit);

        res.json({ ok: true, data: result, total: total, totalPaginas: totalPaginas });
    } catch (error) {
        console.error('[COSTOS_INICIALES] Error listar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error al listar: ' + error.message });
    }
});

router.get('/costos-iniciales/familias', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.query.id_empresa);
        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;
        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });

        var sql = 'SELECT id_familia, descripcion FROM familias WHERE id_empresa = @id_empresa';
        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };

        if (idSucursal) {
            sql += ' AND id_sucursal = @id_sucursal';
            params.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }
        sql += ' ORDER BY descripcion';

        var result = await db.query(sql, params);
        res.json({ ok: true, data: result });
    } catch (error) {
        console.error('[COSTOS_INICIALES] Error familias:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + error.message });
    }
});

router.put('/costos-iniciales', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.body.id_empresa);
        var cambios = req.body.cambios || [];

        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        if (cambios.length === 0) return res.status(400).json({ ok: false, mensaje: 'No hay cambios para guardar' });

        var pool = await db.getPool();
        var transaction = pool.transaction();
        await transaction.begin();

        try {
            for (var i = 0; i < cambios.length; i++) {
                var cambio = cambios[i];
                if (!cambio.id_articulo || cambio.costo_unitario === undefined || cambio.costo_unitario === null) continue;

                var costoNuevo = parseFloat(cambio.costo_unitario);
                if (costoNuevo < 0) {
                    await transaction.rollback();
                    return res.status(400).json({ ok: false, mensaje: 'El costo no puede ser negativo' });
                }

                var getReq = new db.sql.Request(transaction);
                getReq.input('id_empresa', db.sql.Int, idEmpresa);
                getReq.input('id_sucursal', db.sql.Int, req.body.id_sucursal || null);
                getReq.input('id_articulo', db.sql.Int, cambio.id_articulo);
                var sqlGet = 'SELECT costo_promedio FROM articulos WHERE id_empresa = @id_empresa AND id_articulo = @id_articulo';
                if (req.body.id_sucursal) sqlGet += ' AND id_sucursal = @id_sucursal';
                
                var artResult = await getReq.query(sqlGet);
                var costoAnterior = artResult.recordset.length > 0 ? artResult.recordset[0].costo_promedio : 0;

                var updReq = new db.sql.Request(transaction);
                updReq.input('id_empresa', db.sql.Int, idEmpresa);
                updReq.input('id_sucursal', db.sql.Int, req.body.id_sucursal || null);
                updReq.input('id_articulo', db.sql.Int, cambio.id_articulo);
                updReq.input('costo_nuevo', db.sql.Decimal(12, 4), costoNuevo);
                updReq.input('costo_anterior', db.sql.Decimal(12, 4), costoAnterior);
                
                var sqlUpd = `
                    UPDATE articulos
                    SET costo_promedio = @costo_nuevo, costo_anterior = @costo_anterior
                    WHERE id_empresa = @id_empresa AND id_articulo = @id_articulo
                `;
                if (req.body.id_sucursal) sqlUpd += ' AND id_sucursal = @id_sucursal';
                await updReq.query(sqlUpd);
            }

            await transaction.commit();
            res.json({ ok: true, mensaje: 'Costos actualizados (' + cambios.length + ' artículos)' });
        } catch (err) {
            await transaction.rollback();
            throw err;
        }
    } catch (error) {
        console.error('[COSTOS_INICIALES] Error actualizar:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + error.message });
    }
});

router.put('/costos-iniciales/masivo', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.body.id_empresa);
        var idFamilia = parseInt(req.body.id_familia);
        var porcentaje = parseFloat(req.body.porcentaje);

        if (!idEmpresa) return res.status(400).json({ ok: false, mensaje: 'id_empresa es requerido' });
        if (!idFamilia) return res.status(400).json({ ok: false, mensaje: 'Seleccione una familia' });
        if (isNaN(porcentaje)) return res.status(400).json({ ok: false, mensaje: 'Ingrese el porcentaje' });

        var factor = 1 + (porcentaje / 100);

        var pool = await db.getPool();
        var transaction = pool.transaction();
        await transaction.begin();

        try {
            var updReq = new db.sql.Request(transaction);
            updReq.input('id_empresa', db.sql.Int, idEmpresa);
            updReq.input('id_sucursal', db.sql.Int, req.body.id_sucursal || null);
            updReq.input('id_familia', db.sql.Int, idFamilia);
            updReq.input('factor', db.sql.Decimal(8, 4), factor);
            
            var sqlUpd = `
                UPDATE a
                SET a.costo_promedio = CASE WHEN a.costo_promedio > 0 THEN a.costo_promedio * @factor ELSE a.costo_promedio END,
                    a.costo_anterior = a.costo_promedio
                FROM articulos a
                WHERE a.id_empresa = @id_empresa AND a.id_familia = @id_familia
            `;
            if (req.body.id_sucursal) sqlUpd += ' AND a.id_sucursal = @id_sucursal';
            await updReq.query(sqlUpd);

            await transaction.commit();
            res.json({ ok: true, mensaje: 'Costos ajustados (' + (porcentaje >= 0 ? '+' : '') + porcentaje + '%)' });
        } catch (err) {
            await transaction.rollback();
            throw err;
        }
    } catch (error) {
        console.error('[COSTOS_INICIALES] Error masivo:', error.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + error.message });
    }
});

module.exports = router;