<?php

namespace SoftminalB2B\Storefront;

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

use SoftminalB2B\Cart\QuantityRules;

/**
 * "Order again" from the account order history (FEATURES F — Ordering UX).
 *
 * Repeat ordering is the core B2B behaviour, and WooCommerce only offers it as
 * a button on the single order page, for completed orders. This puts it one
 * click from the orders list and re-adds the whole basket, priced at the
 * buyer's *current* B2B rates (the resolver runs on the cart) and clamped to
 * whatever quantity rules apply now — so a reorder never lands below a minimum
 * that was introduced after the original order.
 */
class Reorder
{
    private const ACTION = 'smb2b_reorder';

    private static bool $registered = false;

    public static function init(): void
    {
        if (self::$registered) {
            return;
        }

        self::$registered = true;

        add_filter('woocommerce_my_account_my_orders_actions', [self::class, 'addAction'], 10, 2);
        add_action('template_redirect', [self::class, 'handle']);
    }

    /**
     * Add the "Order again" button to each row of the account orders table.
     *
     * @param array<string, array{url:string, name:string}> $actions
     * @param \WC_Order $order
     * @return array<string, array{url:string, name:string}>
     */
    public static function addAction($actions, $order)
    {
        if (!$order instanceof \WC_Order || !$order->get_item_count()) {
            return $actions;
        }

        $actions[self::ACTION] = [
            'url'  => wp_nonce_url(
                add_query_arg(self::ACTION, $order->get_id(), wc_get_page_permalink('myaccount')),
                self::ACTION . ':' . $order->get_id()
            ),
            'name' => __('Order again', 'softminal-b2b-wholesale-for-woocommerce'),
        ];

        return $actions;
    }

    /**
     * Re-add an order's items to the cart, then send the buyer to the cart.
     */
    public static function handle(): void
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce checked below.
        if (empty($_GET[self::ACTION]) || !function_exists('WC') || !WC()->cart) {
            return;
        }

        $orderId = absint($_GET[self::ACTION]);
        $nonce   = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';

        if (!$orderId || !wp_verify_nonce($nonce, self::ACTION . ':' . $orderId)) {
            wc_add_notice(__('That reorder link has expired. Please try again from your orders.', 'softminal-b2b-wholesale-for-woocommerce'), 'error');
            return;
        }

        $order  = wc_get_order($orderId);
        $userId = get_current_user_id();

        // Only the order's own customer may reorder it.
        if (!$order || $userId <= 0 || (int) $order->get_customer_id() !== $userId) {
            wc_add_notice(__('You are not allowed to reorder that order.', 'softminal-b2b-wholesale-for-woocommerce'), 'error');
            return;
        }

        $added   = 0;
        $skipped = 0;

        foreach ($order->get_items() as $item) {
            if (!$item instanceof \WC_Order_Item_Product) {
                continue;
            }

            $productId   = (int) $item->get_product_id();
            $variationId = (int) $item->get_variation_id();
            $product     = $item->get_product();

            if (!$product || !$product->is_purchasable() || !$product->is_in_stock()) {
                $skipped++;
                continue;
            }

            $qty = max(1, (int) $item->get_quantity());

            // Clamp to the buyer's current quantity rule (min/pack), so an old
            // quantity can't reintroduce an invalid line at add time.
            $rule = QuantityRules::forProduct($productId, $variationId ?: null);
            if ($rule) {
                $qty = $rule->nearestValid($qty);
            }

            $variation = $variationId ? wc_get_product($variationId) : null;
            $attributes = ($variationId && $variation instanceof \WC_Product_Variation)
                ? $variation->get_variation_attributes()
                : [];

            if (WC()->cart->add_to_cart($productId, $qty, $variationId, $attributes)) {
                $added++;
            } else {
                $skipped++;
            }
        }

        if ($added > 0) {
            $message = sprintf(
                /* translators: %d: number of items added */
                _n('%d item from your order was added to the cart.', '%d items from your order were added to the cart.', $added, 'softminal-b2b-wholesale-for-woocommerce'),
                $added
            );

            if ($skipped > 0) {
                $message .= ' ' . sprintf(
                    /* translators: %d: number of items skipped */
                    _n('%d item was unavailable and skipped.', '%d items were unavailable and skipped.', $skipped, 'softminal-b2b-wholesale-for-woocommerce'),
                    $skipped
                );
            }

            wc_add_notice($message, 'success');
            wp_safe_redirect(wc_get_cart_url());
            exit;
        }

        wc_add_notice(
            __('None of those items could be reordered — they may be out of stock or no longer sold.', 'softminal-b2b-wholesale-for-woocommerce'),
            'error'
        );

        wp_safe_redirect(wc_get_account_endpoint_url('orders'));
        exit;
    }
}
