<?php
if (!defined('ABSPATH')) exit;

/**
 * Check if current frontend product is an auction listing.
 */
function stakmv_is_current_auction_product() {
    if (!is_product()) {
        return false;
    }

    $product_id = get_queried_object_id();
    if ($product_id <= 0) {
        return false;
    }

    $product = wc_get_product($product_id);
    return ($product instanceof WC_Product) && $product->get_type() === 'auction';
}

function stakmv_get_auction_product_template_mode() {
    $mode = (string) stakmv_get_option('auction_product_template', 'template_1');
    if (!in_array($mode, array('template_1', 'default_woo'), true)) {
        $mode = 'template_1';
    }
    return $mode;
}

function stakmv_use_custom_auction_product_page() {
    return stakmv_get_auction_product_template_mode() !== 'default_woo';
}

add_action('wp_enqueue_scripts', function () {

    if (stakmv_is_current_auction_product()) {
        if (stakmv_use_custom_auction_product_page()) {
            $template_mode = stakmv_get_auction_product_template_mode();
            if ($template_mode === 'template_1') {
                $template_file = 'assets/css/auction-product-template-1.css';
                wp_enqueue_style(
                    'stakmv-auction-product-template-1',
                    STAKMV_PLUGIN_URL . $template_file,
                    array('stakmv-theme-colors'),
                    file_exists(STAKMV_PLUGIN_PATH . $template_file)
                        ? (string) filemtime(STAKMV_PLUGIN_PATH . $template_file)
                        : (defined('STAKMV_VERSION') ? STAKMV_VERSION : '1.0.0')
                );

                wp_enqueue_script(
                    'stakmv-auction-gallery',
                    STAKMV_PLUGIN_URL . 'assets/js/auction-gallery.js',
                    array(),
                    file_exists(STAKMV_PLUGIN_PATH . 'assets/js/auction-gallery.js')
                        ? (string) filemtime(STAKMV_PLUGIN_PATH . 'assets/js/auction-gallery.js')
                        : (defined('STAKMV_VERSION') ? STAKMV_VERSION : '1.0.0'),
                    true
                );
            }
        } else {
            $dashboard_css = 'assets/css/vendor-dashboard.css';
            wp_enqueue_style(
                'stakmv-dashboard',
                STAKMV_PLUGIN_URL . $dashboard_css,
                array(),
                file_exists(STAKMV_PLUGIN_PATH . $dashboard_css)
                    ? (string) filemtime(STAKMV_PLUGIN_PATH . $dashboard_css)
                    : (defined('STAKMV_VERSION') ? STAKMV_VERSION : '1.0.0')
            );

            wp_add_inline_style(
                'stakmv-dashboard',
                '.mv-auction-actions .mv-btn.buy{display:inline-flex;align-items:center;gap:.55rem;}
                .mv-auction-actions .mv-btn.buy .mv-btn-label{font-weight:700;letter-spacing:.01em;}
                .mv-auction-actions .mv-btn.buy .mv-btn-price-chip{display:inline-flex;align-items:center;padding:.22rem .56rem;border-radius:999px;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.34);font-size:.86em;line-height:1.1;white-space:nowrap;}
                .mv-auction-actions .mv-btn.buy .mv-btn-price-chip .woocommerce-Price-amount{font-size:.94em;font-weight:600;line-height:1;}
                .mv-auction-actions .mv-btn.buy .mv-btn-price-chip .woocommerce-Price-currencySymbol{font-size:.92em;opacity:.95;}
                .mv-auction-actions .mv-shipping-panel{margin-top:14px;padding:12px 14px;border:1px solid rgba(0,0,0,.08);border-radius:12px;background:#fffaf1;}
                .mv-auction-actions .mv-shipping-panel p{margin:0 0 6px 0;}
                .mv-auction-actions .mv-shipping-panel .mv-shipping-row:last-child{margin-bottom:0;}
                .mv-auction-actions .mv-shipping-panel .mv-shipping-title{font-weight:700;color:#7a2f0f;}
                .mv-auction-actions .mv-shipping-panel .mv-shipping-muted{opacity:.85;font-size:.95em;}'
            );
        }
    }

});

/**
 * Always show WooCommerce notices
 */
add_action('woocommerce_before_single_product', 'wc_print_notices', 5);

/**
 * Add auction-specific body class from core (works with or without pro plugin).
 */
add_filter('body_class', function ($classes) {
    if (stakmv_is_current_auction_product()) {
        $classes[] = 'wcmv-auction-product';
        $classes[] = 'wcmv-auction-' . stakmv_get_auction_product_template_mode();
    }
    return $classes;
});

/**
 * Remove gallery callbacks (Woo + theme gallery handlers) for auction pages.
 */
function stakmv_remove_auction_gallery_callbacks() {
    global $wp_filter;

    $hook_name = 'woocommerce_before_single_product_summary';
    if (empty($wp_filter[$hook_name]) || !($wp_filter[$hook_name] instanceof WP_Hook)) {
        return;
    }

    foreach ($wp_filter[$hook_name]->callbacks as $priority => $callbacks) {
        foreach ($callbacks as $cb) {
            if (!isset($cb['function'])) {
                continue;
            }
            $callback = $cb['function'];
            $name = '';

            if (is_string($callback)) {
                $name = $callback;
            } elseif (is_array($callback) && isset($callback[1])) {
                $owner = is_object($callback[0]) ? get_class($callback[0]) : (string) $callback[0];
                $name = $owner . '::' . (string) $callback[1];
            }

            if ($name === '') {
                continue;
            }

            if (
                $name === 'woocommerce_show_product_images' ||
                stripos($name, 'gallery') !== false
            ) {
                remove_action($hook_name, $callback, (int) $priority);
            }
        }
    }
}

/**
 * Render custom gallery markup for auction pages.
 */
function stakmv_render_custom_auction_gallery() {
    if (!stakmv_is_current_auction_product()) {
        return;
    }

    global $product;
    if (!($product instanceof WC_Product)) {
        return;
    }

    $image_ids = array();
    $featured_id = (int) $product->get_image_id();
    if ($featured_id > 0) {
        $image_ids[] = $featured_id;
    }

    $gallery_ids = array_map('intval', (array) $product->get_gallery_image_ids());
    foreach ($gallery_ids as $gid) {
        if ($gid > 0 && !in_array($gid, $image_ids, true)) {
            $image_ids[] = $gid;
        }
    }

    if (empty($image_ids)) {
        $placeholder = wc_placeholder_img_src('woocommerce_single');
        if (!$placeholder) {
            return;
        }
        echo '<div class="wcmv-auction-gallery"><div class="wcmv-auction-gallery-main"><img src="' . esc_url($placeholder) . '" alt="" loading="lazy"></div></div>';
        return;
    }

    $first_id = (int) $image_ids[0];
    $first_url = wp_get_attachment_image_url($first_id, 'large');
    $first_alt = get_post_meta($first_id, '_wp_attachment_image_alt', true);

    echo '<div class="wcmv-auction-gallery">';
    echo '<div class="wcmv-auction-gallery-main">';
    echo '<img class="wcmv-auction-gallery-main-image" src="' . esc_url($first_url ?: wc_placeholder_img_src('woocommerce_single')) . '" alt="' . esc_attr((string) $first_alt) . '" loading="eager">';
    echo '</div>';

    if (count($image_ids) > 1) {
        echo '<div class="wcmv-auction-gallery-thumbs" role="list">';
        foreach ($image_ids as $idx => $image_id) {
            $thumb_url = wp_get_attachment_image_url((int) $image_id, 'thumbnail');
            $large_url = wp_get_attachment_image_url((int) $image_id, 'large');
            $alt_text = get_post_meta((int) $image_id, '_wp_attachment_image_alt', true);
            if (!$thumb_url || !$large_url) {
                continue;
            }
            echo '<button type="button" class="wcmv-auction-gallery-thumb' . ($idx === 0 ? ' is-active' : '') . '" data-large-src="' . esc_url($large_url) . '" data-large-alt="' . esc_attr((string) $alt_text) . '" aria-label="' . esc_attr__('View image', 'stak-multivendor') . '">';
            echo '<img src="' . esc_url($thumb_url) . '" alt="' . esc_attr((string) $alt_text) . '" loading="lazy">';
            echo '</button>';
        }
        echo '</div>';
    }

    echo '</div>';
}

/**
 * Apply auction-specific single-product UI overrides.
 */
add_action('wp', function () {
    if (!stakmv_is_current_auction_product() || !stakmv_use_custom_auction_product_page()) {
        return;
    }

    if (stakmv_get_auction_product_template_mode() !== 'template_1') {
        return;
    }

    remove_action('woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10);
    remove_action('woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20);
    stakmv_remove_auction_gallery_callbacks();
    add_action('woocommerce_before_single_product_summary', 'stakmv_render_custom_auction_gallery', 20);
});

add_filter('woocommerce_product_tabs', function ($tabs) {
    if (stakmv_is_current_auction_product() && stakmv_use_custom_auction_product_page() && stakmv_get_auction_product_template_mode() === 'template_1') {
        return array();
    }
    return $tabs;
}, 999);

function stakmv_render_template1_product_details_section() {
    if (!stakmv_is_current_auction_product() || !stakmv_use_custom_auction_product_page() || stakmv_get_auction_product_template_mode() !== 'template_1') {
        return;
    }

    global $product;
    if (!($product instanceof WC_Product)) {
        return;
    }

    $auction_id = (int) $product->get_id();
    $description = (string) $product->get_description();
    if ($description === '') {
        $description = 'No description provided yet.';
    }

    $saved_faqs = get_post_meta($auction_id, '_stakmv_listing_faqs', true);
    $faq_rows = array();
    if (is_array($saved_faqs)) {
        foreach ($saved_faqs as $faq_row) {
            if (!is_array($faq_row)) {
                continue;
            }
            $faq_q = sanitize_text_field((string) ($faq_row['q'] ?? ''));
            $faq_a = sanitize_textarea_field((string) ($faq_row['a'] ?? ''));
            if ($faq_q === '' && $faq_a === '') {
                continue;
            }
            $faq_rows[] = array('q' => $faq_q, 'a' => $faq_a);
        }
    }
    echo '<section class="wcmv-t1-details-section">';
    echo '<div class="wcmv-t1-tabs" role="tablist" aria-label="Product details tabs">';
    echo '<button class="wcmv-t1-tab is-active" type="button" data-panel="wcmv-t1-panel-description">Description</button>';
    echo '<button class="wcmv-t1-tab" type="button" data-panel="wcmv-t1-panel-reviews">Reviews</button>';
    echo '<button class="wcmv-t1-tab" type="button" data-panel="wcmv-t1-panel-faq">FAQ</button>';
    echo '</div>';
    echo '<div id="wcmv-t1-panel-description" class="wcmv-t1-panel is-active">' . wp_kses_post(wpautop($description)) . '</div>';

    echo '<div id="wcmv-t1-panel-reviews" class="wcmv-t1-panel">';
    ob_start();
    if (function_exists('wc_get_template')) {
        wc_get_template('single-product-reviews.php');
    }
    $reviews_markup = trim((string) ob_get_clean());
    if ($reviews_markup !== '') {
        $review_allowed_html = wp_kses_allowed_html('post');
        $review_allowed_html['form'] = array(
            'action' => true,
            'class'  => true,
            'id'     => true,
            'method' => true,
        );
        $review_allowed_html['input'] = array(
            'aria-describedby' => true,
            'aria-required'    => true,
            'checked'          => true,
            'class'            => true,
            'id'               => true,
            'name'             => true,
            'placeholder'      => true,
            'required'         => true,
            'type'             => true,
            'value'            => true,
        );
        $review_allowed_html['label'] = array(
            'class' => true,
            'for'   => true,
        );
        $review_allowed_html['select'] = array(
            'aria-required' => true,
            'class'         => true,
            'id'            => true,
            'name'          => true,
            'required'      => true,
        );
        $review_allowed_html['option'] = array(
            'selected' => true,
            'value'    => true,
        );
        $review_allowed_html['textarea'] = array(
            'aria-describedby' => true,
            'aria-required'    => true,
            'class'            => true,
            'cols'             => true,
            'id'               => true,
            'name'             => true,
            'placeholder'      => true,
            'required'         => true,
            'rows'             => true,
        );
        echo wp_kses($reviews_markup, $review_allowed_html);
    } else {
        echo '<p>' . esc_html__('No reviews yet.', 'stak-multivendor') . '</p>';
    }
    echo '</div>';

    echo '<div id="wcmv-t1-panel-faq" class="wcmv-t1-panel">';
    if (!empty($faq_rows)) {
        echo '<div class="wcmv-t1-faq-list">';
        foreach ($faq_rows as $faq_row) {
            echo '<details class="wcmv-t1-faq-item"><summary>' . esc_html($faq_row['q']) . '</summary><div class="wcmv-t1-faq-answer">' . wp_kses_post(wpautop($faq_row['a'])) . '</div></details>';
        }
        echo '</div>';
    } else {
        echo '<p>' . esc_html__('No FAQ added for this listing yet.', 'stak-multivendor') . '</p>';
    }
    echo '</div>';
    echo '</section>';
}
add_action('woocommerce_after_single_product_summary', 'stakmv_render_template1_product_details_section', 8);

function stakmv_render_template1_more_from_seller_section() {
    if (!stakmv_is_current_auction_product() || !stakmv_use_custom_auction_product_page() || stakmv_get_auction_product_template_mode() !== 'template_1') {
        return;
    }

    global $product;
    if (!($product instanceof WC_Product)) {
        return;
    }

    $product_id = (int) $product->get_id();
    $seller_id  = (int) get_post_field('post_author', $product_id);

    if ($seller_id <= 0) {
        return;
    }

    $seller_query = new WP_Query(array(
        'post_type'           => 'product',
        'post_status'         => 'publish',
        'posts_per_page'      => 13,
        'author'              => $seller_id,
        'ignore_sticky_posts' => true,
        'no_found_rows'       => true,
    ));

    echo '<section class="wcmv-t1-more-from-seller">';
    echo '<h3 class="wcmv-t1-more-from-seller__title">' . esc_html__('Other items by seller', 'stak-multivendor') . '</h3>';
    echo '<div class="wcmv-t1-more-from-seller__track">';

    if ($seller_query->have_posts()) {
        while ($seller_query->have_posts()) {
            $seller_query->the_post();
            $item_id = (int) get_the_ID();
            if ($item_id <= 0 || $item_id === $product_id) {
                continue;
            }

            $item_product = wc_get_product($item_id);
            if (!($item_product instanceof WC_Product)) {
                continue;
            }

            $permalink = get_permalink($item_id);
            if (!$permalink) {
                continue;
            }

            $thumb = get_the_post_thumbnail($item_id, 'woocommerce_thumbnail', array('loading' => 'lazy'));
            if ($thumb === '') {
                $thumb = '<img src="' . esc_url(wc_placeholder_img_src('woocommerce_thumbnail')) . '" alt="" loading="lazy">';
            }

            echo '<article class="wcmv-t1-more-from-seller__card">';
            echo '<a class="wcmv-t1-more-from-seller__thumb" href="' . esc_url($permalink) . '">' . wp_kses_post($thumb) . '</a>';
            echo '<a class="wcmv-t1-more-from-seller__name" href="' . esc_url($permalink) . '">' . esc_html(wp_trim_words($item_product->get_name(), 7, '…')) . '</a>';
            echo '<div class="wcmv-t1-more-from-seller__price">' . wp_kses_post($item_product->get_price_html()) . '</div>';
            echo '</article>';
        }
        wp_reset_postdata();
    }

    echo '</div>';
    echo '</section>';
}
add_action('woocommerce_before_single_product_summary', 'stakmv_render_template1_more_from_seller_section', 25);

function stakmv_render_template1_you_may_like_section() {
    if (!stakmv_is_current_auction_product() || !stakmv_use_custom_auction_product_page() || stakmv_get_auction_product_template_mode() !== 'template_1') {
        return;
    }

    global $product;
    if (!($product instanceof WC_Product)) {
        return;
    }

    $product_id = (int) $product->get_id();
    $related_ids = array_values(array_filter(array_map('intval', (array) wc_get_related_products($product_id, 8, array($product_id)))));

    if (empty($related_ids)) {
        $fallback = wc_get_products(array(
            'status' => 'publish',
            'limit' => 9,
            'orderby' => 'rand',
            'return' => 'ids',
        ));
        $related_ids = array_values(array_filter(array_map('intval', (array) $fallback)));
    }

    echo '<section class="wcmv-t1-you-may-like">';
    echo '<h3 class="wcmv-t1-you-may-like__title">' . esc_html__('You may like this', 'stak-multivendor') . '</h3>';
    echo '<div class="wcmv-t1-you-may-like__grid">';

    $count = 0;
    foreach ($related_ids as $related_id) {
        if ($count >= 8) {
            break;
        }
        if ((int) $related_id === $product_id) {
            continue;
        }
        $related_product = wc_get_product((int) $related_id);
        if (!($related_product instanceof WC_Product) || $related_product->get_status() !== 'publish') {
            continue;
        }

        $permalink = get_permalink((int) $related_id);
        if (!$permalink) {
            continue;
        }

        $thumb = get_the_post_thumbnail((int) $related_id, 'woocommerce_thumbnail', array('loading' => 'lazy'));
        if ($thumb === '') {
            $thumb = '<img src="' . esc_url(wc_placeholder_img_src('woocommerce_thumbnail')) . '" alt="" loading="lazy">';
        }

        $title = $related_product->get_name();
        $price_html = $related_product->get_price_html();

        echo '<article class="wcmv-t1-you-may-like__card">';
        echo '<a class="wcmv-t1-you-may-like__thumb" href="' . esc_url($permalink) . '">' . wp_kses_post($thumb) . '</a>';
        echo '<a class="wcmv-t1-you-may-like__name" href="' . esc_url($permalink) . '">' . esc_html(wp_trim_words($title, 9, '…')) . '</a>';
        if ($price_html !== '') {
            echo '<div class="wcmv-t1-you-may-like__price">' . wp_kses_post($price_html) . '</div>';
        }
        echo '<a class="wcmv-t1-you-may-like__cta" href="' . esc_url($permalink) . '">' . esc_html__('View Product', 'stak-multivendor') . '</a>';
        echo '</article>';

        $count++;
    }

    echo '</div>';
    echo '</section>';
}
add_action('woocommerce_after_single_product_summary', 'stakmv_render_template1_you_may_like_section', 9);

/**
 * Stable nonce for bidding
 */
function stakmv_get_bid_nonce() {
    static $nonce = null;
    if ($nonce === null) {
        $nonce = wp_create_nonce('stakmv_place_bid');
    }
    return $nonce;
}

/**
 * Default Woo template mode: render the auction summary panel.
 *
 * @param WC_Product $product Auction product.
 */
function stakmv_render_default_woo_summary($product) {
    if (!($product instanceof WC_Product) || $product->get_type() !== 'auction') {
        return;
    }

    $auction_id        = (int) $product->get_id();
    $status            = (string) get_post_meta($auction_id, '_stakmv_auction_status', true);
    $end_raw           = get_post_meta($auction_id, '_stakmv_auction_end_time', true);
    $end_time          = is_numeric($end_raw) ? (int) $end_raw : ($end_raw ? strtotime((string) $end_raw) : 0);
    $sale_mode         = (string) get_post_meta($auction_id, '_stakmv_auction_sale_mode', true);
    $auctions_enabled  = function_exists('stakmv_auctions_enabled')
        ? stakmv_auctions_enabled()
        : (stakmv_get_option('enable_auctions', 'yes') === 'yes');
    $buy_now_price     = (float) get_post_meta($auction_id, '_stakmv_auction_buy_now_price', true);
    $shipping_mode     = function_exists('stakmv_get_listing_shipping_mode')
        ? stakmv_get_listing_shipping_mode($auction_id)
        : 'calculated';
    $shipping_cost     = (float) get_post_meta($auction_id, '_stakmv_auction_shipping_cost', true);
    $shipping_carriers = get_post_meta($auction_id, '_stakmv_auction_shipping_carriers', true);
    if (!is_array($shipping_carriers)) {
        $shipping_carriers = array();
    }
    $shipping_carriers = array_values(array_filter(array_map('sanitize_text_field', $shipping_carriers), function ($carrier) {
        return in_array($carrier, array('USPS', 'UPS', 'FedEx', 'DHL'), true);
    }));
    if (empty($shipping_carriers)) {
        $single_carrier = sanitize_text_field((string) get_post_meta($auction_id, '_stakmv_auction_shipping_carrier', true));
        if (in_array($single_carrier, array('USPS', 'UPS', 'FedEx', 'DHL'), true)) {
            $shipping_carriers[] = $single_carrier;
        }
    }
    $handling_days = (int) get_post_meta($auction_id, '_stakmv_auction_handling_time_days', true);

    if ($status === 'sold' || ($end_time && time() >= $end_time)) {
        echo '<p><strong>' . esc_html__('Auction ended.', 'stak-multivendor') . '</strong></p>';
        return;
    }

    echo '<div class="mv-card mv-auction-actions">';

    $is_owner_global = is_user_logged_in() && (int) get_post_field('post_author', $auction_id) === get_current_user_id();
    do_action('stakmv_auction_render_meta_summary', $auction_id, $product);

    if ($auctions_enabled && in_array($sale_mode, array('auction', 'both'), true)) {
        $current_bid = (float) stakmv_get_highest_bid($auction_id);
        $start_price = (float) get_post_meta($auction_id, '_stakmv_auction_start_price', true);
        $bid_count   = (int) stakmv_get_bid_count($auction_id);
        do_action('stakmv_auction_render_bid_meta', $auction_id, $current_bid, $product);

        if ($start_price > 0) {
            echo '<p class="mv-price-line"><strong>' . esc_html__('Starting Price:', 'stak-multivendor') . '</strong> <span class="mv-price-value">' . wp_kses_post(wc_price($start_price)) . '</span></p>';
        }

        echo '<p class="mv-price-line"><strong>' . esc_html__('Current Highest Bid:', 'stak-multivendor') . '</strong> <span class="mv-price-value">' . wp_kses_post(wc_price($current_bid)) . '</span> <span style="color:#666;">(' . esc_html((string) $bid_count) . ' ' . esc_html__('bids', 'stak-multivendor') . ')</span></p>';

        if (is_user_logged_in()) {
            $is_owner = (int) get_post_field('post_author', $auction_id) === get_current_user_id();
            if (!$is_owner) {
                echo '<form method="post">
                    <input type="number" name="stakmv_bid_amount" step="0.01" min="' . esc_attr((string) ($current_bid + 0.01)) . '" required>
                    <input type="hidden" name="stakmv_auction_id" value="' . esc_attr((string) $auction_id) . '">
                    <input type="hidden" name="stakmv_bid_nonce" value="' . esc_attr(stakmv_get_bid_nonce()) . '">
                    <button type="submit" name="stakmv_place_bid" class="mv-btn bid">' . esc_html__('Place Bid', 'stak-multivendor') . '</button>
                </form>';
            }
        } else {
            echo '<p>' . esc_html__('Please log in to place a bid.', 'stak-multivendor') . '</p>';
        }
    }

    if (in_array($sale_mode, array('buy_now', 'both'), true) && $buy_now_price > 0) {
        $is_owner = is_user_logged_in() && (int) get_post_field('post_author', $auction_id) === get_current_user_id();
        if (!$is_owner) {
            if ($sale_mode === 'buy_now') {
                do_action('stakmv_auction_add_to_cart');
            } else {
                echo '<form method="post" style="margin-top:15px;">
                    <input type="hidden" name="stakmv_buy_now" value="1">
                    <input type="hidden" name="stakmv_auction_id" value="' . esc_attr((string) $auction_id) . '">
                    <input type="hidden" name="stakmv_buy_now_nonce" value="' . esc_attr(wp_create_nonce('stakmv_buy_now')) . '">
                    <button type="submit" class="mv-btn buy">
                        <span class="mv-btn-label">' . esc_html__('Buy Now', 'stak-multivendor') . '</span>
                        <span class="mv-btn-price-chip">' . wp_kses_post(wc_price($buy_now_price)) . '</span>
                    </button>
                </form>';
            }
        } else {
            echo '<p class="mv-price-line"><strong>' . esc_html__('Buy Now Price:', 'stak-multivendor') . '</strong> <span class="mv-price-value">' . wp_kses_post(wc_price($buy_now_price)) . '</span></p>';
        }
    }

    echo '<div class="mv-shipping-panel">';
    echo '<p class="mv-shipping-title">' . esc_html__('Shipping', 'stak-multivendor') . '</p>';

    if ($shipping_mode === 'flat') {
        if ($shipping_cost > 0) {
            echo '<p class="mv-shipping-row"><strong>' . esc_html__('Flat shipping:', 'stak-multivendor') . '</strong> ' . wp_kses_post(wc_price($shipping_cost)) . '</p>';
        } else {
            echo '<p class="mv-shipping-row"><strong>' . esc_html__('Flat shipping:', 'stak-multivendor') . '</strong> ' . esc_html__('Free', 'stak-multivendor') . '</p>';
        }
    } elseif ($shipping_mode === 'free') {
        echo '<p class="mv-shipping-row"><strong>' . esc_html__('Free shipping', 'stak-multivendor') . '</strong></p>';
    } elseif ($shipping_mode === 'pickup_only') {
        echo '<p class="mv-shipping-row"><strong>' . esc_html__('Pickup only', 'stak-multivendor') . '</strong></p>';
    } else {
        echo '<p class="mv-shipping-row"><strong>' . esc_html__('Calculated at checkout', 'stak-multivendor') . '</strong></p>';
        if (!empty($shipping_carriers)) {
            echo '<p class="mv-shipping-row mv-shipping-muted">' . esc_html__('Supported carriers:', 'stak-multivendor') . ' ' . esc_html(implode(', ', $shipping_carriers)) . '</p>';
        }
    }

    if ($handling_days > 0) {
        echo '<p class="mv-shipping-row mv-shipping-muted">' . esc_html__('Handling time:', 'stak-multivendor') . ' ' . esc_html((string) $handling_days) . ' ' . esc_html(_n('day', 'days', $handling_days, 'stak-multivendor')) . '</p>';
    }

    echo '</div>';

    do_action('stakmv_auction_render_secondary_actions', $auction_id, $product);

    if ($is_owner_global) {
        $edit_url = add_query_arg('edit', $auction_id, stakmv_get_create_listing_url());
        echo '<p style="margin-top:12px;"><a class="button" href="' . esc_url($edit_url) . '">' . esc_html__('Edit listing', 'stak-multivendor') . '</a></p>';
    }

    echo '</div>';
}

/**
 * Get number of bids
 */
function stakmv_get_bid_count($auction_id) {
    global $wpdb;
    $bids_table = $wpdb->prefix . 'stakmv_auction_bids';

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is plugin-controlled and escaped; query is bounded.
    return (int) $wpdb->get_var(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Dynamic table name uses current site prefix.
            "SELECT COUNT(*) FROM {$bids_table} WHERE auction_id = %d",
            (int) $auction_id
        )
    );
}

/**
 * 🔔 Notify all bidders when auction is won via Buy Now
 */
function stakmv_notify_bidders_buy_now($auction_id, $winner_user_id) {
    global $wpdb;
    $bids_table = $wpdb->prefix . 'stakmv_auction_bids';

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is plugin-controlled and escaped; query is bounded.
    $bidders = $wpdb->get_results(
        $wpdb->prepare(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Dynamic table name uses current site prefix.
            "SELECT DISTINCT user_id FROM {$bids_table} WHERE auction_id = %d",
            (int) $auction_id
        )
    );

    if (!$bidders) return;

    $product = wc_get_product($auction_id);
    if (!$product) return;

    foreach ($bidders as $bidder) {

        if ((int) $bidder->user_id === (int) $winner_user_id) continue;

        $user = get_user_by('id', $bidder->user_id);
        if (!$user) continue;

        wp_mail(
            $user->user_email,
            'Auction ended – Buy Now was used',
            sprintf(
                "Hello %s,\n\nThe auction for \"%s\" has ended because another buyer completed a Buy Now purchase.\n\n— %s",
                $user->display_name,
                $product->get_name(),
                get_bloginfo('name')
            )
        );
    }
}

/**
 * FRONTEND UI (Auction)
 */
add_action('woocommerce_single_product_summary', function () {
    global $product;

    if (!$product || $product->get_type() !== 'auction') return;
    if (stakmv_get_auction_product_template_mode() === 'default_woo') {
        stakmv_render_default_woo_summary($product);
        return;
    }

    $auction_id    = $product->get_id();
    $vendor_id     = (int) get_post_field('post_author', $auction_id);
    $status        = get_post_meta($auction_id, '_stakmv_auction_status', true);
    $end_raw      = get_post_meta($auction_id, '_stakmv_auction_end_time', true);
    $end_time     = is_numeric($end_raw) ? (int) $end_raw : ( $end_raw ? strtotime($end_raw) : 0 );
    $sale_mode     = get_post_meta($auction_id, '_stakmv_auction_sale_mode', true);
    $auctions_enabled = function_exists('stakmv_auctions_enabled')
        ? stakmv_auctions_enabled()
        : (stakmv_get_option('enable_auctions', 'yes') === 'yes');
    $buy_now_price = (float) get_post_meta($auction_id, '_stakmv_auction_buy_now_price', true);
    $shipping_mode = function_exists('stakmv_get_listing_shipping_mode')
        ? stakmv_get_listing_shipping_mode($auction_id)
        : 'calculated';
    $shipping_cost = (float) get_post_meta($auction_id, '_stakmv_auction_shipping_cost', true);
    $location = sanitize_text_field((string) get_post_meta($auction_id, '_stakmv_auction_location', true));
    $shipping_carriers = get_post_meta($auction_id, '_stakmv_auction_shipping_carriers', true);
    if (!is_array($shipping_carriers)) {
        $shipping_carriers = array();
    }
    $shipping_carriers = array_values(array_filter(array_map('sanitize_text_field', $shipping_carriers), function ($carrier) {
        return in_array($carrier, array('USPS', 'UPS', 'FedEx', 'DHL'), true);
    }));
    if (empty($shipping_carriers)) {
        $single_carrier = sanitize_text_field((string) get_post_meta($auction_id, '_stakmv_auction_shipping_carrier', true));
        if (in_array($single_carrier, array('USPS', 'UPS', 'FedEx', 'DHL'), true)) {
            $shipping_carriers[] = $single_carrier;
        }
    }
    $handling_days = (int) get_post_meta($auction_id, '_stakmv_auction_handling_time_days', true);
    $returns_policy = sanitize_key((string) get_post_meta($auction_id, '_stakmv_auction_returns_policy', true));
    if (in_array($returns_policy, array('returns_14_days', 'returns_30_days'), true)) {
        $returns_policy = 'returns_accepted'; // Normalize older return-period values.
    }
    if (!in_array($returns_policy, array('no_returns', 'returns_accepted'), true)) {
        $returns_policy = 'no_returns';
    }
    $returns_days = (int) get_post_meta($auction_id, '_stakmv_auction_returns_days', true);
    if ($returns_days < 1) {
        $returns_days = 30;
    }
    if ($returns_days > 60) {
        $returns_days = 60;
    }
    $return_shipping_paid_by = sanitize_key((string) get_post_meta($auction_id, '_stakmv_auction_return_shipping_paid_by', true));
    if (!in_array($return_shipping_paid_by, array('buyer', 'seller'), true)) {
        $return_shipping_paid_by = 'buyer';
    }
    $shipping_scope = function_exists('stakmv_get_listing_shipping_scope')
        ? stakmv_get_listing_shipping_scope($auction_id)
        : 'international';
    $shipping_countries = get_post_meta($auction_id, '_stakmv_auction_shipping_countries', true);
    if (!is_array($shipping_countries)) {
        $shipping_countries = array();
    }
    $shipping_countries = array_values(array_filter(array_map(function ($country_code) {
        return strtoupper(sanitize_text_field((string) $country_code));
    }, $shipping_countries)));
    $countries_map = function_exists('WC') && WC()->countries ? WC()->countries->get_countries() : array();
    $vendor_origin_country_code = strtoupper(trim((string) get_user_meta($vendor_id, 'stakmv_ship_origin_country', true)));
    if ($vendor_origin_country_code === '' && function_exists('wc_get_base_location')) {
        $base_loc = wc_get_base_location();
        if (is_array($base_loc) && !empty($base_loc['country'])) {
            $vendor_origin_country_code = strtoupper(sanitize_text_field((string) $base_loc['country']));
        }
    }
    $vendor_origin_country_name = $vendor_origin_country_code;
    if ($vendor_origin_country_code !== '' && !empty($countries_map[$vendor_origin_country_code])) {
        $vendor_origin_country_name = (string) $countries_map[$vendor_origin_country_code];
    }
    $shipping_scope_text = __('Worldwide', 'stak-multivendor');
    if ($shipping_scope === 'domestic') {
        $shipping_scope_text = $vendor_origin_country_name !== '' ? $vendor_origin_country_name : __('Domestic only', 'stak-multivendor');
    } elseif ($shipping_scope === 'selected') {
        $selected_country_names = array();
        foreach ($shipping_countries as $country_code) {
            if (!empty($countries_map[$country_code])) {
                $selected_country_names[] = $countries_map[$country_code];
            }
        }
        $shipping_scope_text = !empty($selected_country_names)
            ? implode(', ', $selected_country_names)
            : __('Selected countries only', 'stak-multivendor');
    }
    $shipping_details_modal_id = 'mv-shipping-details-' . (int) $auction_id;
    $vendor_reputation = function_exists('stakmv_get_vendor_reputation_summary')
        ? stakmv_get_vendor_reputation_summary($vendor_id)
        : array();
    $vendor_rating_summary = function_exists('stakmv_get_vendor_rating_summary')
        ? stakmv_get_vendor_rating_summary($vendor_id)
        : array('average' => 0.0, 'count' => 0);

    if ($status === 'sold' || ($end_time && time() >= $end_time)) {
        echo '<p><strong>Auction ended.</strong></p>';
        return;
    }

    echo '<div class="mv-card mv-auction-actions">';

    $is_owner_global = is_user_logged_in() && (int) get_post_field('post_author', $auction_id) === get_current_user_id();
    $vendor_user = get_userdata($vendor_id);
    $vendor_name = $vendor_user ? $vendor_user->display_name : __('Seller', 'stak-multivendor');

    $rating_count = (int) ($vendor_rating_summary['count'] ?? 0);
    $positive_feedback = 0.0;
    if ($rating_count > 0) {
        $stars = isset($vendor_rating_summary['stars']) && is_array($vendor_rating_summary['stars'])
            ? $vendor_rating_summary['stars']
            : array();
        $positive_count = (int) ($stars[4] ?? 0) + (int) ($stars[5] ?? 0);
        $positive_feedback = ($positive_count / $rating_count) * 100;
    }

    // Resolve display condition for the right-side condition row.
    $condition_raw = trim((string) get_post_meta($auction_id, '_stakmv_auction_condition', true));
    $condition_options = function_exists('stakmv_get_condition_options') ? stakmv_get_condition_options() : array();
    $condition_label = '';
    $condition_detail = '';

    if ($condition_raw !== '' && isset($condition_options[$condition_raw]) && is_array($condition_options[$condition_raw])) {
        $condition_label = sanitize_text_field((string) ($condition_options[$condition_raw]['label'] ?? ''));
        $condition_detail = sanitize_text_field((string) ($condition_options[$condition_raw]['detail'] ?? ''));
    }

    if ($condition_label === '' && $condition_raw !== '') {
        // Support stored labels like "New — Factory sealed, never used".
        $raw_label_candidate = preg_split('/\s*[—-]\s*/u', $condition_raw, 2);
        $condition_label = sanitize_text_field((string) ($raw_label_candidate[0] ?? $condition_raw));
        if ($condition_detail === '' && isset($raw_label_candidate[1])) {
            $condition_detail = sanitize_text_field((string) $raw_label_candidate[1]);
        }
    }

    if ($condition_label === '') {
        $condition_label = __('Not specified', 'stak-multivendor');
    }

    echo '<div class="mv-section-divider mv-section-divider--top" aria-hidden="true"></div>';
    echo '<div class="mv-seller-block">';
    $seller_profile_url = function_exists('stakmv_get_vendor_profile_url') ? stakmv_get_vendor_profile_url($vendor_id) : '';
    $seller_items_url = $seller_profile_url ? add_query_arg('section', 'shop', $seller_profile_url) : '';

    echo '<div class="mv-seller-avatar">' . get_avatar($vendor_id, 56) . '</div>';
    echo '<div class="mv-seller-meta">';
    if ($seller_profile_url) {
        echo '<p class="mv-seller-name"><a href="' . esc_url($seller_profile_url) . '" class="mv-placeholder-link">' . esc_html($vendor_name) . '</a></p>';
    } else {
        echo '<p class="mv-seller-name">' . esc_html($vendor_name) . '</p>';
    }
    if ($rating_count > 0) {
        echo '<p class="mv-seller-feedback">' . esc_html(number_format_i18n($positive_feedback, 1)) . '% ' . esc_html__('positive', 'stak-multivendor') . ' ';
        echo '<span>(' . esc_html((string) $rating_count) . ')</span></p>';
    }
    echo '<p class="mv-seller-links">';
    if ($rating_count === 0) {
        echo '<span class="mv-seller-feedback-inline">' . esc_html__('No feedback yet', 'stak-multivendor') . '</span>';
        echo ' · ';
    }

    if ($seller_items_url) {
        echo '<a href="' . esc_url($seller_items_url) . '" class="mv-placeholder-link">' . esc_html__("Seller's other items", 'stak-multivendor') . '</a>';
    } else {
        echo '<span class="mv-seller-feedback-inline">' . esc_html__("Seller's other items", 'stak-multivendor') . '</span>';
    }
    do_action('stakmv_product_seller_actions', $auction_id, $vendor_id, $product);
    echo '</p>';
    echo '</div>';
    echo '</div>';
    echo '<div class="mv-section-divider" aria-hidden="true"></div>';
    echo '<div class="mv-condition-row">';
    echo '<span class="mv-condition-label">' . esc_html__('Condition:', 'stak-multivendor') . '</span>';
    echo '<strong class="mv-condition-value mv-condition-value-text">' . esc_html($condition_label) . '</strong>';
    $condition_info_text = $condition_detail !== '' ? $condition_detail : $condition_label;
    $condition_detail_id = 'mv-condition-detail-' . $auction_id;
    echo '<button type="button" class="mv-condition-info" data-target="#' . esc_attr($condition_detail_id) . '" aria-label="' . esc_attr__('View condition details', 'stak-multivendor') . '" title="' . esc_attr($condition_info_text) . '">&#9432;</button>';
    echo '<span id="' . esc_attr($condition_detail_id) . '" class="mv-condition-popover" role="note">' . esc_html($condition_info_text) . '</span>';
    echo '</div>';
    echo '<div class="mv-section-divider" aria-hidden="true"></div>';

    do_action('stakmv_auction_render_meta_summary', $auction_id, $product);

    // Bidding
    if ($auctions_enabled && in_array($sale_mode, ['auction', 'both'], true)) {

        $current_bid = stakmv_get_highest_bid($auction_id);
        $start_price = (float) get_post_meta($auction_id, '_stakmv_auction_start_price', true);
        $bid_count   = stakmv_get_bid_count($auction_id);
        do_action('stakmv_auction_render_bid_meta', $auction_id, (float) $current_bid, $product);



        $main_price = $current_bid > 0 ? $current_bid : $start_price;
        if ($main_price <= 0 && $buy_now_price > 0) {
            $main_price = $buy_now_price;
        }
        if ($main_price > 0) {
            echo '<p class="mv-main-price-row"><span class="mv-main-price">' . wp_kses_post(wc_price($main_price)) . '</span>';
            echo '</p>';
        }

        if ($end_time > 0) {
            echo '<p class="mv-auction-timing" data-end-ts="' . esc_attr((string) $end_time) . '">';
            echo '<span class="mv-auction-timing-bids">' . esc_html((string) $bid_count) . ' bids</span>';
            echo ' <span class="mv-auction-timing-sep">·</span> ';
            echo '<span class="mv-auction-timing-ends">Ends soon</span>';
            echo '</p>';
        }

        if ($start_price > 0) {
            echo '<p class="mv-price-line"><strong>Starting Price:</strong> <span class="mv-price-value">' . wp_kses_post( wc_price($start_price) ) . '</span></p>';
        }

        echo '<p class="mv-price-line"><strong>Current Highest Bid:</strong> <span class="mv-price-value">' . wp_kses_post( wc_price($current_bid) ) . '</span>' .
             ' <span class="mv-bid-count">(' . esc_html( (string) $bid_count ) . ' bids)</span></p>';

        if (is_user_logged_in()) {
            $is_owner = is_user_logged_in() && (int) get_post_field('post_author', $auction_id) === get_current_user_id();
            if (!$is_owner) {
                $bid_form_id = 'mv-bid-form-' . $auction_id;
                echo '<button type="button" class="mv-btn bid mv-toggle-form" data-target="#' . esc_attr($bid_form_id) . '">Place Bid</button>';
                echo '<form method="post" id="' . esc_attr($bid_form_id) . '" class="mv-collapsible-form">
                    <input type="number" name="stakmv_bid_amount" step="0.01"
                           min="' . esc_attr($current_bid + 0.01) . '" placeholder="Enter your bid" required>
                    <input type="hidden" name="stakmv_auction_id" value="' . esc_attr($auction_id) . '">
                    <input type="hidden" name="stakmv_bid_nonce" value="' . esc_attr(stakmv_get_bid_nonce()) . '">
                    <button type="submit" name="stakmv_place_bid" class="mv-btn bid">Confirm Bid</button>
                </form>';

                /**
                 * Extension hook: render extra bidding controls (e.g., max proxy bid).
                 */
                do_action('stakmv_auction_render_after_bid_form', $auction_id, $current_bid, $product);
            }
        } else {
            echo '<p>Please log in to place a bid.</p>';
        }
    }

    if (in_array($sale_mode, ['buy_now'], true) && $buy_now_price > 0) {
        echo '<p class="mv-main-price-row"><span class="mv-main-price">' . wp_kses_post(wc_price($buy_now_price)) . '</span>';
        echo '</p>';
    }

    // Buy Now / Add to Cart
    if (in_array($sale_mode, ['buy_now', 'both'], true) && $buy_now_price > 0) {
        $is_owner = is_user_logged_in() && (int) get_post_field('post_author', $auction_id) === get_current_user_id();
        if (!$is_owner) {
            if ($sale_mode === 'buy_now') {
                // Buy Now only: add to cart (standard checkout).
                do_action('stakmv_auction_add_to_cart');
            } else {
                // Auction + Buy Now: direct order flow.
                echo '<form method="post" class="mv-mt-15">
                    <input type="hidden" name="stakmv_buy_now" value="1">
                    <input type="hidden" name="stakmv_auction_id" value="' . esc_attr($auction_id) . '">
                    <input type="hidden" name="stakmv_buy_now_nonce" value="' . esc_attr(wp_create_nonce('stakmv_buy_now')) . '">
    <button type="submit" class="mv-btn buy">
                        <span class="mv-btn-label">Buy Now</span>
                        <span class="mv-btn-price-chip">' . wp_kses_post( wc_price($buy_now_price) ) . '</span>
                    </button>
                </form>';
            }
        } else {
            echo '<p class="mv-price-line"><strong>Buy Now Price:</strong> <span class="mv-price-value">' . wp_kses_post( wc_price($buy_now_price) ) . '</span></p>';
        }
    }

    do_action('stakmv_auction_render_after_buy_now', $auction_id, $product, $buy_now_price);

    do_action('stakmv_auction_render_secondary_actions', $auction_id, $product);

    $urgency_rows = array();
    $bid_count_for_urgency = function_exists('stakmv_get_bid_count') ? (int) stakmv_get_bid_count($auction_id) : 0;
    if ($bid_count_for_urgency > 0) {
        $urgency_rows[] = array(
            'icon' => '⚡',
            'text' => sprintf(
                /* translators: %d is the number of bids placed on this listing. */
                __('Interest is building. %d bid(s) placed so far.', 'stak-multivendor'),
                $bid_count_for_urgency
            ),
        );
    }

    if ($returns_policy === 'returns_accepted') {
        $urgency_rows[] = array(
            'icon' => '↩',
            'text' => sprintf(
                /* translators: %d is the number of days within which returns are accepted. */
                __('Breathe easy. Returns accepted within %d days.', 'stak-multivendor'),
                $returns_days
            ),
        );
    }

    if (!empty($urgency_rows)) {
        echo '<div class="mv-urgency-trust-panel">';
        foreach ($urgency_rows as $urgency_row) {
            echo '<p class="mv-urgency-trust-row"><span class="mv-urgency-icon" aria-hidden="true">' . esc_html($urgency_row['icon']) . '</span>' . esc_html($urgency_row['text']) . '</p>';
        }
        echo '</div>';
    }

    echo '<div class="mv-section-divider" aria-hidden="true"></div>';
    echo '<div class="mv-shipping-panel">';
    echo '<p class="mv-shipping-title">Shipping, returns, and payments</p>';
    echo '<div class="mv-shipping-grid">';

    if ($shipping_mode === 'flat') {
        $shipping_value = $shipping_cost > 0 ? wp_strip_all_tags(wc_price($shipping_cost)) : __('Free', 'stak-multivendor');
        echo '<p class="mv-shipping-row"><span class="mv-shipping-label">Shipping:</span><span class="mv-shipping-value">' . esc_html($shipping_value) . ' <button type="button" class="mv-shipping-details-trigger" data-target="#' . esc_attr($shipping_details_modal_id) . '">' . esc_html__('See details', 'stak-multivendor') . '</button></span></p>';
    } elseif ($shipping_mode === 'free') {
        echo '<p class="mv-shipping-row"><span class="mv-shipping-label">Shipping:</span><span class="mv-shipping-value">' . esc_html__('Free shipping', 'stak-multivendor') . ' <button type="button" class="mv-shipping-details-trigger" data-target="#' . esc_attr($shipping_details_modal_id) . '">' . esc_html__('See details', 'stak-multivendor') . '</button></span></p>';
    } elseif ($shipping_mode === 'pickup_only') {
        echo '<p class="mv-shipping-row"><span class="mv-shipping-label">Shipping:</span><span class="mv-shipping-value">' . esc_html__('Pickup only', 'stak-multivendor') . ' <button type="button" class="mv-shipping-details-trigger" data-target="#' . esc_attr($shipping_details_modal_id) . '">' . esc_html__('See details', 'stak-multivendor') . '</button></span></p>';
    } else {
        echo '<p class="mv-shipping-row"><span class="mv-shipping-label">Shipping:</span><span class="mv-shipping-value">' . esc_html__('Calculated at checkout', 'stak-multivendor') . ' <button type="button" class="mv-shipping-details-trigger" data-target="#' . esc_attr($shipping_details_modal_id) . '">' . esc_html__('See details', 'stak-multivendor') . '</button></span></p>';
    }

    if ($returns_policy === 'returns_accepted') {
        $payer_text = $return_shipping_paid_by === 'seller'
            ? __('Seller pays for return shipping.', 'stak-multivendor')
            : __('Buyer pays for return shipping.', 'stak-multivendor');
        /* translators: 1: number of return days, 2: who pays return shipping text. */
        $returns_summary = sprintf(__('Returns accepted within %1$d days. %2$s', 'stak-multivendor'), $returns_days, $payer_text);
        echo '<p class="mv-shipping-row"><span class="mv-shipping-label">Returns:</span><span class="mv-shipping-value">' . esc_html($returns_summary) . '</span></p>';
    } else {
        echo '<p class="mv-shipping-row"><span class="mv-shipping-label">Returns:</span><span class="mv-shipping-value">' . esc_html__('Seller does not accept returns.', 'stak-multivendor') . '</span></p>';
    }

    // Shipping information table (weight + dimensions only).
    $shipping_weight = trim((string) $product->get_weight());
    $shipping_weight_text = $shipping_weight !== '' ? wc_format_weight($shipping_weight) : __('Not specified', 'stak-multivendor');

    $shipping_length = trim((string) $product->get_length());
    $shipping_width  = trim((string) $product->get_width());
    $shipping_height = trim((string) $product->get_height());
    $shipping_dimensions_text = __('Not specified', 'stak-multivendor');
    if ($shipping_length !== '' && $shipping_width !== '' && $shipping_height !== '') {
        $shipping_dimensions_text = wc_format_dimensions(
            array(
                'length' => $shipping_length,
                'width'  => $shipping_width,
                'height' => $shipping_height,
            )
        );
    }

    echo '<div class="mv-shipping-info-table-wrap">';
    echo '<p class="mv-shipping-subtitle">' . esc_html__('Additional information', 'stak-multivendor') . '</p>';
    echo '<table class="mv-shipping-info-table" role="table" aria-label="' . esc_attr__('Additional information', 'stak-multivendor') . '">';
    echo '<tbody>';
    echo '<tr><th scope="row">' . esc_html__('Weight', 'stak-multivendor') . '</th><td>' . esc_html($shipping_weight_text) . '</td></tr>';
    echo '<tr><th scope="row">' . esc_html__('Dimensions', 'stak-multivendor') . '</th><td>' . esc_html($shipping_dimensions_text) . '</td></tr>';
    echo '</tbody>';
    echo '</table>';
    echo '</div>';

    echo '</div>';
    echo '</div>';

    $handling_line = __('Will ship within 1 business day of receiving cleared payment.', 'stak-multivendor');
    if ($handling_days > 1) {
        /* translators: %d is the number of business days before shipment. */
        $handling_format = __('Will ship within %d business days of receiving cleared payment.', 'stak-multivendor');
        $handling_line = sprintf(
            $handling_format,
            $handling_days
        );
    } elseif ($handling_days === 1) {
        $handling_line = __('Will ship within 1 business day of receiving cleared payment.', 'stak-multivendor');
    }

    $returns_line = __('Seller does not accept returns.', 'stak-multivendor');
    if ($returns_policy === 'returns_accepted') {
        /* translators: %d is the number of return days. */
        $returns_line = sprintf(__('Returns accepted within %d days.', 'stak-multivendor'), $returns_days);
    }
    $returns_shipping_line = $returns_policy === 'returns_accepted'
        ? ($return_shipping_paid_by === 'seller'
            ? __('Seller pays for return shipping.', 'stak-multivendor')
            : __('Buyer pays for return shipping.', 'stak-multivendor'))
        : '';
    $supported_carriers_text = !empty($shipping_carriers) ? implode(', ', $shipping_carriers) : __('Not specified', 'stak-multivendor');

    echo '<div id="' . esc_attr($shipping_details_modal_id) . '" class="mv-shipping-details-modal" aria-hidden="true">';
    echo '<div class="mv-shipping-details-modal__dialog" role="dialog" aria-modal="true" aria-label="' . esc_attr__('Shipping details', 'stak-multivendor') . '">';
    echo '<button type="button" class="mv-shipping-details-modal__close" aria-label="' . esc_attr__('Close shipping details', 'stak-multivendor') . '">×</button>';
    echo '<p class="mv-shipping-details-modal__title">' . esc_html__('Shipping, returns, and payments', 'stak-multivendor') . '</p>';
    echo '<div class="mv-shipping-details-modal__body">';
    echo '<p class="mv-shipping-details-modal__row"><span class="mv-shipping-details-modal__label">' . esc_html__('Shipping', 'stak-multivendor') . '</span><span class="mv-shipping-details-modal__value">' . esc_html($shipping_mode === 'flat' ? $shipping_value : ($shipping_mode === 'free' ? __('Free shipping', 'stak-multivendor') : ($shipping_mode === 'pickup_only' ? __('Pickup only', 'stak-multivendor') : __('Calculated at checkout', 'stak-multivendor')))) . '</span></p>';
    echo '<p class="mv-shipping-details-modal__row"><span class="mv-shipping-details-modal__label">' . esc_html__('Supported carriers', 'stak-multivendor') . '</span><span class="mv-shipping-details-modal__value">' . esc_html($supported_carriers_text) . '</span></p>';
    echo '<p class="mv-shipping-details-modal__row"><span class="mv-shipping-details-modal__label">' . esc_html__('Location', 'stak-multivendor') . '</span><span class="mv-shipping-details-modal__value">' . esc_html($location !== '' ? $location : __('Not specified', 'stak-multivendor')) . '</span></p>';
    echo '<p class="mv-shipping-details-modal__row"><span class="mv-shipping-details-modal__label">' . esc_html__('Ships to', 'stak-multivendor') . '</span><span class="mv-shipping-details-modal__value">' . esc_html($shipping_scope_text) . '</span></p>';
    echo '<p class="mv-shipping-details-modal__row"><span class="mv-shipping-details-modal__label">' . esc_html__('Handling time', 'stak-multivendor') . '</span><span class="mv-shipping-details-modal__value">' . esc_html($handling_line) . '</span></p>';
    echo '<p class="mv-shipping-details-modal__row"><span class="mv-shipping-details-modal__label">' . esc_html__('Returns', 'stak-multivendor') . '</span><span class="mv-shipping-details-modal__value">' . esc_html($returns_line . ($returns_shipping_line !== '' ? ' ' . $returns_shipping_line : '')) . '</span></p>';
    echo '</div>';
    echo '</div>';
    echo '</div>';

    if (!empty($vendor_reputation['total_orders'])) {
        echo '<div class="mv-seller-trust-panel">';
        echo '<p class="mv-seller-trust-title">Seller reputation</p>';

        if (!empty($vendor_rating_summary['count'])) {
            echo '<p class="mv-seller-trust-row"><strong>Rating:</strong> ' .
                esc_html(number_format_i18n((float) ($vendor_rating_summary['average'] ?? 0), 1)) . '/5 (' .
                esc_html((string) ((int) ($vendor_rating_summary['count'] ?? 0))) . ')</p>';
        }

        echo '<p class="mv-seller-trust-row"><strong>Fulfillment:</strong> ' .
            esc_html(number_format_i18n((float) ($vendor_reputation['fulfillment_rate'] ?? 0), 1)) . '%</p>';

        echo '<p class="mv-seller-trust-row"><strong>Cancellation rate:</strong> ' .
            esc_html(number_format_i18n((float) ($vendor_reputation['cancellation_rate'] ?? 0), 1)) . '%</p>';

        if (!empty($vendor_reputation['avg_shipping_days'])) {
            echo '<p class="mv-seller-trust-row"><strong>Avg shipping speed:</strong> ' .
                esc_html(number_format_i18n((float) $vendor_reputation['avg_shipping_days'], 1)) . ' days</p>';
        }

        if (!empty($vendor_reputation['repeat_buyers_rate'])) {
            echo '<p class="mv-seller-trust-row"><strong>Repeat buyers:</strong> ' .
                esc_html(number_format_i18n((float) $vendor_reputation['repeat_buyers_rate'], 1)) . '%</p>';
        }

        if (!empty($vendor_reputation['dispute_rate'])) {
            echo '<p class="mv-seller-trust-row"><strong>Dispute rate:</strong> ' .
                esc_html(number_format_i18n((float) $vendor_reputation['dispute_rate'], 1)) . '%</p>';
        }

        echo '</div>';
    }

    if ( $is_owner_global ) {
        $edit_url = add_query_arg( 'edit', $auction_id, stakmv_get_create_listing_url() );
        echo '<p class="mv-mt-12"><a class="button" href="' . esc_url( $edit_url ) . '">Edit listing</a></p>';
    }

    echo '</div>';
}, 35);

/**
 * Add to cart support for buy-now-only auction listings.
 */
add_action('stakmv_auction_add_to_cart', function () {
    global $product;
    if (!$product || $product->get_type() !== 'auction') {
        return;
    }

    $listing_type = get_post_meta($product->get_id(), '_stakmv_auction_listing_type', true);
    if ($listing_type !== 'buy_now_only') {
        return;
    }

    $buy_now_price = (float) get_post_meta($product->get_id(), '_stakmv_auction_buy_now_price', true);
    echo '<form class="cart" method="post" enctype="multipart/form-data">';
    if ($buy_now_price > 0) {
        echo '<button type="submit" class="mv-btn buy" name="add-to-cart" value="' . esc_attr($product->get_id()) . '">
            <span class="mv-btn-label">Add to cart</span>
            <span class="mv-btn-price-chip">' . wp_kses_post(wc_price($buy_now_price)) . '</span>
        </button>';
    } else {
        echo '<button type="submit" class="mv-btn buy" name="add-to-cart" value="' . esc_attr($product->get_id()) . '">
            <span class="mv-btn-label">Add to cart</span>
        </button>';
    }
    echo '</form>';
}, 10, 0);

add_filter('woocommerce_is_purchasable', function ($purchasable, $product) {
    if (!$product || $product->get_type() !== 'auction') {
        return $purchasable;
    }

    $listing_type = get_post_meta($product->get_id(), '_stakmv_auction_listing_type', true);
    if ($listing_type === 'buy_now_only') {
        return true;
    }

    return $purchasable;
}, 10, 2);

add_filter('woocommerce_add_to_cart_validation', function ($passed, $product_id) {
    $product = wc_get_product($product_id);
    if ($product && $product->get_type() === 'auction') {
        $listing_type = get_post_meta($product_id, '_stakmv_auction_listing_type', true);
        if ($listing_type !== 'buy_now_only') {
            wc_add_notice('This item cannot be added to cart.', 'error');
            return false;
        }
    }
    return $passed;
}, 10, 2);

/**
 * HANDLE BIDDING
 */
add_action('template_redirect', function () {

    if (!isset($_POST['stakmv_place_bid'])) return;

    if (
        !isset($_POST['stakmv_bid_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(wp_unslash($_POST['stakmv_bid_nonce'])),
            'stakmv_place_bid'
        )
    ) {
        wc_add_notice('Security validation failed.', 'error');
        wp_safe_redirect(wp_get_referer() ?: home_url('/'));
exit;

    }

    $auction_id = isset($_POST['stakmv_auction_id']) ? absint(wp_unslash($_POST['stakmv_auction_id'])) : 0;

    if (!is_user_logged_in()) {
        wc_add_notice('You must be logged in to bid.', 'error');
       wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

    }

    if (
        (function_exists('stakmv_auctions_enabled')
            ? stakmv_auctions_enabled()
            : (stakmv_get_option('enable_auctions', 'yes') === 'yes')) !== true
    ) {
        wc_add_notice('Bidding is currently disabled.', 'error');
        wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;
    }

    $bid_amount = (float) sanitize_text_field(wp_unslash($_POST['stakmv_bid_amount'] ?? 0));
    $user_id    = get_current_user_id();
    $author_id  = (int) get_post_field('post_author', $auction_id);
    if ($author_id === $user_id) {
        wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

    }

    if (get_post_meta($auction_id, '_stakmv_auction_status', true) === 'sold') {
        wc_add_notice('Auction already sold.', 'error');
        wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

    }

    $current_bid = stakmv_get_highest_bid($auction_id);
    if ($bid_amount <= $current_bid) {
        wc_add_notice('Your bid must be higher.', 'error');
       wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

    }

    $bid_id = function_exists('stakmv_insert_bid_row')
        ? stakmv_insert_bid_row($auction_id, $user_id, $bid_amount)
        : 0;

    // Auction lifecycle hooks for extensions.
    do_action('stakmv_auction_bid_placed', $auction_id, $bid_amount, $user_id, $bid_id, 'manual');
    do_action('stakmv_auction_extend_time', $auction_id, $bid_amount, $user_id);

    wc_add_notice('Bid placed successfully!', 'success');
   wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

});

/**
 * HANDLE BUY NOW (FASTEST FINGER)
 */
add_action('template_redirect', function () {

    if (!isset($_POST['stakmv_buy_now'])) return;

    if (
        !isset($_POST['stakmv_buy_now_nonce']) ||
        !wp_verify_nonce(
            sanitize_text_field(wp_unslash($_POST['stakmv_buy_now_nonce'])),
            'stakmv_buy_now'
        )
    ) {
        wc_add_notice('Security check failed.', 'error');
        wp_safe_redirect(wp_get_referer() ?: home_url('/'));
        exit;

    }

    $auction_id = isset($_POST['stakmv_auction_id']) ? absint(wp_unslash($_POST['stakmv_auction_id'])) : 0;

    if (!is_user_logged_in()) {
        wc_add_notice('You must be logged in to buy.', 'error');
        wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

    }

    $user_id    = get_current_user_id();

    if (get_post_meta($auction_id, '_stakmv_auction_status', true) === 'sold') {
        wc_add_notice('Sorry, this item was just sold.', 'error');
       wp_safe_redirect(
    wp_get_referer() ?: get_permalink($auction_id)
);
exit;

    }

    $product = wc_get_product($auction_id);
    $price   = (float) get_post_meta($auction_id, '_stakmv_auction_buy_now_price', true);

    $order = wc_create_order(['customer_id' => $user_id]);
    $order->add_product($product, 1, ['subtotal' => $price, 'total' => $price]);

    $shipping_cost = (float) get_post_meta($auction_id, '_stakmv_auction_shipping_cost', true);
    if ($shipping_cost > 0) {
        $order->add_fee([
            'name'   => 'Shipping',
            'amount' => $shipping_cost,
        ]);
    }

    $order->update_meta_data('_stakmv_auction_id', $auction_id);
    $order->update_meta_data('_buy_now_used', true);
    $order->set_status('pending', 'Fastest-finger Buy Now attempt');

    $order->calculate_totals();
    $order->save();

    wp_safe_redirect(
        add_query_arg(
            ['key' => $order->get_order_key(), 'pay_for_order' => 'true'],
            wc_get_endpoint_url('order-pay', $order->get_id(), wc_get_checkout_url())
        )
    );
    exit;
});
