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

function getColSql(col) {
    var map = {
        'cod_articulo': 'a.cod_articulo',
        'nom_art': 'a.nombre',
        'nom_fam': 'f.nombre',
        'fecha_movimiento': 'm.fecha_movimiento',
        'tipo': 'm.tipo',
        'documento': 'm.documento'
    };
    return map[col] || 'a.cod_articulo';
}

function buildWhere(req) {
    var idEmpresa = parseInt(req.query.id_empresa);
    var buscar = req.query.buscar || '';
    var fechaDesde = req.query.fecha_desde || '';
    var fechaHasta = req.query.fecha_hasta || '';

    var conditions = ['m.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) {
        conditions.push('m.id_sucursal = @id_sucursal');
        params.id_sucursal = { type: db.sql.Int, value: idSucursal };
    }

    if (buscar) {
        conditions.push("(a.cod_articulo LIKE @buscar OR a.nombre LIKE @buscar)");
        params.buscar = { type: db.sql.NVarChar, value: '%' + buscar + '%' };
    }
    if (fechaDesde) {
        conditions.push("CONVERT(DATE, m.fecha_movimiento) >= @fecha_desde");
        params.fecha_desde = { type: db.sql.Date, value: new Date(fechaDesde + 'T00:00:00') };
    }
    if (fechaHasta) {
        conditions.push("CONVERT(DATE, m.fecha_movimiento) <= @fecha_hasta");
        params.fecha_hasta = { type: db.sql.Date, value: new Date(fechaHasta + 'T00:00:00') };
    }

    if (req.query.filtros) {
        try {
            var filtros = JSON.parse(req.query.filtros);
            for (var col in filtros) {
                if (filtros.hasOwnProperty(col) && filtros[col]) {
                    var vals = (Array.isArray(filtros[col]) ? filtros[col] : String(filtros[col]).split('\x01')).map(function(v) { return v.trim(); });
                    if (vals.length === 1) {
                        if (col === 'tipo') {
                            conditions.push("m.tipo = @filtro_tipo");
                            params['filtro_tipo'] = { type: db.sql.Char(1), value: vals[0] };
                        } else {
                            conditions.push(getColSql(col) + ' LIKE @filtro_' + col);
                            params['filtro_' + col] = { type: db.sql.NVarChar, value: '%' + vals[0] + '%' };
                        }
                    } else {
                        if (col === 'tipo') {
                            var tipoPlaceholders = vals.map(function(_, i) { return '@filtro_tipo_' + i; }).join(',');
                            conditions.push("m.tipo IN (" + tipoPlaceholders + ")");
                            vals.forEach(function(v, i) {
                                params['filtro_tipo_' + i] = { type: db.sql.Char(1), value: v };
                            });
                        } else {
                            var likeParts = vals.map(function(v, i) {
                                return getColSql(col) + ' LIKE @filtro_' + col + '_' + i;
                            });
                            conditions.push('(' + likeParts.join(' OR ') + ')');
                            vals.forEach(function(v, i) {
                                params['filtro_' + col + '_' + i] = { type: db.sql.NVarChar, value: '%' + v + '%' };
                            });
                        }
                    }
                }
            }
        } catch(e) {}
    }

    return { where: conditions.join(' AND '), params: params };
}

function buildOrderSql(req) {
    var sort = req.query.sort || 'sub.fecha_movimiento';
    var order = (req.query.order || 'ASC').toUpperCase();
    var orderMap = {
        'sub.fecha_movimiento': 'sub.fecha_movimiento',
        'sub.cod_articulo': 'sub.cod_articulo',
        'sub.nom_art': 'sub.nom_art',
        'sub.tipo': 'sub.tipo',
        'sub.cantidad': 'sub.cantidad',
        'sub.costo_total': 'sub.costo_total'
    };
    var col = orderMap[sort] || 'sub.fecha_movimiento';
    return col + ' ' + (order === 'DESC' ? 'DESC' : 'ASC') + ', sub.id_movimiento ASC';
}

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

        var limit = req.query.limit !== undefined ? parseInt(req.query.limit) : 50;
        var page = parseInt(req.query.page) || 1;
        var offset = (page - 1) * limit;
        var built = buildWhere(req);
        var orderSql = buildOrderSql(req);

        var params = Object.assign({}, built.params);

        var selectColumns = "a.cod_articulo, a.cod_vta, a.nombre AS nom_art, a.id_articulo, ISNULL(f.nombre, '') AS nom_fam, a.id_familia, m.id_movimiento, m.fecha_movimiento, m.tipo, m.documento, m.id_documento, (SELECT STRING_AGG(x.oc_ref, ', ') FROM (SELECT DISTINCT CAST(d.ejercicio AS VARCHAR) + '-' + d.num_oc AS oc_ref FROM guias_remision_det d WHERE d.id_guia = m.id_documento AND d.id_empresa = m.id_empresa AND d.num_oc IS NOT NULL) x) AS num_ocs, ISNULL(m.cantidad, 0) AS cantidad, ISNULL(m.costo_unitario, 0) AS costo_unitario, ISNULL(m.costo_total, 0) AS costo_total, SUM(CASE WHEN m.tipo = 'E' THEN ISNULL(m.cantidad, 0) ELSE -ISNULL(m.cantidad, 0) END) OVER (PARTITION BY m.id_articulo ORDER BY m.fecha_movimiento, m.id_movimiento ROWS UNBOUNDED PRECEDING) AS saldo_cantidad, SUM(CASE WHEN m.tipo = 'E' THEN ISNULL(m.costo_total, 0) ELSE -ISNULL(m.costo_total, 0) END) OVER (PARTITION BY m.id_articulo ORDER BY m.fecha_movimiento, m.id_movimiento ROWS UNBOUNDED PRECEDING) AS saldo_valor";

        var sql = "SELECT sub.* FROM (SELECT " + selectColumns + " FROM movimiento_almacen m INNER JOIN articulos a ON m.id_articulo = a.id_articulo AND m.id_empresa = a.id_empresa LEFT JOIN familias f ON a.id_empresa = f.id_empresa AND a.id_familia = f.id_familia WHERE " + built.where + ") sub ORDER BY " + orderSql;
        var countSql = "SELECT COUNT(*) AS total FROM movimiento_almacen m INNER JOIN articulos a ON m.id_articulo = a.id_articulo AND m.id_empresa = a.id_empresa LEFT JOIN familias f ON a.id_empresa = f.id_empresa AND a.id_familia = f.id_familia WHERE " + built.where;

        if (limit > 0) {
            sql += " 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 result = await db.query(sql, params);
        var countResult = await db.query(countSql, built.params);
        var total = countResult[0] ? countResult[0].total : 0;
        var totalPaginas = limit > 0 ? Math.ceil(total / limit) : 1;

        res.json({ ok: true, data: result, total: total, pagina: page, totalPaginas: totalPaginas, limit: limit });
    } catch (err) {
        console.error('[KARDEX-VALORIZADO] Error:', err.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + err.message });
    }
});

