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

class VS_Admin_Moderation {

    private static function notify_vendor_product_moderation($product_id, $status = 'approved', $reason = '') {
        $product_id = (int) $product_id;
        
        // Respect existing notification flag for rejection
        if ($status === 'rejected' && get_post_meta($product_id, '_vs_rejection_notified', true)) {
            return;
        }
        $product_post = get_post($product_id);
        if (!$product_post) return;

        $vendor_id = (int) $product_post->post_author;
        if ($vendor_id <= 0) return;

        $vendor = get_userdata($vendor_id);
        if (!$vendor || empty($vendor->user_email)) return;

        $product_name = get_the_title($product_id);
        $site_name = get_bloginfo('name');
        $accent_color = ($status === 'rejected') ? '#ef4444' : '#10b981';

        if ($status === 'rejected') {
            $final_reason = trim((string) $reason) ?: __('Our team reviewed your product and it does not meet our guidelines.', 'vendor-space');
            $subject = sprintf(__('[%s] Product Update: Feedback Required', 'vendor-space'), $site_name);
            $content_title = __('Product Requires Adjustments', 'vendor-space');
            $content_desc = sprintf(__('We reviewed your product "<strong>%s</strong>" and unfortunately, it cannot be published in its current state.', 'vendor-space'), esc_html($product_name));
            $action_btn = '<a href="' . site_url('/vendor-dashboard/?tab=products') . '" style="display:inline-block;padding:12px 24px;background:#ef4444;color:#ffffff;text-decoration:none;font-weight:700;border-radius:8px;">' . esc_html__('Edit Product', 'vendor-space') . '</a>';
            $extra_info = '<div style="background:#fef2f2;border-left:4px solid #ef4444;padding:16px;margin:24px 0;border-radius:0 8px 8px 0;text-align:left;"><strong style="display:block;margin-bottom:4px;color:#991b1b;font-size:13px;text-transform:uppercase;">' . esc_html__('Reason for Rejection', 'vendor-space') . '</strong><p style="margin:0;color:#7f1d1d;line-height:1.5;">' . nl2br(esc_html($final_reason)) . '</p></div>';
        } else {
            $subject = sprintf(__('[%s] Product Live: Approved!', 'vendor-space'), $site_name);
            $content_title = __('Congratulations!', 'vendor-space');
            $content_desc = sprintf(__('Your product "<strong>%s</strong>" has been approved and is now live on our marketplace.', 'vendor-space'), esc_html($product_name));
            $action_btn = '<a href="' . esc_url(get_permalink($product_id)) . '" style="display:inline-block;padding:12px 24px;background:#10b981;color:#ffffff;text-decoration:none;font-weight:700;border-radius:8px;">' . esc_html__('View Live Product', 'vendor-space') . '</a>';
            $extra_info = '';
        }

        $message = '
        <div style="background:#f4f7fb;padding:32px 16px;font-family:Arial,Helvetica,sans-serif;color:#334155;">
            <div style="max-width:550px;margin:0 auto;background:#ffffff;border-radius:16px;padding:32px;box-shadow:0 10px 40px rgba(15,23,42,0.08);border:1px solid #e5e7eb;text-align:center;">
                <div style="margin-bottom:24px;">
                    <h2 style="margin:0;font-size:24px;color:#0f172a;line-height:1.2;">' . esc_html($content_title) . '</h2>
                    <p style="margin:12px 0 0;font-size:15px;color:#64748b;line-height:1.6;">' . $content_desc . '</p>
                </div>
                
                ' . $extra_info . '

                <div style="margin-top:32px;">
                    ' . $action_btn . '
                </div>
                
                <div style="margin-top:32px;padding-top:24px;border-top:1px solid #f1f5f9;text-align:center;font-size:12px;color:#94a3b8;">
                    ' . sprintf(esc_html__('Thank you for being a part of %s.', 'vendor-space'), $site_name) . '<br>
                    ' . esc_html__('Regards,', 'vendor-space') . ' ' . esc_html($site_name) . '
                </div>
            </div>
        </div>';

        $headers = ['Content-Type: text/html; charset=UTF-8'];
        $sent = wp_mail($vendor->user_email, $subject, $message, $headers);
        
        if ($sent && $status === 'rejected') {
            update_post_meta($product_id, '_vs_rejection_notified', '1');
        }
    }

    public static function render_front_requests_rows() {
        if (!current_user_can('manage_options')) return '';
        $args = [
            'post_type'   => 'product',
            'post_status' => 'pending',
            'numberposts' => -1,
        ];
        $pending_products = get_posts($args);
        ob_start();
        if (empty($pending_products)) {
            ?>
            <tr>
              <td colspan="8">
                <div class="vs-empty-state">
                  <div class="vs-empty-icon">
                    <i class="fa-regular fa-folder-open"></i>
                  </div>
                  <div class="vs-empty-title">No pending requests</div>
                  <div class="vs-empty-sub">Everything is up to date</div>
                </div>
              </td>
            </tr>
            <?php
        } else {
            foreach ($pending_products as $p) {
                $vendor = get_userdata($p->post_author);
                $vendor_name = $vendor ? $vendor->display_name : 'Unknown';
                $price = get_post_meta($p->ID, '_price', true);
                $img = get_the_post_thumbnail($p->ID, [50, 50]) ?: '<span class="dashicons dashicons-format-image" style="font-size:40px; color:#ccc;"></span>';
                $categories = wp_get_post_terms($p->ID, 'product_cat');
                $category_names = array();
                if (!is_wp_error($categories) && !empty($categories)) {
                    foreach ($categories as $cat) {
                        $category_names[] = esc_html($cat->name);
                    }
                }
                $category_display = !empty($category_names) ? implode(', ', $category_names) : '<em style="color:#999;">No category</em>';
                ?>
                <tr id="vs-mod-row-<?php echo $p->ID; ?>">
                    <td><input type="checkbox" class="vs-product-checkbox" value="<?php echo $p->ID; ?>"></td>
                    <td><?php echo $img; ?></td>
                    <td><strong><?php echo esc_html($p->post_title); ?></strong></td>
                    <td><?php echo $category_display; ?></td>
                    <td><?php echo esc_html($vendor_name); ?></td>
                    <td><?php echo wc_price($price); ?></td>
                    <td><?php echo get_the_date('M j, Y g:i a', $p->ID); ?></td>
                    <td>
                       <button class="vs-btn vs-approve-front-btn" data-id="<?php echo $p->ID; ?>" data-tooltip="<?php echo esc_attr__('Approve', 'vendor-space'); ?>" style="background:#10b981; color:#fff; border:none; padding:6px 8px; border-radius:6px; font-size:14px; margin-right:5px; position:relative;">
                            <i class="fa-solid fa-check"></i>
                        </button>
                        <button class="vs-btn vs-reject-front-btn" data-id="<?php echo $p->ID; ?>" data-tooltip="<?php echo esc_attr__('Reject', 'vendor-space'); ?>" style="background:#ef4444; color:#fff; border:none; padding:6px 8px; border-radius:6px; font-size:14px; position:relative;">
                            <i class="fa-solid fa-xmark"></i>
                        </button>
                    </td>
                </tr>
                <?php
            }
        }
        return ob_get_clean();
    }

