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

/**
 * PageSpeed Budget — prioritize LCP-critical images (featured + first in content).
 */
class AIIO_LCP_Scanner {

    const TRANSIENT = 'aiio_lcp_scan';

    public static function scan($args = []) {
        @set_time_limit(120); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Extends time limit for long-running bulk/scan jobs.
        $settings = aiio_get_settings();
        $budget_kb = max(50, (int) ($args['budget_kb'] ?? ($settings['lcp_budget_kb'] ?? 200)));
        $budget_bytes = $budget_kb * 1024;

        $candidates = [];
        $post_types = apply_filters('aiio_lcp_post_types', ['post', 'page', 'product']);

        $q = new WP_Query([
            'post_type'      => $post_types,
            'post_status'    => 'publish',
            'posts_per_page' => 150,
            'fields'         => 'ids',
            'no_found_rows'  => true,
        ]);

        foreach ($q->posts as $post_id) {
            $post_id = (int) $post_id;
            $thumb = (int) get_post_thumbnail_id($post_id);
            if ($thumb) {
                self::add_candidate($candidates, $thumb, 'featured', $post_id, 100);
            }
            $first = self::first_content_image_id($post_id);
            if ($first) {
                self::add_candidate($candidates, $first, 'content', $post_id, 80);
            }
        }

        $items = [];
        $over_budget = 0;
        foreach ($candidates as $row) {
            $id = (int) $row['attachment_id'];
            $file = get_attached_file($id);
            if (!$file || !is_file($file)) {
                continue;
            }
            $bytes = filesize($file);
            if ($bytes <= $budget_bytes) {
                continue;
            }
            $over_budget++;
            $items[] = [
                'id'           => $id,
                'bytes'        => $bytes,
                'size_label'   => AIIO_Optimizer::format_bytes($bytes),
                'budget_kb'    => $budget_kb,
                'over_kb'      => (int) round(($bytes - $budget_bytes) / 1024),
                'priority'     => (int) $row['priority'],
                'role'         => $row['role'],
                'post_id'      => (int) $row['post_id'],
                'post_title'   => get_the_title($row['post_id']),
                'post_url'     => get_permalink($row['post_id']),
                'filename'     => basename($file),
                'thumb'        => wp_get_attachment_image_url($id, 'thumbnail'),
                'optimizable'  => AIIO_Optimizer::is_optimizable($id, $reason),
            ];
        }

        usort($items, function ($a, $b) {
            return ((int) $b['priority'] <=> (int) $a['priority']) ?: ((int) $b['bytes'] <=> (int) $a['bytes']);
        });

        $payload = [
            'budget_kb'   => $budget_kb,
            'checked'     => count($candidates),
            'over_budget' => $over_budget,
            'items'       => array_slice($items, 0, 50),
            'time'        => time(),
        ];
        set_transient(self::TRANSIENT, $payload, HOUR_IN_SECONDS);
        return $payload;
    }

    public static function over_budget_attachment_ids() {
        $scan = self::get_last_scan();
        $ids = [];
        foreach ($scan['items'] ?? [] as $item) {
            if (!empty($item['optimizable']) && !empty($item['id'])) {
                $ids[] = (int) $item['id'];
            }
        }
        return array_values(array_unique($ids));
    }

    public static function get_last_scan() {
        $data = get_transient(self::TRANSIENT);
        return is_array($data) ? $data : ['budget_kb' => 200, 'checked' => 0, 'over_budget' => 0, 'items' => [], 'time' => 0];
    }

    private static function add_candidate(&$candidates, $attachment_id, $role, $post_id, $priority) {
        $attachment_id = (int) $attachment_id;
        if (!$attachment_id) {
            return;
        }
        $key = $attachment_id . '_' . $role . '_' . $post_id;
        if (!isset($candidates[$key])) {
            $candidates[$key] = [
                'attachment_id' => $attachment_id,
                'role'          => $role,
                'post_id'       => (int) $post_id,
                'priority'      => (int) $priority,
            ];
        }
    }

    private static function first_content_image_id($post_id) {
        $post = get_post($post_id);
        if (!$post) {
            return 0;
        }
        $html = $post->post_content;
        if (preg_match('/wp-image-(\d+)/', $html, $m)) {
            return (int) $m[1];
        }
        if (preg_match('/class="[^"]*size-/', $html) && preg_match('/<img[^>]+src=["\']([^"\']+)["\']/', $html, $m)) {
            return (int) attachment_url_to_postid($m[1]);
        }
        return 0;
    }
}
