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

function buildWhere(req) {
    var idEmpresa = parseInt(req.query.id_empresa);
    var buscar = req.query.buscar || '';
    var fecha = req.query.fecha || new Date().toISOString().slice(0, 10);
    var tipo = req.query.tipo || '';
    var idFamilia = parseInt(req.query.id_familia) || 0;

    var conditions = ['m.id_empresa = @id_empresa', 'CONVERT(DATE, m.fecha_movimiento) = @fecha'];
    var params = {
        id_empresa: { type: db.sql.Int, value: idEmpresa },
        fecha: { type: db.sql.Date, value: new Date(fecha + 'T00:00:00') }
    };
    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 OR m.documento LIKE @buscar)");
        params.buscar = { type: db.sql.NVarChar, value: '%' + buscar + '%' };
    }
    if (tipo && (tipo === 'E' || tipo === 'S')) {
        conditions.push("m.tipo = @tipo");
        params.tipo = { type: db.sql.Char(1), value: tipo };
    }
    if (idFamilia > 0) {
        conditions.push("a.id_familia = @id_familia");
        params.id_familia = { type: db.sql.Int, value: idFamilia };
    }

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

router.get('/movimientos-dia', function(req, res) {
    var limit = parseInt(req.query.limit) || 50;
    var page = parseInt(req.query.page) || 1;
    var offset = (page - 1) * limit;
    var built = buildWhere(req);

    var sort = req.query.sort || 'm.fecha_movimiento';
    var order = (req.query.order || 'DESC').toUpperCase();
    var orderMap = {
        'm.fecha_movimiento': 'm.fecha_movimiento',
        'cod_articulo': 'a.cod_articulo',
        'nom_art': 'a.nombre',
        'm.tipo': 'm.tipo',
        'm.costo_total': 'm.costo_total'
    };
    var sortCol = orderMap[sort] || 'm.fecha_movimiento';
    var orderSql = sortCol + ' ' + (order === 'DESC' ? 'DESC' : 'ASC') + ', m.id_movimiento ASC';

    var dataSql = `
        SELECT
            m.id_movimiento,
            m.fecha_movimiento,
            m.tipo,
            m.documento,
            m.id_documento,
            ISNULL(m.cantidad, 0) AS cantidad,
            ISNULL(m.costo_unitario, 0) AS costo_unitario,
            ISNULL(m.costo_total, 0) AS costo_total,
            a.id_articulo,
            a.cod_articulo,
            a.cod_vta,
            a.nombre AS nom_art,
            ISNULL(f.nombre, '') AS nom_fam,
            a.id_familia,
            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
        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}
        ORDER BY ${orderSql}
        OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY
    `;

    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}
    `;

    var params = Object.assign({}, built.params);
    params.offset = { type: db.sql.Int, value: offset };
    params.limit = { type: db.sql.Int, value: limit };

    var conn = db.getPool();
    conn.then(function(pool) {
        var countReq = new db.sql.Request(pool);
        Object.keys(built.params).forEach(function(k) {
            countReq.input(k, built.params[k].type, built.params[k].value);
        });
        countReq.query(countSql, function(err, countResult) {
            if (err) {
                console.error('[MOVIMIENTOS-DIA] Count error:', err.message);
                return res.json({ ok: false, error: err.message });
            }
            var total = countResult.recordset[0].total;
            var totalPaginas = Math.ceil(total / limit) || 1;

            var dataReq = new db.sql.Request(pool);
            Object.keys(params).forEach(function(k) {
                dataReq.input(k, params[k].type, params[k].value);
            });
            dataReq.query(dataSql, function(err2, result) {
                if (err2) {
                    console.error('[MOVIMIENTOS-DIA] Query error:', err2.message);
                    return res.json({ ok: false, error: err2.message });
                }
                res.json({
                    ok: true,
                    data: result.recordset || [],
                    total: total,
                    pagina: page,
                    totalPaginas: totalPaginas,
                    limit: limit
                });
            });
        });
    }).catch(function(err) {
        res.json({ ok: false, error: err.message });
    });
});

router.get('/movimientos-dia/totales', function(req, res) {
    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 entradas_cant,
            SUM(CASE WHEN m.tipo = 'E' THEN ISNULL(m.costo_total, 0) ELSE 0 END) AS entradas_valor,
            SUM(CASE WHEN m.tipo = 'S' THEN ISNULL(m.cantidad, 0) ELSE 0 END) AS salidas_cant,
            SUM(CASE WHEN m.tipo = 'S' THEN ISNULL(m.costo_total, 0) ELSE 0 END) AS salidas_valor,
            COUNT(DISTINCT m.id_articulo) AS articulos_distintos
        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 conn = db.getPool();
    conn.then(function(pool) {
        var req2 = new db.sql.Request(pool);
        Object.keys(built.params).forEach(function(k) {
            req2.input(k, built.params[k].type, built.params[k].value);
        });
        req2.query(sql, function(err, result) {
            if (err) return res.json({ ok: false, error: err.message });
            var r = result.recordset[0] || {};
            res.json({
                ok: true,
                total_movimientos: r.total_movimientos || 0,
                entradas_cant: r.entradas_cant || 0,
                entradas_valor: r.entradas_valor || 0,
                salidas_cant: r.salidas_cant || 0,
                salidas_valor: r.salidas_valor || 0,
                articulos_distintos: r.articulos_distintos || 0
            });
        });
    }).catch(function(err) {
        res.json({ ok: false, error: err.message });
    });
});

router.get('/movimientos-dia/familias', function(req, res) {
    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 whereExtra = 'm.id_empresa = @id_empresa AND f.nombre IS NOT NULL';
    var params = { id_empresa: { type: db.sql.Int, value: idEmpresa } };
    if (idSucursal) {
        whereExtra += ' AND m.id_sucursal = @id_sucursal';
        params.id_sucursal = { type: db.sql.Int, value: idSucursal };
    }

    var sql = `
        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 ${whereExtra}
        ORDER BY f.nombre
    `;

    var conn = db.getPool();
    conn.then(function(pool) {
        var req2 = new db.sql.Request(pool);
        Object.keys(params).forEach(function(k) {
            req2.input(k, params[k].type, params[k].value);
        });
        req2.query(sql, function(err, result) {
            if (err) return res.json({ ok: false, error: err.message });
            res.json({ ok: true, data: result.recordset || [] });
        });
    }).catch(function(err) {
        res.json({ ok: false, error: err.message });
    });
});

module.exports = router;