    public static function init() {
        add_action('admin_menu', [__CLASS__, 'register_moderation_menu'], 25);
        add_action('wp_ajax_vs_approve_product', [__CLASS__, 'approve_product_ajax']);
        add_action('wp_ajax_vs_reject_product', [__CLASS__, 'reject_product_ajax']);
        add_action('wp_ajax_vs_approve_bulk_products', [__CLASS__, 'approve_bulk_products_ajax']);
        add_action('wp_ajax_vs_reject_bulk_products', [__CLASS__, 'reject_bulk_products_ajax']);
        
        // Vendor Account Moderation
        add_action('wp_ajax_vs_approve_vendor', [__CLASS__, 'approve_vendor_ajax']);
        add_action('wp_ajax_vs_reject_vendor', [__CLASS__, 'reject_vendor_ajax']);

        add_action('wp_ajax_nopriv_vs_approve_product', [__CLASS__, 'approve_product_ajax']);
        add_action('wp_ajax_nopriv_vs_reject_product', [__CLASS__, 'reject_product_ajax']);

        // Polling endpoints for dynamic UI updates
        add_action('wp_ajax_vs_get_pending_counts', [__CLASS__, 'ajax_get_pending_counts']);
        add_action('wp_ajax_vs_refresh_publish_requests_rows', [__CLASS__, 'ajax_refresh_publish_requests_rows']);

        // Vendor-side approval for admin-assigned products
        add_action('wp_ajax_vs_vendor_approve_product', [__CLASS__, 'vendor_approve_product_ajax']);
        add_action('wp_ajax_vs_vendor_reject_product', [__CLASS__, 'vendor_reject_product_ajax']);
        // Hook للتحقق من الموافقة اليدوية عند تغيير حالة المنتج
        add_action('transition_post_status', [__CLASS__, 'check_vendor_product_approval'], 10, 3);

        add_action('save_post_product', [__CLASS__, 'check_product_save'], 10, 2);
        // Safety net: if a product is moved from pending to draft as rejected, ensure email is sent.
        add_action('transition_post_status', [__CLASS__, 'maybe_notify_vendor_on_reject_transition'], 20, 3);
    }

    public static function maybe_notify_vendor_on_reject_transition($new_status, $old_status, $post) {
        if (!$post || $post->post_type !== 'product') {
            return;
        }

        if ($old_status !== 'pending' || $new_status !== 'draft') {
            return;
        }

        $product_id = (int) $post->ID;
        if (!$product_id) {
            return;
        }

        if (!get_post_meta($product_id, '_vs_rejected', true)) {
            return;
        }

        if (get_post_meta($product_id, '_vs_rejection_notified', true)) {
            return;
        }

        $reason = (string) get_post_meta($product_id, '_vs_reject_reason', true);
        self::notify_vendor_product_moderation($product_id, 'rejected', $reason);
        update_post_meta($product_id, '_vs_rejection_notified', '1');
    }

   
    public static function is_manual_approval_enabled() {
        $settings = VS_Admin_Settings::get_settings();
        return isset($settings['vendors']['manual_vendor_approval']) 
            && $settings['vendors']['manual_vendor_approval'] === 'yes';
    }

    public static function check_product_save($post_id, $post) {
        if (!self::is_manual_approval_enabled()) {
            return;
        }

        if (current_user_can('manage_options')) {
            return;
        }

        if ($post->post_status === 'publish') {
            wp_update_post([
                'ID'          => $post_id,
                'post_status' => 'pending'
            ]);
        }
    }

  
    public static function check_vendor_product_approval($new_status, $old_status, $post) {
        if ($post->post_type !== 'product') {
            return;
        }

        if (!self::is_manual_approval_enabled()) {
            return;
        }

        if ($new_status === 'pending') {
            return;
        }

        if ($new_status === 'publish' && in_array($old_status, ['draft', 'pending', 'auto-draft'])) {
            $can_publish_directly = current_user_can('manage_options');
            
            if (!$can_publish_directly) {
                remove_action('transition_post_status', [__CLASS__, 'check_vendor_product_approval'], 10);
                
                wp_update_post([
                    'ID'          => $post->ID,
                    'post_status' => 'pending'
                ]);
                
                add_action('transition_post_status', [__CLASS__, 'check_vendor_product_approval'], 10, 3);

           
            }
        }
    }

 
    /**
     * Notify admin about a new vendor application
     */
    public static function notify_admin_new_vendor_application($user_id) {
        $user_id = (int) $user_id;
        if ($user_id <= 0) return;

        $user = get_userdata($user_id);
        if (!$user) return;

        $store_name = get_user_meta($user_id, 'vs_store_name', true) ?: $user->display_name;
        $admin_email = 'mekkaouifouad32@gmail.com';

        $subject = sprintf(__('[%s] New Vendor Application: %s', 'vendor-space'), get_bloginfo('name'), esc_html($store_name));

        $message = sprintf(
            __("A new vendor application has been submitted by %s (%s).\n\nStore name: %s\n\nReview applications here: %s", 'vendor-space'),
            esc_html($user->display_name),
            esc_html($user->user_email),
            esc_html($store_name),
            admin_url('admin.php?page=vs-vendor-requests')
        );

        $headers = ['Content-Type: text/plain; charset=UTF-8'];
        wp_mail($admin_email, $subject, $message, $headers);
    }

    public static function register_moderation_menu() {
        $pending_products = self::get_pending_count();
        $pending_vendors  = self::get_pending_vendors_count();
        $total_pending    = $pending_products + $pending_vendors;

        $badge = $total_pending > 0 ? " <span class='update-plugins count-$total_pending'><span class='plugin-count'>$total_pending</span></span>" : "";

       
    }

    public static function render_moderation_page_wrapper() {
        echo '<div class="vs-moderation-page-wrapper" style="padding: 20px;">';
        
        // Sub-navigation - Only products here now
        echo '<div class="vs-mod-sub-nav" style="margin-bottom: 30px; border-bottom: 2px solid #e2e8f0; display: flex; gap: 30px;">';
        echo '<a href="#" class="vs-mod-nav-item active" data-target="tab-publish-requests" style="padding: 10px 5px; text-decoration: none; color: #2563eb; font-weight: 700; border-bottom: 3px solid #2563eb; transition: all 0.2s;">Product Requests</a>';
        echo '</div>';

        echo '<div class="vs-mod-tabs-content">';
        echo self::render_front_requests_tab();
        echo '</div>';

        echo '<script>
            jQuery(document).ready(function($) {
                $(".vs-mod-nav-item").on("click", function(e) {
                    e.preventDefault();
                    var target = $(this).data("target");
                    
                    // Update Nav
                    $(".vs-mod-nav-item").removeClass("active").css({"color": "#64748b", "font-weight": "600", "border-bottom-color": "transparent"});
                    $(this).addClass("active").css({"color": "#2563eb", "font-weight": "700", "border-bottom-color": "#2563eb"});
                    
                    // Update Tabs
                    $(".vs-tab").hide();
                    $("#" + target).show();
                });
                
                // Show first tab by default
                $("#tab-publish-requests").show();
            });
        </script>';
        echo '</div>';
    }
        
