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

/**
 * Add custom cron schedule (every minute)
 */
add_filter('cron_schedules', function ($schedules) {
    $schedules['every_minute'] = [
        'interval' => 60,
        'display'  => 'Every Minute',
    ];
    return $schedules;
});

/**
 * Schedule auction end cron
 */
add_action('init', function () {
    if (!wp_next_scheduled('stakmv_auction_end_cron')) {
        wp_schedule_event(time(), 'every_minute', 'stakmv_auction_end_cron');
    }
});

/**
 * Process ended auctions
 */
add_action('stakmv_auction_end_cron', function () {
    if (function_exists('stakmv_auctions_enabled') && !stakmv_auctions_enabled()) {
        return;
    }

    global $wpdb;

    // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Auction closing cron needs end-time/status meta constraints.
    $auctions = get_posts([
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'meta_query'     => [
            [
                'key'   => '_stakmv_auction_status',
                'value' => 'active',
            ],
            [
                'key'     => '_stakmv_auction_end_time',
                'compare' => 'EXISTS',
            ],
        ],
        'fields' => 'ids',
    ]);
    // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_query

    if (!$auctions) return;

    foreach ($auctions as $auction_id) {

        $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);
        if (!$end_time || time() < $end_time) {
            continue;
        }

        // Auction ended
        update_post_meta($auction_id, '_stakmv_auction_status', 'ended');

        // Get highest bid
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Single-row lookup for cron auction settlement.
        $highest = $wpdb->get_row(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Dynamic table name uses current site prefix.
            $wpdb->prepare(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Dynamic table name uses current site prefix.
                "SELECT * FROM {$wpdb->prefix}stakmv_auction_bids\n                 WHERE auction_id = %d\n                 ORDER BY bid_amount DESC, created_at ASC\n                 LIMIT 1",
                $auction_id
            )
        );

        if (!$highest) {
            // No bids → auction simply ends
            continue;
        }

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

        // Create order for winner
        $order = wc_create_order([
            'customer_id' => $highest->user_id,
        ]);

        $order->add_product($product, 1, [
            'subtotal' => $highest->bid_amount,
            'total'    => $highest->bid_amount,
        ]);

        $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,
            ]);
        }

        $payment_timeout_hours = function_exists('stakmv_auction_payment_timeout_hours')
            ? stakmv_auction_payment_timeout_hours($auction_id)
            : 48;
        $payment_timeout_hours = max(1, (int) $payment_timeout_hours);

        $order->update_meta_data('_stakmv_auction_id', $auction_id);
        $order->update_meta_data('_stakmv_auction_winner', $highest->user_id);
        $order->set_status('pending', 'Auction ended – awaiting winner payment');
        $order->update_meta_data('_stakmv_auction_payment_deadline', time() + ($payment_timeout_hours * HOUR_IN_SECONDS));

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

        // Mark auction awaiting payment
        update_post_meta($auction_id, '_stakmv_auction_status', 'pending_payment');
    }
});
