-- Stored Procedure para atualização segura do estoque com movimentação e política de negativo
DROP PROCEDURE IF EXISTS sp_update_product_stock;
DELIMITER $$
CREATE PROCEDURE sp_update_product_stock (
    IN p_product_id BIGINT,
    IN p_delta DECIMAL(18,3),
    IN p_origin_type VARCHAR(50),
    IN p_origin_id BIGINT,
    IN p_origin_number VARCHAR(50),
    IN p_allow_negative TINYINT(1)
)
BEGIN
    DECLARE v_before DECIMAL(18,3);
    DECLARE v_after DECIMAL(18,3);

    SELECT estoque INTO v_before FROM products WHERE id = p_product_id LIMIT 1;
    IF v_before IS NULL THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Produto inexistente para atualização de estoque';
    END IF;

    SET v_after = v_before + p_delta;
    IF p_allow_negative = 0 AND v_after < 0 THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Estoque insuficiente (política negativa desativada)';
    END IF;

    UPDATE products SET estoque = v_after WHERE id = p_product_id;

    -- Registrar movimento (tipo baseado no delta)
    INSERT INTO inventory_movements (product_id, tipo, quantidade, motivo, stock_before, stock_after, origin_type, origin_id, origin_number)
    VALUES (
        p_product_id,
        CASE WHEN p_delta < 0 THEN 'saida_sp' ELSE 'entrada_sp' END,
        p_delta,
        'Atualização via SP',
        v_before,
        v_after,
        p_origin_type,
        p_origin_id,
        p_origin_number
    );
END $$
DELIMITER ;