    public static function render_vendor_requests_page_wrapper() {
        echo '<div class="vs-moderation-page-wrapper" style="padding: 20px;">';
        
        // Sub-navigation
        echo '<div class="vs-mod-sub-nav" style="margin-bottom: 30px; border-bottom: 2px solid #e2e8f0; display: flex; gap: 30px;">';
        echo '<a href="#" class="vs-mod-nav-item active" data-target="tab-vendor-requests" style="padding: 10px 5px; text-decoration: none; color: #2563eb; font-weight: 700; border-bottom: 3px solid #2563eb; transition: all 0.2s;">Request Login (Vendor Requests)</a>';
        echo '</div>';

        echo '<div class="vs-mod-tabs-content">';
        echo self::render_admin_vendor_applications_tab();
        echo '</div>';

        echo '<script>
            jQuery(document).ready(function($) {
                $("#tab-vendor-requests").show();
            });
        </script>';
        
        echo '</div>';
    }

    public static function get_vendor_pending_count($user_id) {
        $args = [
            'post_type'   => 'product',
            'post_status' => 'pending_vendor',
            'author'      => (int) $user_id,
            'numberposts' => -1,
            'fields'      => 'ids'
        ];
        $posts = get_posts($args);
        return count($posts);
    }

    public static function get_pending_count() {
        $args = [
            'post_type'   => 'product',
            'post_status' => 'pending',
            'numberposts' => -1,
            'fields'      => 'ids'
        ];
        return count(get_posts($args));
    }

    public static function get_pending_vendors_count() {
        $args = [
            'meta_key'     => 'vs_vendor_status',
            'meta_value'   => 'pending',
            'fields'       => 'ID',
            'number'       => -1,
        ];
        $users = get_users($args);
        return count($users);
    }

    /**
     * AJAX Handler - الموافقة على المنتج
     */
    public static function approve_product_ajax() {
        check_ajax_referer('vs_moderation_nonce', 'security');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'vendor-space'));
        }

        $product_id = intval($_POST['product_id'] ?? 0);
        if (!$product_id) {
            wp_send_json_error(__('Invalid product ID', 'vendor-space'));
        }

        $result = wp_update_post([
            'ID' => $product_id,
            'post_status' => 'publish'
        ]);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        delete_post_meta($product_id, '_vs_rejected');
        
        self::notify_vendor_product_moderation($product_id, 'approved');

        wp_send_json_success([ 'message' => __('Product approved successfully', 'vendor-space'), 'pending_count' => self::get_pending_count() ]);
    }

    /**
     * AJAX Handler - رفض المنتج
     */
    public static function reject_product_ajax() {
        check_ajax_referer('vs_moderation_nonce', 'security');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'vendor-space'));
        }

        $product_id = intval($_POST['product_id'] ?? 0);
        if (!$product_id) {
            wp_send_json_error(__('Invalid product ID', 'vendor-space'));
        }

        $reason = sanitize_text_field($_POST['reason'] ?? __('Your product does not meet our guidelines.', 'vendor-space'));
        update_post_meta($product_id, '_vs_rejected', '1');
        update_post_meta($product_id, '_vs_reject_reason', $reason);
        delete_post_meta($product_id, '_vs_rejection_notified');

        $result = wp_update_post([
            'ID' => $product_id,
            'post_status' => 'draft'
        ]);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        self::notify_vendor_product_moderation($product_id, 'rejected', $reason);
        update_post_meta($product_id, '_vs_rejection_notified', '1');

        wp_send_json_success([ 'message' => __('Product rejected successfully', 'vendor-space'), 'pending_count' => self::get_pending_count() ]);
    }

    /**
     * AJAX Handler - bulk approve products
     */
    public static function approve_bulk_products_ajax() {
        check_ajax_referer('vs_moderation_nonce', 'security');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'vendor-space'));
        }

        $ids = is_array($_POST['product_ids']) ? array_map('intval', $_POST['product_ids']) : [];
        if (empty($ids)) {
            wp_send_json_error(__('No products selected', 'vendor-space'));
        }

        $success_count = 0;
        foreach ($ids as $pid) {
            $res = wp_update_post(['ID' => $pid, 'post_status' => 'publish']);
            if (!is_wp_error($res)) {
                $success_count++;
                delete_post_meta($pid, '_vs_rejected');

                self::notify_vendor_product_moderation($pid, 'approved');
            }
        }

        wp_send_json_success(['message' => sprintf(__('%d products approved.', 'vendor-space'), $success_count), 'pending_count' => self::get_pending_count()]);
    }

    /**
     * AJAX Handler - bulk reject products
     */
    public static function reject_bulk_products_ajax() {
        check_ajax_referer('vs_moderation_nonce', 'security');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'vendor-space'));
        }

        $ids = is_array($_POST['product_ids']) ? array_map('intval', $_POST['product_ids']) : [];
        if (empty($ids)) {
            wp_send_json_error(__('No products selected', 'vendor-space'));
        }

        $reason = sanitize_text_field($_POST['reason'] ?? __('Rejected by administrator.', 'vendor-space'));
        $success_count = 0;
        foreach ($ids as $pid) {
            update_post_meta($pid, '_vs_rejected', '1');
            update_post_meta($pid, '_vs_reject_reason', $reason);
            delete_post_meta($pid, '_vs_rejection_notified');
            $res = wp_update_post(['ID' => $pid, 'post_status' => 'draft']);
            if (!is_wp_error($res)) {
                $success_count++;
                self::notify_vendor_product_moderation($pid, 'rejected', $reason);
            }
        }

        wp_send_json_success(['message' => sprintf(__('%d products rejected.', 'vendor-space'), $success_count), 'pending_count' => self::get_pending_count()]);
    }

    public static function render_front_requests_tab() {
        if (!current_user_can('manage_options')) return '';
        $pending_count = self::get_pending_count();
        $args = [
            'post_type'   => 'product',
            'post_status' => 'pending',
            'numberposts' => -1,
        ];
        $pending_products = get_posts($args);

        ob_start();
        ?>
        <div id="tab-publish-requests" class="vs-tab" style="display:none;">
            <div class="vs-dashboard-header" style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; border-bottom: 2px solid #2563eb; padding-bottom: 10px;">
                <h2 id="vs-publish-requests-title" style="margin:0; font-size:24px; color:#1e293b;">Publish Requests (<span id="vs-publish-requests-count"><?php echo $pending_count; ?></span>)</h2>
            </div>
            
            <div id="vs-bulk-actions-front" style="margin-bottom: 15px; display: none; padding: 10px; background: #f0f0f0; border-radius: 4px;">
                <button id="vs-approve-all-front-btn" class="vs-btn" data-tooltip="<?php echo esc_attr__('Approve Selected', 'vendor-space'); ?>" style="background:#10b981; color:#fff; border:none; padding:8px 15px; border-radius:4px; font-size:13px; margin-right: 10px; cursor: pointer; position:relative;">✓ Approve Selected</button>
                <button id="vs-reject-all-front-btn" class="vs-btn" data-tooltip="<?php echo esc_attr__('Reject Selected', 'vendor-space'); ?>" style="background:#ef4444; color:#fff; border:none; padding:8px 15px; border-radius:4px; font-size:13px; cursor: pointer; position:relative;">✕ Reject Selected</button>
                <span id="vs-selected-count-front" style="margin-left: 15px; color: #666;">0 selected</span>
            </div>
            
            <div class="vs-moderation-container">
                <table class="vs-products-table">
                    <thead>
                        <tr>
                        <th width="30"  style="padding: 15px 20px; font-weight: 600; background-color: #f8fafc;"><input type="checkbox" id="vs-select-all" title="Select all"></th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Image</th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Product Name</th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Category</th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Vendor</th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Price</th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Date Submitted</th>
                        <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;" width="200">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        <style>
                            .vs-empty-state {
    padding: 40px 20px;
    text-align: center;
    border-radius: 12px;
    background: #f9fafb;
    border: 1px dashed #e5e7eb;
    transition: all 0.3s ease;
}

.vs-empty-state:hover {
    background: #f3f4f6;
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0,0,0,0.05);
}