router.get('/kardex-valorizado/totales', async function(req, res) {
    try {
        var built = buildWhere(req);
        var sql = "SELECT COUNT(*) AS total_movimientos, SUM(CASE WHEN m.tipo = 'E' THEN ISNULL(m.cantidad, 0) ELSE 0 END) AS total_entradas_cant, SUM(CASE WHEN m.tipo = 'E' THEN ISNULL(m.costo_total, 0) ELSE 0 END) AS total_entradas_valor, SUM(CASE WHEN m.tipo = 'S' THEN ISNULL(m.cantidad, 0) ELSE 0 END) AS total_salidas_cant, SUM(CASE WHEN m.tipo = 'S' THEN ISNULL(m.costo_total, 0) ELSE 0 END) AS total_salidas_valor, COUNT(DISTINCT m.id_articulo) AS total_articulos FROM movimiento_almacen m INNER JOIN articulos a ON m.id_articulo = a.id_articulo AND m.id_empresa = a.id_empresa LEFT JOIN familias f ON a.id_empresa = f.id_empresa AND a.id_familia = f.id_familia WHERE " + built.where;
        var result = await db.query(sql, built.params);
        var r = result[0] || {};
        res.json({
            ok: true,
            total_movimientos: r.total_movimientos || 0,
            total_entradas_cant: r.total_entradas_cant || 0,
            total_entradas_valor: r.total_entradas_valor || 0,
            total_salidas_cant: r.total_salidas_cant || 0,
            total_salidas_valor: r.total_salidas_valor || 0,
            total_articulos: r.total_articulos || 0
        });
    } catch (err) {
        console.error('[KARDEX-VALORIZADO] Error totales:', err.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + err.message });
    }
});

router.get('/kardex-valorizado/familias', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.query.id_empresa);
        if (!idEmpresa) return res.json({ ok: true, data: [] });
        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;

        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };
        var conditions = ['m.id_empresa = @id_empresa'];
        if (idSucursal) {
            conditions.push('m.id_sucursal = @id_sucursal');
            params.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }
        var result = await db.query("SELECT DISTINCT f.id_familia, f.nombre AS nom_fam FROM movimiento_almacen m INNER JOIN articulos a ON m.id_articulo = a.id_articulo AND m.id_empresa = a.id_empresa LEFT JOIN familias f ON a.id_empresa = f.id_empresa AND a.id_familia = f.id_familia WHERE " + conditions.join(' AND ') + " AND f.nombre IS NOT NULL ORDER BY f.nombre", params);
        res.json({ ok: true, data: result });
    } catch (err) {
        console.error('[KARDEX-VALORIZADO] Error familias:', err.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + err.message });
    }
});

router.get('/kardex-valorizado/articulos', async function(req, res) {
    try {
        var idEmpresa = parseInt(req.query.id_empresa);
        if (!idEmpresa) return res.json({ ok: true, data: [] });
        var idSucursal = req.query.id_sucursal ? parseInt(req.query.id_sucursal) : null;

        var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };
        var conditions = ['m.id_empresa = @id_empresa'];
        if (idSucursal) {
            conditions.push('m.id_sucursal = @id_sucursal');
            params.id_sucursal = { type: db.sql.Int, value: idSucursal };
        }
        var result = await db.query("SELECT DISTINCT a.id_articulo, a.cod_articulo, a.nombre AS nom_art FROM movimiento_almacen m INNER JOIN articulos a ON m.id_articulo = a.id_articulo AND m.id_empresa = a.id_empresa WHERE " + conditions.join(' AND ') + " ORDER BY a.cod_articulo", params);
        res.json({ ok: true, data: result });
    } catch (err) {
        console.error('[KARDEX-VALORIZADO] Error articulos:', err.message);
        res.status(500).json({ ok: false, mensaje: 'Error: ' + err.message });
    }
});

module.exports = router;