<?php

namespace SoftminalB2B\Cart;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Adds many lines to the WooCommerce cart in one pass (FEATURES F1).
 *
 * The single trusted path shared by the bulk order form's "Add all to cart" and
 * a saved list's "Reorder". Each line is validated against stock and its
 * quantity rule *before* adding, because WC_Cart::add_to_cart() does not run the
 * `woocommerce_add_to_cart_validation` filter — so without this, a bulk add
 * would silently bypass min/max/step. Valid lines are added; invalid ones are
 * reported per line rather than failing the whole batch.
 */
class BulkAdder
{
    /**
     * @param array<int, array<string, mixed>> $lines each {product_id, variation_id, quantity}
     * @return array{added:int, skipped:array<int, array{name:string, reason:string}>}
     */
    public static function add(array $lines): array
    {
        // Load the buyer's cart session inside the REST request.
        if (null === WC()->cart) {
            wc_load_cart();
        }

        $added   = 0;
        $skipped = [];

        foreach ($lines as $line) {
            $productId   = absint($line['product_id'] ?? 0);
            $variationId = absint($line['variation_id'] ?? 0);
            $quantity    = absint($line['quantity'] ?? 0);

            if ($productId <= 0 || $quantity <= 0) {
                continue;
            }

            $product = wc_get_product($variationId ?: $productId);

            if (!$product || !$product->is_purchasable() || !$product->is_in_stock()) {
                $skipped[] = self::skip($product, __('is not available to buy', 'softminal-b2b-wholesale-for-woocommerce'));
                continue;
            }

            $rule = QuantityRules::forProduct($productId, $variationId ?: null);

            if ($rule) {
                // Judge the line on the running total — what this rule already
                // governs in the cart (including earlier lines added in this same
                // batch) plus what we are about to add — so a bulk add can't push
                // a product past its maximum one line at a time.
                $existing  = QuantityRules::cartQuantityForRule($rule, $productId, $variationId ?: 0);
                $violation = $rule->violationFor($existing + $quantity, $product->get_name());

                if ($violation !== null) {
                    $skipped[] = ['name' => $product->get_name(), 'reason' => $violation];
                    continue;
                }
            }

            $result = WC()->cart->add_to_cart($productId, $quantity, $variationId);

            if ($result) {
                $added++;
            } else {
                $skipped[] = self::skip($product, __('could not be added', 'softminal-b2b-wholesale-for-woocommerce'));
            }
        }

        return ['added' => $added, 'skipped' => $skipped];
    }

    /**
     * @return array{name:string, reason:string}
     */
    private static function skip(?\WC_Product $product, string $reason): array
    {
        return [
            'name'   => $product ? $product->get_name() : __('A product', 'softminal-b2b-wholesale-for-woocommerce'),
            'reason' => $reason,
        ];
    }
}