.vs-empty-icon {
    font-size: 48px;
    color: #9ca3af;
    margin-bottom: 12px;
    transition: 0.3s;
}

.vs-empty-state:hover .vs-empty-icon {
    transform: scale(1.1);
    color: #6b7280;
}

.vs-empty-title {
    font-size: 16px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 5px;
}

.vs-empty-sub {
    font-size: 13px;
    color: #9ca3af;
}
.vs-empty-state {
    animation: fadeIn 0.5s ease;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}
                        </style>
                                                <?php echo self::render_front_requests_rows(); ?>
                    </tbody>
                </table>
            </div>
        </div>

        <script>
        jQuery(document).ready(function($) {
            // Select All Checkbox (Front)
            $('#vs-select-all-front').on('change', function() {
                $('.vs-front-product-checkbox').prop('checked', this.checked);
                updateBulkActionsFrontUI();
            });

            // Individual Checkboxes (Front)
            $(document).on('change', '.vs-front-product-checkbox', function() {
                const allChecked = $('.vs-front-product-checkbox:not(:checked)').length === 0;
                $('#vs-select-all-front').prop('checked', allChecked);
                updateBulkActionsFrontUI();
            });

            // Update UI for bulk actions (Front)
            function updateBulkActionsFrontUI() {
                const selected = $('.vs-front-product-checkbox:checked').length;
                if (selected > 0) {
                    $('#vs-bulk-actions-front').show();
                    $('#vs-selected-count-front').text(selected + ' selected');
                } else {
                    $('#vs-bulk-actions-front').hide();
                }
            }

            // Approve All Selected (Front)
            $('#vs-approve-all-front-btn').on('click', function() {
                const selected = $('.vs-front-product-checkbox:checked').map(function() { return $(this).val(); }).get();
                if (!selected.length) return;
                
                Swal.fire({
                    title: 'Approve ' + selected.length + ' product(s)?',
                    icon: 'question',
                    showCancelButton: true,
                    confirmButtonText: 'Yes, Approve All',
                    confirmButtonColor: '#10b981'
                }).then((result) => {
                    if (result.isConfirmed) {
                        const btn = $('#vs-approve-all-front-btn');
                        btn.prop('disabled', true).text('...');

                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_approve_bulk_products',
                            product_ids: selected,
                            security: '<?php echo wp_create_nonce("vs_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                selected.forEach(function(id) {
                                    $('#vs-front-req-row-' + id).fadeOut(function() { $(this).remove(); });
                                });
                                $('#vs-select-all-front').prop('checked', false);
                                updateBulkActionsFrontUI();
                                updatePublishRequestsBadge(null, res.data.pending_count);
                                Swal.fire('Success!', res.data.message, 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed to approve', 'error');
                            }
                            btn.prop('disabled', false).text('✓ Approve Selected');
                        });
                    }
                });
            });

            // Reject All Selected (Front)
            $('#vs-reject-all-front-btn').on('click', function() {
                const selected = $('.vs-front-product-checkbox:checked').map(function() { return $(this).val(); }).get();
                if (!selected.length) return;
                
                Swal.fire({
                    title: 'Reject ' + selected.length + ' product(s)?',
                    input: 'textarea',
                    inputLabel: 'Reason for rejection',
                    inputPlaceholder: 'Type your reason here...',
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonText: 'Yes, Reject All',
                    confirmButtonColor: '#ef4444'
                }).then((result) => {
                    if (result.isConfirmed) {
                        const reason = result.value || 'Rejected by administrator.';
                        const btn = $('#vs-reject-all-front-btn');
                        btn.prop('disabled', true).text('...');

                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_reject_bulk_products',
                            product_ids: selected,
                            reason: reason,
                            security: '<?php echo wp_create_nonce("vs_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                selected.forEach(function(id) {
                                    $('#vs-mod-row-' + id).fadeOut(function() { $(this).remove(); });
                                });
                                $('#vs-select-all').prop('checked', false);
                                $('.vs-product-checkbox').prop('checked', false);
                                updateBulkActionsFrontUI();
                                updatePublishRequestsBadge(null, res.data.pending_count);
                                Swal.fire('Success!', res.data.message, 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed to reject', 'error');
                            }
                            btn.prop('disabled', false).text('✕ Reject Selected');
                        });
                    }
                });
            });

            $(document).on('click', '.vs-approve-front-btn', function() {
                const btn = $(this);
                const pid = btn.data('id');
                
                Swal.fire({
                    title: 'Approve this product?',
                    icon: 'question',
                    showCancelButton: true,
                    confirmButtonText: 'Yes, Approve',
                    confirmButtonColor: '#10b981'
                }).then((result) => {
                    if (result.isConfirmed) {
                        btn.prop('disabled', true).text('...');
                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_approve_product',
                            product_id: pid,
                            security: '<?php echo wp_create_nonce("vs_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                $('#vs-front-req-row-' + pid).fadeOut();
                                updatePublishRequestsBadge(-1);
                                Swal.fire('Approved!', 'The product is now live.', 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed to approve', 'error');
                                btn.prop('disabled', false).text('Approve');
                            }
                        });
                    }
                });
            });

            function setPublishRequestsCount(count) {
                const n = Math.max(0, parseInt(count, 10) || 0);
                const $badge = $('#vs-publish-requests-badge');
                const $badgeP = $('#vs-products-badge');
                const $topCount = $('#vs-publish-requests-count');

                if ($badge.length) {
                    if (n > 0) { $badge.text(n).show(); } else { $badge.text('0').hide(); }
                }

                if ($badgeP.length) {
                    if (n > 0) { $badgeP.text(n).show(); } else { $badgeP.text('0').hide(); }
                }

                if ($topCount.length) {
                    $topCount.text(n);
                }
            }

            function updatePublishRequestsBadge(delta) {
                const current = parseInt($('#vs-publish-requests-count').text() || '0', 10) || 0;
                setPublishRequestsCount(Math.max(0, current + (delta || 0)));
            }

            $(document).on('click', '.vs-reject-front-btn', function() {
                const btn = $(this);
                const pid = btn.data('id');
                
                Swal.fire({
                    title: 'Reject this product?',
                    input: 'textarea',
                    inputLabel: 'Reason for rejection',
                    inputPlaceholder: 'Type your reason here...',
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonText: 'Yes, Reject',
                    confirmButtonColor: '#ef4444'
                }).then((result) => {
                    if (result.isConfirmed) {
                        const reason = result.value || 'Your product does not meet our guidelines.';
                        btn.prop('disabled', true).find('i').attr('class', 'fa-solid fa-spinner fa-spin');
                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_reject_product',
                            product_id: pid,
                            reason: reason,
                            security: '<?php echo wp_create_nonce("vs_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                $('#vs-mod-row-' + pid).fadeOut();
                                updatePublishRequestsBadge(-1);
                                Swal.fire('Rejected!', 'The feedback has been sent to the vendor.', 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed to reject', 'error');
                                btn.prop('disabled', false).find('i').attr('class', 'fa-solid fa-xmark');
                            }
                        });
                    }
                });
            });
        });
        </script>
        <style>
        .vs-btn[data-tooltip] {
            position: relative;
        }

        .vs-btn[data-tooltip]::after {
            content: attr(data-tooltip);
            position: absolute;
            top: -35px;
            left: 50%;
            transform: translateX(-50%);
            background: #1e293b;
            color: white;
            padding: 6px 10px;
            border-radius: 6px;
            font-size: 12px;
            font-weight: 600;
            white-space: nowrap;
            opacity: 0;
            visibility: hidden;
            transition: opacity 0.2s ease, visibility 0.2s ease;
            pointer-events: none;
            z-index: 1000;
            box-shadow: 0 2px 8px rgba(0,0,0,0.15);
        }

        .vs-btn[data-tooltip]::before {
            content: "";
            position: absolute;
            top: -7px;
            left: 50%;
            transform: translateX(-50%);
            width: 0;
            height: 0;
            border-left: 5px solid transparent;
            border-right: 5px solid transparent;
            border-top: 5px solid #1e293b;
            opacity: 0;
            visibility: hidden;
            transition: opacity 0.2s ease, visibility 0.2s ease;
            pointer-events: none;
            z-index: 1000;
        }

        .vs-btn[data-tooltip]:hover::after,
        .vs-btn[data-tooltip]:hover::before {
            opacity: 1;
            visibility: visible;
        }
        </style>
        <?php
        return ob_get_clean();
    }

    public static function vendor_approve_product_ajax() {
        check_ajax_referer('vs_vendor_moderation_nonce', 'security');
        
        $product_id = intval($_POST['product_id'] ?? 0);
        $user_id = get_current_user_id();
        
        $product = get_post($product_id);
        if (!$product || $product->post_author != $user_id || $product->post_status !== 'pending_vendor') {
            wp_send_json_error(__('Permission denied or invalid product.', 'vendor-space'));
        }

        $result = wp_update_post([
            'ID' => $product_id,
            'post_status' => 'publish'
        ]);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success([ 'message' => __('Product published successfully', 'vendor-space'), 'pending_count' => self::get_vendor_pending_count($user_id) ]);
    }

    public static function vendor_reject_product_ajax() {
        check_ajax_referer('vs_vendor_moderation_nonce', 'security');
        
        $product_id = intval($_POST['product_id'] ?? 0);
        $user_id = get_current_user_id();
        
        $product = get_post($product_id);
        if (!$product || $product->post_author != $user_id || $product->post_status !== 'pending_vendor') {
            wp_send_json_error(__('Permission denied or invalid product.', 'vendor-space'));
        }

        $result = wp_update_post([
            'ID' => $product_id,
            'post_status' => 'draft'
        ]);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success([ 'message' => __('Product rejected and saved as draft.', 'vendor-space'), 'pending_count' => self::get_vendor_pending_count($user_id) ]);
    }

    public static function ajax_get_pending_counts() {
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Permission denied');
        }
        $pending = self::get_pending_count();
        $pending_cat = class_exists('VS_Categories') ? VS_Categories::get_pending_count() : 0;
        $pending_vendors = self::get_pending_vendors_count();
        wp_send_json_success([ 'pending' => (int) $pending, 'pending_cat' => (int) $pending_cat, 'pending_vendors' => (int) $pending_vendors ]);
    }

    public static function ajax_refresh_publish_requests_rows() {
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Permission denied');
        }
        $rows = self::render_front_requests_rows();
        $pending = self::get_pending_count();
        wp_send_json_success([ 'html' => $rows, 'pending_count' => (int) $pending ]);
    }

    public static function render_vendor_requests_tab() {
        $user_id = get_current_user_id();
        $pending_count = self::get_vendor_pending_count($user_id);
        $args = [
            'post_type'   => 'product',
            'post_status' => 'pending_vendor',
            'author'      => $user_id,
            'numberposts' => -1,
        ];
        $pending_products = get_posts($args);

        ob_start();
        ?>
        <div id="tab-vendor-assign-requests" class="vs-tab" style="display:none;">
            <div class="vs-dashboard-header" style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; border-bottom: 2px solid #2563eb; padding-bottom: 10px;">
                <h2 style="margin:0; font-size:24px; color:#1e293b;">Assign Requests (<span id="vs-vendor-assign-count"><?php echo $pending_count; ?></span>)</h2>
            </div>
            
            <p style="margin-bottom: 20px; color: #64748b;"><?php echo esc_html__('The following products were assigned to you by the administrator. Please review and approve them to be published in your store.', 'vendor-space'); ?></p>

            <div class="vs-moderation-container">
                <table class="vs-products-table">
                    <thead>
                        <tr>
                            <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Image</th>
                            <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Product Name</th>
                            <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Price</th>
                            <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;">Assign Date</th>
                            <th style="padding: 15px 20px; font-weight: 600; color: #475569;background-color: #f8fafc;" width="200">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php if (empty($pending_products)): ?>
                        <tr>
                            <td colspan="5">
                                <div class="vs-empty-state">
                                    <div class="vs-empty-icon"><i class="fa-regular fa-folder-open"></i></div>
                                    <div class="vs-empty-title"><?php echo esc_html__('No pending requests', 'vendor-space'); ?></div>
                                    <div class="vs-empty-sub"><?php echo esc_html__('You have handled all assigned products.', 'vendor-space'); ?></div>
                                </div>
                            </td>
                        </tr>
                        <?php else: ?>
                            <?php foreach ($pending_products as $p): 
                                $price = get_post_meta($p->ID, '_price', true);
                                $img = get_the_post_thumbnail($p->ID, [50, 50]) ?: '<span class="dashicons dashicons-format-image" style="font-size:40px; color:#ccc;"></span>';
                            ?>
                            <tr id="vs-vendor-req-row-<?php echo $p->ID; ?>">
                                <td><?php echo $img; ?></td>
                                <td><strong><?php echo esc_html($p->post_title); ?></strong></td>
                                <td><?php echo wc_price($price); ?></td>
                                <td><?php echo get_the_date('M j, Y', $p->ID); ?></td>
                                <td>
                                    <button class="vs-btn vs-vendor-approve-btn" data-id="<?php echo $p->ID; ?>" style="background:#10b981; color:#fff; border:none; padding:6px 12px; border-radius:6px; font-size:14px; margin-right:5px; cursor:pointer;" title="<?php echo esc_attr__('Approve & Publish', 'vendor-space'); ?>">
                                        <i class="fa-solid fa-check"></i> <?php echo esc_html__('Approve', 'vendor-space'); ?>
                                    </button>
                                    <button class="vs-btn vs-vendor-reject-btn" data-id="<?php echo $p->ID; ?>" style="background:#ef4444; color:#fff; border:none; padding:6px 12px; border-radius:6px; font-size:14px; cursor:pointer;" title="<?php echo esc_attr__('Reject & Save as Draft', 'vendor-space'); ?>">
                                        <i class="fa-solid fa-xmark"></i> <?php echo esc_html__('Reject', 'vendor-space'); ?>
                                    </button>
                                </td>
                            </tr>
                            <?php endforeach; ?>
                        <?php endif; ?>
                    </tbody>
                </table>
            </div>
        </div>

        <script>
        jQuery(document).ready(function($) {
            $(document).on('click', '.vs-vendor-approve-btn', function() {
                const btn = $(this);
                const pid = btn.data('id');
                
                Swal.fire({
                    title: '<?php echo esc_js(__('Approve and publish this product?', 'vendor-space')); ?>',
                    text: '<?php echo esc_js(__('It will be visible in your store immediately.', 'vendor-space')); ?>',
                    icon: 'question',
                    showCancelButton: true,
                    confirmButtonText: '<?php echo esc_js(__('Yes, Publish', 'vendor-space')); ?>',
                    confirmButtonColor: '#10b981'
                }).then((result) => {
                    if (result.isConfirmed) {
                        btn.prop('disabled', true).text('...');
                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_vendor_approve_product',
                            product_id: pid,
                            security: '<?php echo wp_create_nonce("vs_vendor_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                $('#vs-vendor-req-row-' + pid).fadeOut();
                                updateVendorBadge(res.data.pending_count);
                                Swal.fire('<?php echo esc_js(__('Published!', 'vendor-space')); ?>', res.data.message, 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed to approve', 'error');
                                btn.prop('disabled', false).text('Approve');
                            }
                        });
                    }
                });
            });

            $(document).on('click', '.vs-vendor-reject-btn', function() {
                const btn = $(this);
                const pid = btn.data('id');
                
                Swal.fire({
                    title: '<?php echo esc_js(__('Reject this product?', 'vendor-space')); ?>',
                    text: '<?php echo esc_js(__('It will be removed from requests and saved as a draft.', 'vendor-space')); ?>',
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonText: '<?php echo esc_js(__('Yes, Reject', 'vendor-space')); ?>',
                    confirmButtonColor: '#ef4444'
                }).then((result) => {
                    if (result.isConfirmed) {
                        btn.prop('disabled', true).text('...');
                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_vendor_reject_product',
                            product_id: pid,
                            security: '<?php echo wp_create_nonce("vs_vendor_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                $('#vs-vendor-req-row-' + pid).fadeOut();
                                updateVendorBadge(res.data.pending_count);
                                Swal.fire('<?php echo esc_js(__('Rejected!', 'vendor-space')); ?>', res.data.message, 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed to reject', 'error');
                                btn.prop('disabled', false).text('Reject');
                            }
                        });
                    }
                });
            });

            function updateVendorBadge(count) {
                const n = parseInt(count);
                const $badge = $('#vs-vendor-assign-requests-badge');
                if ($badge.length) {
                    if (n > 0) { $badge.text(n).show(); } else { $badge.hide(); }
                }
                const $titleCount = $('#vs-vendor-assign-count');
                if ($titleCount.length) { $titleCount.text(n); }
            }
        });
        </script>
        <?php
        return ob_get_clean();
    }

    /**
     * AJAX: Approve Vendor Account
     */
    public static function approve_vendor_ajax() {
        check_ajax_referer('vs_moderation_nonce', 'security');
        if (!current_user_can('manage_options')) wp_send_json_error(__('Permission denied.', 'vendor-space'));

        $user_id = intval($_POST['user_id'] ?? 0);
        if (!$user_id) wp_send_json_error(__('Invalid user ID.', 'vendor-space'));

        $user = new WP_User($user_id);
        $user->set_role('vendor');
        update_user_meta($user_id, 'vs_vendor_status', 'active');

        // Send Email
        $site_name = get_bloginfo('name');
        $subject = sprintf(__('[%s] Your Vendor Account has been Approved!', 'vendor-space'), $site_name);
        $message = sprintf(
            __("<h3>Congratulations %s!</h3><p>Your application to become a vendor on <strong>%s</strong> has been approved.</p><p>You can now access your dashboard and start uploading products.</p><p><a href='%s' style='background:#2563eb; color:#fff; padding:10px 20px; text-decoration:none; border-radius:5px; display:inline-block;'>Access Vendor Dashboard</a></p><p>Regards,<br>Team %s</p>", 'vendor-space'),
            esc_html($user->display_name),
            esc_html($site_name),
            site_url('/vendor-dashboard'),
            esc_html($site_name)
        );
        $headers = ['Content-Type: text/html; charset=UTF-8'];
        wp_mail($user->user_email, $subject, $message, $headers);

        wp_send_json_success([
            'message' => __('Vendor approved and notified.', 'vendor-space'),
            'pending_count' => self::get_pending_vendors_count()
        ]);
    }

    /**
     * AJAX: Reject Vendor Account
     */
    public static function reject_vendor_ajax() {
        check_ajax_referer('vs_moderation_nonce', 'security');
        if (!current_user_can('manage_options')) wp_send_json_error(__('Permission denied.', 'vendor-space'));

        $user_id = intval($_POST['user_id'] ?? 0);
        if (!$user_id) wp_send_json_error(__('Invalid user ID.', 'vendor-space'));

        $reason = sanitize_text_field($_POST['reason'] ?? __('Application does not meet our criteria.', 'vendor-space'));
        
        update_user_meta($user_id, 'vs_vendor_status', 'rejected');
        update_user_meta($user_id, 'vs_rejection_reason', $reason);
        // We no longer reset 'vs_vendor_onboarded' here, 
        // as the vendor needs to see the rejection screen first.
        // They can reset it themselves via the 'Apply Again' button.
        
        $user = get_userdata($user_id);
        
        // Send Email
        $site_name = get_bloginfo('name');
        $subject = sprintf(__('[%s] Vendor Application Update', 'vendor-space'), $site_name);
        $message = sprintf(
            __("<h3>Hello %s,</h3><p>We have reviewed your vendor application on <strong>%s</strong>.</p><p>Unfortunately, your application was not approved for the following reason:</p><blockquote style='background:#f9f9f9; padding:15px; border-left:5px solid #ef4444;'>%s</blockquote><p>If you have any questions, please contact our support team.</p><p>Regards,<br>Team %s</p>", 'vendor-space'),
            esc_html($user->display_name),
            esc_html($site_name),
            nl2br(esc_html($reason)),
            esc_html($site_name)
        );
        $headers = ['Content-Type: text/html; charset=UTF-8'];
        wp_mail($user->user_email, $subject, $message, $headers);

        wp_send_json_success([
            'message' => __('Vendor rejected and notified.', 'vendor-space'),
            'pending_count' => self::get_pending_vendors_count()
        ]);
    }

    /**
     * UI: Render Vendor Applications Tab
     */
    public static function render_front_vendor_requests_tab() {
        if (!current_user_can('manage_options')) return '';

        $args = [
            'role__in'   => ['customer'],
            'meta_key'   => 'vs_vendor_status',
            'meta_value' => 'pending',
        ];
        $pending_vendors = get_users($args);
        $count = count($pending_vendors);

        ob_start();
        ?>
        <div id="tab-vendor-requests" class="vs-tab" style="display:none;">

            <style>
            /* ── Account Requests — Header ── */
            #tab-vendor-requests .vs-req-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: 20px;
                border-bottom: 2px solid #f59e0b;
                padding-bottom: 10px;
            }
            #tab-vendor-requests .vs-req-header h2 {
                margin: 0;
                font-size: 22px;
                color: #1e293b;
            }

            /* ── Desktop: normal table ── */
            .vs-req-table-wrap {
                background: #fff;
                border-radius: 14px;
                overflow: hidden;
                box-shadow: 0 2px 8px rgba(0,0,0,0.06);
            }
            .vs-req-table {
                width: 100%;
                border-collapse: collapse;
                font-size: 14px;
            }
            .vs-req-table th {
                padding: 13px 16px;
                font-weight: 600;
                color: #475569;
                background: #fffbeb;
                text-align: left;
                white-space: nowrap;
            }
            .vs-req-table td {
                padding: 13px 16px;
                border-top: 1px solid #f1f5f9;
                vertical-align: middle;
            }
            .vs-req-table tr:hover td {
                background: #fafafa;
            }
            .vs-req-store { font-weight: 700; color: #1e293b; }
            .vs-req-email { font-size: 12px; color: #64748b; }
            .vs-req-btn-approve {
                background: #10b981; color: #fff; border: none;
                padding: 7px 14px; border-radius: 8px; cursor: pointer;
                font-size: 13px; font-weight: 600; margin-right: 6px;
            }
            .vs-req-btn-reject {
                background: #ef4444; color: #fff; border: none;
                padding: 7px 14px; border-radius: 8px; cursor: pointer;
                font-size: 13px; font-weight: 600;
            }
            .vs-req-btn-approve:hover { background: #059669; }
            .vs-req-btn-reject:hover  { background: #dc2626; }

            /* ── Mobile: card layout ── */
            .vs-req-cards { display: none; }

            @media (max-width: 768px) {
                /* Hide table, show cards */
                .vs-req-table-wrap { display: none !important; }
                .vs-req-cards      { display: flex; flex-direction: column; gap: 12px; }

                #tab-vendor-requests .vs-req-header h2 { font-size: 17px; }

                /* Each application = a card */
                .vs-req-card {
                    background: #fff;
                    border: 1px solid #e2e8f0;
                    border-radius: 16px;
                    padding: 16px;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.05);
                }

                /* Top row: avatar initial + name/email */
                .vs-req-card-top {
                    display: flex;
                    align-items: center;
                    gap: 12px;
                    margin-bottom: 12px;
                }
                .vs-req-avatar {
                    width: 44px; height: 44px;
                    border-radius: 50%;
                    background: #ede9fe;
                    color: #7c3aed;
                    font-weight: 800; font-size: 16px;
                    display: flex; align-items: center; justify-content: center;
                    flex-shrink: 0;
                }
                .vs-req-name  { font-weight: 700; font-size: 15px; color: #1e293b; }
                .vs-req-email { font-size: 12px; color: #64748b; margin-top: 2px; }

                /* Info rows */
                .vs-req-card-info {
                    display: grid;
                    grid-template-columns: 1fr 1fr;
                    gap: 8px;
                    margin-bottom: 14px;
                }
                .vs-req-info-item {
                    background: #f8fafc;
                    border-radius: 10px;
                    padding: 8px 10px;
                }
                .vs-req-info-label {
                    font-size: 10px; font-weight: 700;
                    text-transform: uppercase; letter-spacing: .05em;
                    color: #94a3b8; margin-bottom: 3px;
                }
                .vs-req-info-value {
                    font-size: 13px; font-weight: 600; color: #1e293b;
                }

                /* Action buttons: full width, side by side */
                .vs-req-card-actions {
                    display: grid;
                    grid-template-columns: 1fr 1fr;
                    gap: 8px;
                }
                .vs-req-card-actions .vs-req-btn-approve,
                .vs-req-card-actions .vs-req-btn-reject {
                    width: 100%; margin: 0;
                    padding: 11px 0;
                    font-size: 14px; font-weight: 700;
                    border-radius: 10px;
                    text-align: center;
                    min-height: 44px;
                }
            }
            </style>

            <div class="vs-req-header">
                <h2>Vendor Applications (<span id="vs-vendor-requests-count"><?php echo $count; ?></span>)</h2>
            </div>

            <?php if (empty($pending_vendors)): ?>
                <div class="vs-empty-state">
                    <div class="vs-empty-icon"><i class="fa-solid fa-user-clock"></i></div>
                    <div class="vs-empty-title">No pending applications</div>
                    <div class="vs-empty-sub">All clear!</div>
                </div>
            <?php else: ?>

            <!-- ── DESKTOP TABLE ── -->
            <div class="vs-req-table-wrap">
                <table class="vs-req-table">
                    <thead>
                        <tr>
                            <th>Store Name</th>
                            <th>Applicant</th>
                            <th>Location</th>
                            <th>Phone</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($pending_vendors as $v):
                            $store_name = get_user_meta($v->ID, 'vs_store_name', true) ?: $v->display_name;
                            $location   = get_user_meta($v->ID, 'vs_store_location', true) ?: '-';
                            $phone      = get_user_meta($v->ID, 'vs_store_phone', true) ?: '-';
                        ?>
                        <tr id="vs-vendor-row-<?php echo $v->ID; ?>">
                            <td><span class="vs-req-store"><?php echo esc_html($store_name); ?></span></td>
                            <td>
                                <?php echo esc_html($v->display_name); ?>
                                <br><span class="vs-req-email"><?php echo esc_html($v->user_email); ?></span>
                            </td>
                            <td><?php echo esc_html($location); ?></td>
                            <td><?php echo esc_html($phone); ?></td>
                            <td>
                                <button class="vs-req-btn-approve vs-admin-approve-vendor-btn" data-id="<?php echo $v->ID; ?>">Approve</button>
                                <button class="vs-req-btn-reject  vs-admin-reject-vendor-btn"  data-id="<?php echo $v->ID; ?>">Reject</button>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>

            <!-- ── MOBILE CARDS ── -->
            <div class="vs-req-cards">
                <?php foreach ($pending_vendors as $v):
                    $store_name = get_user_meta($v->ID, 'vs_store_name', true) ?: $v->display_name;
                    $location   = get_user_meta($v->ID, 'vs_store_location', true) ?: '-';
                    $phone      = get_user_meta($v->ID, 'vs_store_phone', true) ?: '-';
                    $initial    = strtoupper(mb_substr($v->display_name, 0, 1));
                ?>
                <div class="vs-req-card" id="vs-vendor-row-<?php echo $v->ID; ?>">
                    <div class="vs-req-card-top">
                        <div class="vs-req-avatar"><?php echo esc_html($initial); ?></div>
                        <div>
                            <div class="vs-req-name"><?php echo esc_html($v->display_name); ?></div>
                            <div class="vs-req-email"><?php echo esc_html($v->user_email); ?></div>
                        </div>
                    </div>
                    <div class="vs-req-card-info">
                        <div class="vs-req-info-item">
                            <div class="vs-req-info-label">Store</div>
                            <div class="vs-req-info-value"><?php echo esc_html($store_name); ?></div>
                        </div>
                        <div class="vs-req-info-item">
                            <div class="vs-req-info-label">Location</div>
                            <div class="vs-req-info-value"><?php echo esc_html($location); ?></div>
                        </div>
                        <div class="vs-req-info-item" style="grid-column:1/-1;">
                            <div class="vs-req-info-label">Phone</div>
                            <div class="vs-req-info-value"><?php echo esc_html($phone); ?></div>
                        </div>
                    </div>
                    <div class="vs-req-card-actions">
                        <button class="vs-req-btn-approve vs-admin-approve-vendor-btn" data-id="<?php echo $v->ID; ?>">✓ Approve</button>
                        <button class="vs-req-btn-reject  vs-admin-reject-vendor-btn"  data-id="<?php echo $v->ID; ?>">✕ Reject</button>
                    </div>
                </div>
                <?php endforeach; ?>
            </div>

            <?php endif; ?>
        </div>

        <script>
        jQuery(document).ready(function($) {
            $(document).on('click', '.vs-admin-approve-vendor-btn', function() {
                const btn = $(this);
                const uid = btn.data('id');
                
                Swal.fire({
                    title: 'Approve this vendor?',
                    text: 'They will be granted the vendor role and notified via email.',
                    icon: 'question',
                    showCancelButton: true,
                    confirmButtonText: 'Yes, Approve',
                    confirmButtonColor: '#10b981'
                }).then((result) => {
                    if (result.isConfirmed) {
                        btn.prop('disabled', true).text('...');
                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_approve_vendor',
                            user_id: uid,
                            security: '<?php echo wp_create_nonce("vs_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                $('#vs-vendor-row-' + uid).fadeOut();
                                $('#vs-vendor-requests-count-tab').text(res.data.pending_count);
                                $('#vs-vendor-requests-badge').text(res.data.pending_count); // Sidebar badge
                                if (res.data.pending_count <= 0) {
                                    $('#vs-vendor-requests-badge').hide();
                                    $('#vs-users-badge').hide();
                                }
                                Swal.fire('Approved!', res.data.message, 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed', 'error');
                                btn.prop('disabled', false).text('Approve');
                            }
                        });
                    }
                });
            });

            $(document).on('click', '.vs-admin-reject-vendor-btn', function() {
                const btn = $(this);
                const uid = btn.data('id');
                
                Swal.fire({
                    title: 'Reject this application?',
                    input: 'textarea',
                    inputLabel: 'Reason for rejection',
                    inputPlaceholder: 'Explain why...',
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonText: 'Yes, Reject',
                    confirmButtonColor: '#ef4444'
                }).then((result) => {
                    if (result.isConfirmed) {
                        const reason = result.value || 'Application does not meet our guidelines.';
                        btn.prop('disabled', true).text('...');
                        $.post(vs_vars.ajaxurl, {
                            action: 'vs_reject_vendor',
                            user_id: uid,
                            reason: reason,
                            security: '<?php echo wp_create_nonce("vs_moderation_nonce"); ?>'
                        }, function(res) {
                            if (res.success) {
                                $('#vs-vendor-row-' + uid).fadeOut();
                                $('#vs-vendor-requests-count-tab').text(res.data.pending_count);
                                $('#vs-vendor-requests-badge').text(res.data.pending_count); // Sidebar badge
                                if (res.data.pending_count <= 0) {
                                    $('#vs-vendor-requests-badge').hide();
                                    $('#vs-users-badge').hide();
                                }
                                Swal.fire('Rejected!', res.data.message, 'success');
                            } else {
                                Swal.fire('Error', res.data || 'Failed', 'error');
                                btn.prop('disabled', false).text('Reject');
                            }
                        });
                    }
                });
            });
        });
        </script>
        <?php
        return ob_get_clean();
    }
}