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

    class cloudS3StorageObserver {

        private static $url_cache = array();

        public function __construct($connect = false) {

            if($connect) {
                add_action('wp_ajax_modifica_url_immagine', array($this, 'ajax_modifica_url_immagine'));
                add_filter('wp_get_attachment_url', array($this, 'cloudS3Storage_image_url_filter'));
                add_filter('the_content', array($this, 'cloudS3Storage_content_filter')); 
                add_action('wp_head', array($this, 'start_output_buffer'), 1);
                add_action('wp_footer', array($this, 'end_output_buffer'), 999);
            }
            
            $this->observer();
        }

        public function cloudS3Storage_image_url_filter($url) {
            $from_img = $url;
            $to_img = cloudS3StorageObserver::replace_url($from_img);
            $upload_dir = wp_upload_dir();
            $from_img_full = $upload_dir['baseurl'] . $from_img;
            return $to_img;
        }

        public function cloudS3Storage_content_filter($content) {
            $content = preg_replace_callback('/<img[^>]+src="([^">]+)"/', function ($matches) {
                $url = $matches[1];
                $new_url = cloudS3StorageObserver::replace_url($url);
                return str_replace($url, $new_url, $matches[0]);
            }, $content);
        
            return $content;
        }

        public function start_output_buffer() {
            ob_start(array($this, 'modify_output'));
            ob_start(array($this, 'modify_meta_output')); 
        }
        
        public function end_output_buffer() {
            ob_end_flush();
        }
        
        public function modify_output($content) {
            // Modifica i tag <img>
            $content = preg_replace_callback('/<img([^>]+)>/', function ($matches) {
                $img_tag = $matches[0];
        
                $img_tag = preg_replace_callback('/(\bsrc\b|\bsrcset\b|\bdata-retina_logo_url\b)="([^"]*)"/', function ($attr_matches) {
                    $attribute = $attr_matches[1];
                    $urls = explode(' ', $attr_matches[2]); 
        
                    $urls = array_map(function ($url) {
                        return cloudS3StorageObserver::replace_url($url);
                    }, $urls);
        
                    $new_value = implode(' ', $urls);
                    return $attribute . '="' . $new_value . '"';
                }, $img_tag);
        
                return $img_tag;
            }, $content);
        
            // Modifica i tag <a href="">
            $content = preg_replace_callback('/<a[^>]+href="([^"]+)"/', function ($matches) {
                $href_url = $matches[1];
                
                // Verifica se l'href punta a un media, controllando l'estensione o il mime type
                if (preg_match('/\.(jpg|jpeg|png|gif|svg|pdf|mp4|webm|avi)$/i', $href_url)) {
                    $new_href_url = cloudS3StorageObserver::replace_url($href_url);
                    return str_replace($href_url, $new_href_url, $matches[0]);
                }
        
                return $matches[0]; // Nessuna sostituzione se non è un media
            }, $content);
        
            return $content;
        }           

        public function modify_meta_output($content) {
        
            $content = preg_replace_callback('/<meta[^>]+content="([^"]+)"[^>]*>/', function ($matches) {
                $meta_tag = $matches[0];
                $url = $matches[1];
                
                if (filter_var($url, FILTER_VALIDATE_URL)) {
                    $new_url = cloudS3StorageObserver::replace_url($url);
                    return str_replace($url, $new_url, $meta_tag);
                }
        
                return $meta_tag;
            }, $content);
        
            return $content;
        }
                     
        public function observer() {

            add_filter('attachment_class', array($this, 'class_for_image'), 10, 2);
            add_filter('wp_calculate_image_srcset', array($this, 'custom_image_srcset_and_sizes'), 10, 5);

            add_filter('wp_prepare_attachment_for_js', array($this, 'modify_attachment_urls'), 10, 3);
        }

        public function modify_attachment_urls($response, $attachment, $meta) {
            $response['url'] = $this->replace_image_url($response['url']);

            foreach ($response['sizes'] as $size => $image) {
                $response['sizes'][$size]['url'] = $this->replace_image_url($image['url']);
            }  
            return $response;
        }

        public function custom_image_srcset_and_sizes($sources, $size_array, $image_src, $image_meta, $attachment_id) {
            foreach ($sources as $k => $image) {
                $sources[$k]['url'] = $this->replace_image_url($image['url']);
            }
        
            return $sources;
        }      

        public function replace_image_url($original_src) {
            $upload_dir = wp_upload_dir();
            $upload_base_url = $upload_dir['baseurl'];
            $relative_image_url = str_replace($upload_base_url, '', $original_src);
            return cloudS3Class::get_single_path($relative_image_url) ?? $original_src;
        }

        static function replace_url($original_src) {
            $original_src = rawurldecode($original_src);
        
            if (isset(self::$url_cache[$original_src])) {
                return self::$url_cache[$original_src];
            }
        
            $upload_dir = wp_upload_dir();
            $upload_base_url = $upload_dir['baseurl'];
            $relative_image_url = str_replace($upload_base_url, '', $original_src);
        
            $new_url = cloudS3Class::get_single_path($relative_image_url) ?? $original_src;
        
            $new_url = rawurldecode($new_url);
        
            self::$url_cache[$original_src] = $new_url;
        
            return $new_url;
        }       
        
    }