<?php
/**
 * Image Boost — Auto Optimizer
 * Automatically queues images for background compression upon upload.
 */

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

class ImgBoost_Auto_Optimizer {

    /**
     * Initialize auto-optimization hooks.
     */
    public static function init() {
        add_filter('wp_generate_attachment_metadata', [__CLASS__, 'queue_optimization_on_upload'], 10, 2);
    }

    /**
     * Called after WordPress generates attachment metadata (thumbnails, etc.).
     *
     * @param array $metadata
     * @param int   $attachment_id
     * @return array
     */
    public static function queue_optimization_on_upload($metadata, $attachment_id) {
        $mime = get_post_mime_type($attachment_id);
        $supported = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

        if (!in_array($mime, $supported)) {
            return $metadata;
        }

        $file_path = imgboost_get_attachment_path($attachment_id);

        if (!$file_path || !file_exists($file_path)) {
            return $metadata;
        }

        // Set pending status — image will be processed in background
        update_post_meta($attachment_id, '_imgboost_status', 'pending');
        
        // Add to lightweight queue using postmeta to prevent parallel write race conditions
        update_post_meta($attachment_id, '_imgboost_pending_queue', '1');

        // Fire a one-shot cron event in ~10 seconds to process ASAP without blocking
        if (!wp_next_scheduled('imgboost_process_queue')) {
            wp_schedule_single_event(time() + 10, 'imgboost_process_queue');
        }

        return $metadata;
    }

    /**
     * Set up recurring cron task for processing the queue.
     */
    public static function setup_cron() {
        if (!wp_next_scheduled('imgboost_process_queue')) {
            wp_schedule_event(time(), 'imgboost_five_minutes', 'imgboost_process_queue');
        }
    }

    /**
     * Process images from the queue (called by WP-Cron in background).
     */
    public static function process_queue() {
        // Transient lock to prevent overlapping crons
        if (get_transient('imgboost_auto_queue_lock')) {
            return;
        }
        set_transient('imgboost_auto_queue_lock', 1, 120);

        global $wpdb;

        // Fetch 2 items from the queue per cycle (lightweight on CPU)
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $batch = $wpdb->get_col("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_imgboost_pending_queue' AND meta_value = '1' ORDER BY post_id ASC LIMIT 2");
        
        if (empty($batch)) {
            delete_transient('imgboost_auto_queue_lock');
            return;
        }

        foreach ($batch as $attachment_id) {
            // Remove from queue immediately to prevent infinite loops on error
            delete_post_meta($attachment_id, '_imgboost_pending_queue');

            // Use full process_attachment which handles Full + ALL thumbnails + WebP
            if (class_exists('ImgBoost_Background_Process')) {
                ImgBoost_Background_Process::process_attachment($attachment_id);
            }
        }

        delete_transient('imgboost_auto_queue_lock');

        // Check if more items exist
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $remaining = (int) $wpdb->get_var("SELECT COUNT(meta_id) FROM {$wpdb->postmeta} WHERE meta_key = '_imgboost_pending_queue' AND meta_value = '1'");

        // If there are still items in queue, schedule another run rapidly
        if ($remaining > 0 && !wp_next_scheduled('imgboost_process_queue')) {
            wp_schedule_single_event(time() + 10, 'imgboost_process_queue');
        }
    }
}
