<?php
namespace NeoMotionBeta\NeoGlobal; if (!defined("ABSPATH")) { die("neoWP direct access not allowed"); }




// WordPress Hook to apply deterministic, file-based cache-busting so browsers only invalidate cached images when the underlying media file has actually changed.


\NeoMotionBeta\NeoGlobal\val("neo_global__frontend_image_hook_callbacks", []);
function frontend_image_hook_register_callback($callback) {
    \NeoMotionBeta\NeoGlobal\val("neo_global__frontend_image_hook_callbacks")[] = $callback;
}



function frontend_image_hook_filter_html($html) {
    if ($html === "") { return $html; }

    
    $process_image = function ($img_attributes) {
        
        static $cache = []; $cache_hash = md5(serialize($img_attributes)); if (isset($cache[$cache_hash])) { return $cache[$cache_hash]; }
        
        $set_changes = [];
        $get_attr = function ($key) use (&$img_attributes) { return $img_attributes[$key] ?? null; };
        $set_attr = function ($key, $value) use (&$img_attributes, &$set_changes) { $set_changes[$key] = $value; if ($value === null) { unset($img_attributes[$key]); return; } else { $img_attributes[$key] = $value; } };
        
        if (!\NeoMotionBeta\NeoGlobal\is_url_internal($get_attr("src"))) { return []; }
        
        $image_file_path = untrailingslashit(ABSPATH) . \NeoMotionBeta\NeoGlobal\get_url_path($get_attr("src"));
        
        if (!\NeoMotionBeta\NeoGlobal\fs_file_exists($image_file_path)) { return []; }
        
        foreach (\NeoMotionBeta\NeoGlobal\val("neo_global__frontend_image_hook_callbacks") as $callback) {
            try {
                $callback($get_attr, $set_attr, $image_file_path);
            } catch (\Throwable $e) { \NeoMotionBeta\NeoGlobal\global_warn_with_module_name("_global-frontend-image-hook", $e->getMessage() . " - Failed to process image: " . $get_attr("src")); }
        }

        $cache[$cache_hash] = $set_changes;
        return $cache[$cache_hash];
    };


    
    $img_url_regex_raw = "https?:\/\/(www\.)?(?:[-a-z0-9@:%._\+~#=]{1,256}\.[a-z0-9()]{1,32}|[-a-z0-9@:%_\+~#=]{1,256})\b([-a-z0-9()@:%_\+.~\/=]*)\.(?:jpg|jpeg|jfif|webp|avif|png|gif|bmp|tif|tiff|heic|heif|svg|ico)(?![a-z0-9\.])(\?[-a-z0-9()@:%_\+.~#&\/=;]*)?(?!&quot;)";
    $split_css_url_match = function ($img_url) { $open_parentheses = 0; for ($i = 0; $i < strlen($img_url); $i++) { if ($img_url[$i] === "(") { $open_parentheses++; continue; } if ($img_url[$i] !== ")") { continue; } if ($open_parentheses > 0) { $open_parentheses--; continue; } $suffix = substr($img_url, $i); $img_url = substr($img_url, 0, $i); if (\NeoMotionBeta\NeoGlobal\preg_match_all_better("/[&?](neo-global--processed-[a-z0-9-]+)=([^&#)]*)/i", $suffix, $processed_param_matches, PREG_SET_ORDER)) { foreach ($processed_param_matches as $processed_param_match) { $img_url = \NeoMotionBeta\NeoGlobal\add_query_param($img_url, $processed_param_match[1], urldecode($processed_param_match[2])); } $suffix = \NeoMotionBeta\NeoGlobal\preg_replace_better("/[&?]neo-global--processed-[a-z0-9-]+=[^&#)]*/i", "", $suffix); } return [$img_url, $suffix]; } return [$img_url, ""]; };
    $img_tag_regex_raw = "<img[^>]*" . $img_url_regex_raw . "[^>]*>";
    $img_tag_or_url_regex = "/(?<img_tag>$img_tag_regex_raw)|(?<img_url>$img_url_regex_raw)/i";
    $html = \NeoMotionBeta\NeoGlobal\preg_replace_callback_better($img_tag_or_url_regex, function ($matches) use ($process_image, $img_url_regex_raw, $split_css_url_match) {
        if (!empty($matches["img_tag"])) {
            
            $img_tag = $matches["img_tag"];
            
            if (str_contains($img_tag, "data-neo-global--processed-neo-motion-beta")) { return $img_tag; }
            
            $attr_regex_pattern = '/(?<spacing_before_attr>\s+)(?<key>[a-zA-Z0-9_\-:]+)(?:(?<equals>=)(?:"(?<value1>[^"]*)"|\'(?<value2>[^\']*)\'|(?<value3>[^ \t\r\n"\'>]*)))?/';
            $attributes = [];
            if (\NeoMotionBeta\NeoGlobal\preg_match_all_better($attr_regex_pattern, $img_tag, $matches, PREG_SET_ORDER)) {
                foreach ($matches as $match) {
                    $attr_key   = $match["key"];
                    $attr_value = ($match["value1"] ?? "") ?: ($match["value2"] ?? "") ?: ($match["value3"] ?? "") ?: "";
                    if (isset($attributes[$attr_key])) { \NeoMotionBeta\NeoGlobal\global_warn_with_module_name("_global-frontend-image-hook", "Duplicate attribute in image tag: $attr_key in $img_tag. It was deduplicated."); }
                    $attributes[$attr_key] = $attr_value;
                }
            }


            
            
            $attribute_changes = null;
            $attribute_changes_remembered_for_attribute_key = null;
            $attributes_before = $attributes;
            foreach ($attributes as $attr_key => $attr_value) {
                if ($attr_value === null) { continue; }
                $attributes[$attr_key] = \NeoMotionBeta\NeoGlobal\preg_replace_callback_better("/$img_url_regex_raw/i", function ($match) use (&$attributes_before, &$process_image, &$attr_key, &$attribute_changes, &$attribute_changes_remembered_for_attribute_key, &$split_css_url_match) {
                    
                    [$img_url, $img_url_suffix] = $split_css_url_match($match[0]);
                    $fake_attributes = $attributes_before; $fake_attributes["src"] = $img_url;
                    $set_changes = $process_image($fake_attributes);
                    $result = $set_changes["src"] ?? $fake_attributes["src"];
                    unset($set_changes["src"]);
                    if (($attr_key === "srcset" && !in_array($attribute_changes_remembered_for_attribute_key, ["src", "data-src", "srcset"])) || ($attr_key === "src" && !in_array($attribute_changes_remembered_for_attribute_key, ["data-src"])) || ($attr_key === "data-src" && !in_array($attribute_changes_remembered_for_attribute_key, []))) { $attribute_changes = $set_changes; $attribute_changes_remembered_for_attribute_key = $attr_key; }
                    return $result . $img_url_suffix;
                }, $attr_value);
            }

            foreach ($attribute_changes ?? [] as $attr_key => $attr_value) { if ($attr_value === null) { unset($attributes[$attr_key]); } else { $attributes[$attr_key] = $attr_value; } }
            
            $attributes["data-neo-global--processed-neo-motion-beta"] = "true";

            
            
            $additional_attributes_string = ""; foreach ($attributes as $key => $value) { if (array_key_exists($key, $attributes_before)) { continue; } $additional_attributes_string .= " " . $key . ($value === null ? "" : ('="' . str_replace('"', '&quot;', $value) . '"')); }
            $new_img_tag = \NeoMotionBeta\NeoGlobal\preg_replace_better('/\s*\/?\s*>$/', $additional_attributes_string . "$0", $img_tag);
            
            $new_img_tag = \NeoMotionBeta\NeoGlobal\preg_replace_callback_better($attr_regex_pattern, function ($match) use (&$attributes, &$attribute_changes) {
                $spacing_before_attr = $match["spacing_before_attr"];
                $key = $match["key"];
                if (!array_key_exists($key, $attributes)) { return ""; }
                $value = $attributes[$key];
                $equals = $match["equals"] ?? null;
                if (empty($equals) && $value !== "") { $equals = "="; }
                $quote_type = !empty($match["value1"]) ? '"' : (!empty($match["value2"]) ? "'" : (!empty($match["value3"]) ? "" : null));
                if (empty($quote_type) && $value !== "") $quote_type ??= '"';
                if ($quote_type !== "" && $quote_type !== null && str_contains($value, $quote_type)) { $value = $quote_type === '"' ? str_replace('"', '&quot;', $value) : ($quote_type === "'" ? str_replace("'", '&#39;', $value) : $value); }
                     if ($value === "" && array_key_exists($key, $attribute_changes ?? [])) { return $spacing_before_attr . $key; }
                else if ($value === "") { return $match[0]; }
                return $spacing_before_attr . $key . ($equals ?: "=") . $quote_type . $value . $quote_type;
            }, $new_img_tag);
            
            return $new_img_tag;
        } else {
            
            [$img_url, $img_url_suffix] = $split_css_url_match($matches["img_url"]);
            if (str_contains($img_url, "neo-global--processed-neo-motion-beta=true")) { return $img_url . $img_url_suffix; }
            if (!\NeoMotionBeta\NeoGlobal\is_url_internal($img_url)) { return $img_url . $img_url_suffix; }
            
            $img_url = $process_image(["src" => $img_url])["src"] ?? $img_url;
            
            $img_url = \NeoMotionBeta\NeoGlobal\add_query_param($img_url, "neo-global--processed-neo-motion-beta", "true");
            return $img_url . $img_url_suffix;
        }
    }, $html);
    return $html;
}
\NeoMotionBeta\NeoGlobal\add_filter_hook(
    "the_content",
    "elementor/frontend/the_content",
    "vc_shortcode_output",
    "et_module_process_display_conditions",
    "fl_builder_after_render_shortcodes",
    "bricks/frontend/render_data",
    function ($html) {
        if (!is_string($html)) { return $html; }
        return frontend_image_hook_filter_html($html);
    }
);
