<?php
/**
 * WP Social Buffer Publisher Handler
 *
 * @package MKM_DSPB_Bridge
 * @version 2.0.2
 */

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

if ( ! function_exists( 'mkm_dspb_get_clean_permalink' ) ) {
    /**
     * Get accurate permalink for a post, preserving native post language when Polylang, WPML, TranslatePress, or Weglot is active.
     *
     * @param int|WP_Post $post
     * @return string
     */
    function mkm_dspb_get_clean_permalink( $post ) {
        $post_obj = get_post( $post );
        if ( ! $post_obj ) {
            return '';
        }
        $post_id = $post_obj->ID;

        // 1. Polylang Support
        $switched_polylang = false;
        $old_curlang = null;
        if ( function_exists( 'pll_get_post_language' ) && isset( $GLOBALS['polylang'] ) ) {
            $post_lang = pll_get_post_language( $post_id, 'object' );
            if ( $post_lang && isset( $GLOBALS['polylang']->curlang ) ) {
                $old_curlang = $GLOBALS['polylang']->curlang;
                $GLOBALS['polylang']->curlang = $post_lang;
                $switched_polylang = true;
            }
        }

        // 2. WPML Support
        $wpml_lang = null;
        if ( class_exists( 'SitePress' ) && isset( $GLOBALS['sitepress'] ) && method_exists( $GLOBALS['sitepress'], 'get_language_for_element' ) ) {
            $post_type = get_post_type( $post_id );
            $wpml_lang = $GLOBALS['sitepress']->get_language_for_element( $post_id, 'post_' . $post_type );
        }

        $permalink = get_permalink( $post_id );

        if ( $wpml_lang ) {
            $permalink = apply_filters( 'wpml_permalink', $permalink, $wpml_lang, true );
        }

        // Restore Polylang curlang
        if ( $switched_polylang && isset( $GLOBALS['polylang'] ) ) {
            $GLOBALS['polylang']->curlang = $old_curlang;
        }

        // 3. TranslatePress (TRP) Support
        if ( function_exists( 'trp_get_url_for_language' ) ) {
            if ( function_exists( 'pll_get_post_language' ) ) {
                $lang_slug = pll_get_post_language( $post_id, 'slug' );
                if ( $lang_slug ) {
                    $permalink = trp_get_url_for_language( $permalink, $lang_slug );
                }
            }
        }

        // Only normalize localhost or 127.0.0.1 staging hosts to prevent breaking real language subdomains (e.g. en.domain.com)
        if ( ! empty( $permalink ) ) {
            $perm_parts = wp_parse_url( $permalink );
            if ( ! empty( $perm_parts['host'] ) && ( 'localhost' === strtolower( $perm_parts['host'] ) || '127.0.0.1' === $perm_parts['host'] ) ) {
                $home_url   = home_url();
                $home_parts = wp_parse_url( $home_url );
                if ( ! empty( $home_parts['host'] ) && 'localhost' !== strtolower( $home_parts['host'] ) ) {
                    $permalink = str_replace( $perm_parts['host'], $home_parts['host'], $permalink );
                }
            }
        }

        return $permalink;
    }
}

if ( ! function_exists( 'mkm_dspb_clean_social_text' ) ) {
    /**
     * Clean social media text by decoding HTML entities (e.g. &amp; -> &, &#8217; -> ')
     * so social platforms display plain, unencoded text correctly.
     *
     * @param string $text
     * @return string
     */
    function mkm_dspb_clean_social_text( $text ) {
        if ( empty( $text ) || ! is_string( $text ) ) {
            return $text;
        }

        $cleaned = $text;

        // Decode HTML entities twice to fix potential double-encoded entities (e.g. &amp;amp;)
        $cleaned = htmlspecialchars_decode( $cleaned, ENT_QUOTES );
        $cleaned = html_entity_decode( $cleaned, ENT_QUOTES | ENT_HTML5, 'UTF-8' );

        // Replace any remaining numeric or named HTML entities explicitly
        $search  = array( '&amp;', '&lt;', '&gt;', '&quot;', '&#039;', '&#8217;', '&#8216;', '&#8220;', '&#8221;', '&#8211;', '&#8212;', '&nbsp;' );
        $replace = array( '&',     '<',    '>',    '"',      "'",       "'",       "'",       '"',       '"',       '-',       '--',      ' ' );
        $cleaned = str_replace( $search, $replace, $cleaned );

        return $cleaned;
    }
}

if ( ! function_exists( 'mkm_dspb_html_to_social_text' ) ) {
    /**
     * Convert HTML content (Gutenberg blocks, WooCommerce descriptions, list items, bold text)
     * into clean, readable plain text with bullet points (•) and proper line breaks for social media.
     *
     * @param string $html
     * @return string
     */
    function mkm_dspb_html_to_social_text( $html ) {
        if ( empty( $html ) || ! is_string( $html ) ) {
            return '';
        }

        $text = $html;

        // Remove shortcodes (e.g. [gallery], [elementor-template])
        if ( function_exists( 'strip_shortcodes' ) ) {
            $text = strip_shortcodes( $text );
        }

        // Remove Gutenberg block comments
        $text = preg_replace( '/<!--[\s\S]*?-->/', '', $text );

        // Convert list items <li> into bullet points with newlines
        $text = preg_replace( '/<li[^>]*>\s*/i', "\n• ", $text );
        $text = preg_replace( '/\s*<\/li>/i', '', $text );

        // Convert breaks and block elements to line breaks
        $text = preg_replace( '/<br\s*\/?>/i', "\n", $text );
        $text = preg_replace( '/<\/(p|div|h[1-6]|table|tr|blockquote|section|article)>\s*/i', "\n\n", $text );
        $text = preg_replace( '/<(p|div|h[1-6]|table|tr|blockquote|section|article)[^>]*>/i', '', $text );
        $text = preg_replace( '/<\/(ul|ol)>\s*/i', "\n", $text );
        $text = preg_replace( '/<(ul|ol)[^>]*>/i', '', $text );

        // Strip any remaining HTML tags (like <strong>, <b>, <em>, <a>, <span>, etc.)
        $text = wp_strip_all_tags( $text );

        // Decode HTML entities (e.g. &amp; -> &, &#8217; -> ')
        $text = mkm_dspb_clean_social_text( $text );

        // Normalize line breaks
        $lines = explode( "\n", $text );
        $clean_lines = array();
        foreach ( $lines as $line ) {
            $clean_lines[] = trim( $line );
        }
        $text = implode( "\n", $clean_lines );
        $text = preg_replace( "/\n{3,}/", "\n\n", $text );

        return trim( $text );
    }
}

if ( ! class_exists( 'MKM_DSPB_Publisher' ) ) {
    class MKM_DSPB_Publisher {

    private $api;
    private static $pending_posts = array();

    public function __construct( $api ) {
        $this->api = $api;

        // Auto-publish with deferred execution to allow all meta & terms to save
        add_action( 'transition_post_status', array( $this, 'mark_for_auto_publish' ), 10, 3 );
        add_action( 'save_post', array( $this, 'queue_auto_publish' ), 20, 2 );
        add_action( 'rest_after_insert_post', array( $this, 'process_rest_publish' ), 99, 2 );
        add_action( 'shutdown', array( $this, 'process_deferred_publishes' ) );

        // Metabox for manual sharing
        add_action( 'add_meta_boxes', array( $this, 'add_publishing_metabox' ) );
        add_action( 'save_post', array( $this, 'save_metabox_data' ) );

        // AJAX handler for manual share
        add_action( 'wp_ajax_mkm_dspb_manual_share', array( $this, 'handle_manual_share_ajax' ) );

        // Enqueue assets
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_publisher_assets' ) );
    }

    public function enqueue_publisher_assets( $hook ) {
        if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
            return;
        }

        $post_types = get_option( 'mkm_dspb_post_types', array( 'post' ) );
        $current_post_type = get_post_type();
        if ( ! in_array( $current_post_type, $post_types ) ) {
            return;
        }

        wp_enqueue_style(
            'mkm-dspb-publisher-style',
            MKM_DSPB_URL . 'admin/css/publisher-style.css',
            array(),
            MKM_DSPB_VERSION
        );

        wp_enqueue_script(
            'mkm-dspb-publisher-script',
            MKM_DSPB_URL . 'admin/js/publisher-script.js',
            array( 'jquery' ),
            MKM_DSPB_VERSION,
            true
        );

        global $post;
        wp_localize_script(
            'mkm-dspb-publisher-script',
            'mkmDspbPublisher',
            array(
                'postId'           => $post ? $post->ID : 0,
                'postUrl'          => $post ? mkm_dspb_get_clean_permalink( $post->ID ) : '',
                'postShortlink'    => $post ? $this->resolve_post_shortlink( $post ) : '',
                'postTitle'        => $post ? mkm_dspb_html_to_social_text( $post->post_title ) : '',
                'postExcerpt'      => $post ? $this->smart_extract_excerpt( $post, 240 ) : '',
                'shortenerProvider' => get_option( 'mkm_dspb_shortener_provider', 'none' ),
                'nonce'            => wp_create_nonce( 'mkm_dspb_manual_share_nonce' ),
                'selectChannelMsg' => __( 'Seleziona almeno un canale social.', 'mkmdigital-social-publisher-bridge' ),
                'sendingMsg'       => __( 'Invio in corso...', 'mkmdigital-social-publisher-bridge' ),
                'connectingMsg'    => __( 'Connessione alle API di Buffer...', 'mkmdigital-social-publisher-bridge' ),
                'errorMsg'         => __( 'Errore del server durante l\'invio.', 'mkmdigital-social-publisher-bridge' ),
                'btnText'          => __( 'Invia a Buffer ora', 'mkmdigital-social-publisher-bridge' ),
            )
        );
    }

    /**
     * Add metabox to selected post types
     */
    public function add_publishing_metabox() {
        $post_types = get_option( 'mkm_dspb_post_types', array( 'post' ) );
        $screen     = get_current_screen();

        if ( in_array( $screen->post_type, $post_types ) ) {
            add_meta_box(
                'mkm_dspb_metabox',
                __( 'WP Social Buffer Share', 'mkmdigital-social-publisher-bridge' ),
                array( $this, 'render_metabox' ),
                $screen->post_type,
                'normal',
                'high'
            );
        }
    }

    /**
     * Render the metabox content
     */
    public function render_metabox( $post ) {
        wp_nonce_field( 'mkm_dspb_metabox_action', 'mkm_dspb_metabox_nonce' );

        $token        = get_option( 'mkm_dspb_token', '' );
        $profiles     = get_option( 'mkm_dspb_profiles', array() );
        $defaults     = get_option( 'mkm_dspb_default_channels', array() );
        $publish_mode = get_option( 'mkm_dspb_publish_mode', 'addToQueue' );

        if ( empty( $token ) ) {
            echo '<p style="color:#d63638;">' . esc_html__( 'Please configure your Buffer Access Token in settings first.', 'mkmdigital-social-publisher-bridge' ) . '</p>';
            return;
        }

        if ( empty( $profiles ) ) {
            echo '<p style="color:#d63638;">' . esc_html__( 'No social channels synced. Sync them in plugin settings.', 'mkmdigital-social-publisher-bridge' ) . '</p>';
            return;
        }

        // Check if already published
        $is_published = get_post_meta( $post->ID, '_mkm_dspb_published', true );
        $logs         = get_post_meta( $post->ID, '_mkm_dspb_log', true );

        // Generate default template preview text
        $preview_text = mkm_dspb_html_to_social_text( $this->format_post_template( $post ) );

        // Load saved post meta overrides
        $settings        = get_post_meta( $post->ID, '_mkm_dspb_post_settings', true );
        $saved_channels  = get_post_meta( $post->ID, '_mkm_dspb_share_channels', true );
        $saved_share_now = get_post_meta( $post->ID, '_mkm_dspb_share_now', true );

        $defaults  = is_array( $saved_channels ) ? $saved_channels : get_option( 'mkm_dspb_default_channels', array() );
        $share_now = ( $saved_share_now !== '' && $saved_share_now !== false ) ? ( $saved_share_now === '1' ) : ( $publish_mode === 'shareNow' );

        $fb_text    = isset( $settings['facebook']['custom_text'] ) ? mkm_dspb_html_to_social_text( $settings['facebook']['custom_text'] ) : '';
        $fb_move    = isset( $settings['facebook']['move_link'] ) ? $settings['facebook']['move_link'] : get_option( 'mkm_dspb_move_link_to_comment', '0' );
        $fb_comment = isset( $settings['facebook']['comment'] ) ? $settings['facebook']['comment'] : '';

        $ig_text    = isset( $settings['instagram']['custom_text'] ) ? mkm_dspb_html_to_social_text( $settings['instagram']['custom_text'] ) : '';
        $ig_move    = isset( $settings['instagram']['move_link'] ) ? $settings['instagram']['move_link'] : '0';
        $ig_comment = isset( $settings['instagram']['comment'] ) ? $settings['instagram']['comment'] : '';

        $li_text    = isset( $settings['linkedin']['custom_text'] ) ? mkm_dspb_html_to_social_text( $settings['linkedin']['custom_text'] ) : '';
        $li_move    = isset( $settings['linkedin']['move_link'] ) ? $settings['linkedin']['move_link'] : get_option( 'mkm_dspb_move_link_to_comment', '0' );
        $li_comment = isset( $settings['linkedin']['comment'] ) ? $settings['linkedin']['comment'] : '';

        $gmb_text   = isset( $settings['googlebusiness']['custom_text'] ) ? mkm_dspb_html_to_social_text( $settings['googlebusiness']['custom_text'] ) : '';
        $tw_text    = isset( $settings['twitter']['custom_text'] ) ? mkm_dspb_html_to_social_text( $settings['twitter']['custom_text'] ) : '';

        // Determine active networks based on connected profiles
        $active_services = array();
        foreach ( $profiles as $profile ) {
            if ( isset( $profile['service'] ) ) {
                $active_services[] = $profile['service'];
            }
        }
        $active_services = array_unique( $active_services );

        $services_config = array(
            'facebook'       => 'fb',
            'instagram'      => 'ig',
            'linkedin'       => 'li',
            'googlebusiness' => 'gmb',
            'twitter'        => 'tw',
        );

        $visible_services = array();
        foreach ( $services_config as $key => $target ) {
            if ( in_array( $key, $active_services ) ) {
                $visible_services[] = $key;
            }
        }
        $default_active_service = ! empty( $visible_services ) ? $visible_services[0] : 'facebook';

        // Extract channel names & real profile avatars
        $fb_name   = __( 'Facebook Page', 'mkmdigital-social-publisher-bridge' );
        $ig_name   = __( 'instagram_profile', 'mkmdigital-social-publisher-bridge' );
        $li_name   = __( 'LinkedIn Page', 'mkmdigital-social-publisher-bridge' );
        $gmb_name  = __( 'Google Business', 'mkmdigital-social-publisher-bridge' );
        $tw_name   = __( 'X (Twitter) Profile', 'mkmdigital-social-publisher-bridge' );
        $fb_avatar  = '';
        $ig_avatar  = '';
        $li_avatar  = '';
        $gmb_avatar = '';
        $tw_avatar  = '';

        foreach ( $profiles as $key => $profile ) {
            $avatar_url = ! empty( $profile['avatar'] ) ? $profile['avatar'] : '';
            if ( 'facebook' === $profile['service'] ) {
                $fb_name = $profile['name'];
                if ( $avatar_url ) $fb_avatar = $avatar_url;
            } elseif ( 'instagram' === $profile['service'] ) {
                $ig_name = $profile['name'];
                if ( $avatar_url ) $ig_avatar = $avatar_url;
            } elseif ( 'linkedin' === $profile['service'] ) {
                $li_name = $profile['name'];
                if ( $avatar_url ) $li_avatar = $avatar_url;
            } elseif ( 'googlebusiness' === $profile['service'] ) {
                $gmb_name = $profile['name'];
                if ( $avatar_url ) $gmb_avatar = $avatar_url;
            } elseif ( 'twitter' === $profile['service'] ) {
                $tw_name = $profile['name'];
                if ( $avatar_url ) $tw_avatar = $avatar_url;
            }
        }

        $post_media = self::get_post_media_urls( $post->ID );
        $img_url    = ! empty( $post_media ) ? $post_media[0] : ( get_the_post_thumbnail_url( $post->ID, 'large' ) ?: get_the_post_thumbnail_url( $post->ID, 'full' ) );

        // Official Network SVG Icons
        $svg_facebook  = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#1877f2"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>';
        $svg_instagram = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="url(#ig-grad-free)" d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/><defs><linearGradient id="ig-grad-free" x1="0%" y1="100%" x2="100%" y2="0%"><stop offset="0%" stop-color="#f09433"/><stop offset="25%" stop-color="#e6683c"/><stop offset="50%" stop-color="#dc2743"/><stop offset="75%" stop-color="#cc2366"/><stop offset="100%" stop-color="#bc1888"/></linearGradient></defs></svg>';
        $svg_linkedin  = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#0077b5"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.779-1.75-1.75s.784-1.75 1.75-1.75 1.75.779 1.75 1.75-.784 1.75-1.75 1.75zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>';
        $svg_google    = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="#4285F4" d="M23.745 12.27c0-.7-.06-1.4-.19-2.07H12v4.51h6.6c-.29 1.52-1.14 2.82-2.4 3.68v3.05h3.88c2.27-2.09 3.665-5.17 3.665-9.17z"/><path fill="#34A853" d="M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.88-3.05c-1.08.72-2.45 1.16-4.05 1.16-3.12 0-5.77-2.1-6.72-4.93H1.29v3.15C3.26 21.3 7.31 24 12 24z"/><path fill="#FBBC05" d="M5.28 14.27c-.25-.72-.38-1.49-.38-2.27s.13-1.55.38-2.27V6.58H1.29C.47 8.2.0 10.04.0 12s.47 3.8 1.29 5.42l3.99-3.15z"/><path fill="#EA4335" d="M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.31 0 3.26 2.7 1.29 6.58l3.99 3.15c.95-2.83 3.6-4.98 6.72-4.98z"/></svg>';
        $svg_twitter   = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#000000"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>';
        $svg_threads   = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#000000"><path d="M12.004 0C5.372 0 0 5.372 0 12s5.372 12 12.004 12c6.627 0 11.996-5.372 11.996-12S18.631 0 12.004 0zm4.845 13.791c-.139 1.954-1.393 3.422-3.324 3.738-1.579.259-3.131-.194-4.103-1.226-.814-.863-1.173-2.062-1.026-3.385.228-2.054 1.832-3.612 3.901-3.785 1.578-.133 3.033.473 3.903 1.621.144.19.09.458-.105.592-.196.134-.462.083-.605-.107-.714-.943-1.91-1.44-3.21-1.33-1.696.142-3.007 1.417-3.195 3.099-.12 1.082.176 2.063.84 2.766.793.842 2.066 1.212 3.359 1.001 1.472-.241 2.479-1.327 2.585-2.778.083-1.135-.458-2.079-1.458-2.532-1.029-.466-2.316-.277-3.08.452-.162.155-.417.147-.57-.017-.152-.164-.144-.418.019-.571 1.05-.998 2.772-1.248 4.148-.625 1.341.607 2.082 1.884 1.986 3.487z"/></svg>';
        $svg_bluesky   = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#0085ff"><path d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.737.935 2.645c-.626.908-.344 2.825.293 4.298.638 1.473 2.518 3.524 3.791 4.542.427.342.923.633 1.439.882-2.036.05-4.147.288-5.385 1.155-1.238.867-1.419 2.493-.842 3.666.576 1.173 2.164 1.968 3.921 1.968 2.94 0 5.485-1.892 7.848-5.356 2.363 3.464 4.908 5.356 7.848 5.356 1.757 0 3.345-.795 3.921-1.968.577-1.173.396-2.799-.842-3.666-1.238-.867-3.349-1.105-5.385-1.155.516-.249 1.012-.54 1.439-.882 1.273-1.018 3.153-3.069 3.791-4.542.637-1.473.919-3.39.293-4.298-.626-.908-1.631-1.701-4.267.165C16.046 4.747 13.087 8.686 12 10.8z"/></svg>';
        $svg_pinterest = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#e60023"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg>';
        $svg_youtube   = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#FF0000"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>';
        $svg_tiktok    = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#000000"><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.97-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.82.56-1.31 1.52-1.34 2.52-.06 1.41.87 2.73 2.24 3.09 1.31.35 2.76-.11 3.58-1.15.53-.66.8-1.48.81-2.32.03-4.57.02-9.14.02-13.71z"/></svg>';
        $svg_mastodon  = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="#6364FF"><path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.3-5.004C15.54.004 12 .004 12 .004s-3.54 0-5.968.305C3.352.703 1.085 2.735.735 5.313c-.41 3.018-.458 6.444-.109 9.537.28 2.47 1.503 4.887 3.93 5.922 2.378 1.014 5.074 1.19 7.448 1.077 1.637-.078 3.272-.349 4.793-.93 0 0 .428-.168.397-.563 0 0-.012-.224-.047-.56-.035-.335-.045-.436-.045-.436s-1.282.474-2.885.643c-1.58.167-3.329.176-4.757-.22-1.782-.494-2.28-1.92-2.39-3.064 0 0 1.838.455 4.316.562 1.62.07 3.238-.035 4.834-.316 2.551-.45 4.848-1.942 5.163-5.004.35-3.093.3-6.52-.109-9.537zm-4.73 7.828h-2.396v-5.61c0-1.182-.496-1.782-1.488-1.782-1.095 0-1.643.708-1.643 2.115v3.06h-2.01v-3.06c0-1.407-.548-2.115-1.643-2.115-.992 0-1.488.6-1.488 1.782v5.61H5.463V7.322c0-1.182.302-2.122.907-2.818.632-.718 1.463-1.09 2.497-1.09 1.233 0 2.163.477 2.776 1.433l.357.564.357-.564c.613-.956 1.543-1.433 2.776-1.433 1.034 0 1.865.372 2.497 1.09.605.696.907 1.636.907 2.818v5.819z"/></svg>';
        ?>
        <div class="mkm-dspb-meta-container" data-default-text="<?php echo esc_attr( $preview_text ); ?>">
            
            <!-- Left Panel: Controls & Inputs -->
            <div class="mkm-dspb-controls-panel">
                <?php if ( $is_published ) : ?>
                    <div class="notice notice-success is-dismissible" style="margin: 0 0 15px 0; padding: 8px 12px; border-left-color: #46b450;">
                        <p style="margin: 0; font-size: 0.95em;">
                            <strong><?php esc_html_e( 'Auto-shared to Buffer!', 'mkmdigital-social-publisher-bridge' ); ?></strong>
                            <?php if ( ! empty( $logs['time'] ) ) : ?>
                                <br/><span style="font-size: 0.85em; color: #666;"><?php echo esc_html( $logs['time'] ); ?></span>
                            <?php endif; ?>
                        </p>
                    </div>
                <?php endif; ?>

                <!-- Channels Selector -->
                <p style="margin-top: 0;"><strong style="font-size: 1.1em; font-weight: 600;"><?php esc_html_e( 'Share on Channels:', 'mkmdigital-social-publisher-bridge' ); ?></strong></p>
                <div style="max-height: 140px; overflow-y: auto; border: 1px solid #ccd0d4; border-radius: 4px; padding: 8px 12px; background: #fff; margin-bottom: 20px;">
                    <?php foreach ( $profiles as $key => $profile ) :
                        $icon_svg = $svg_facebook;
                        if ( 'instagram' === $profile['service'] ) { $icon_svg = $svg_instagram; }
                        elseif ( 'linkedin' === $profile['service'] ) { $icon_svg = $svg_linkedin; }
                        elseif ( 'googlebusiness' === $profile['service'] ) { $icon_svg = $svg_google; }
                        elseif ( 'twitter' === $profile['service'] ) { $icon_svg = $svg_twitter; }
                        elseif ( 'threads' === $profile['service'] ) { $icon_svg = $svg_threads; }
                        elseif ( 'bluesky' === $profile['service'] ) { $icon_svg = $svg_bluesky; }
                        elseif ( 'pinterest' === $profile['service'] ) { $icon_svg = $svg_pinterest; }
                        elseif ( 'youtube' === $profile['service'] ) { $icon_svg = $svg_youtube; }
                        elseif ( 'tiktok' === $profile['service'] ) { $icon_svg = $svg_tiktok; }
                        elseif ( 'mastodon' === $profile['service'] ) { $icon_svg = $svg_mastodon; }
                        ?>
                        <label style="display: flex; align-items: center; margin-bottom: 8px; cursor: pointer;">
                            <input type="checkbox" name="mkm_dspb_share_channels[]" class="mkm-dspb-meta-channel-cb" value="<?php echo esc_attr( $key ); ?>" <?php checked( in_array( $key, $defaults ) ); ?> style="margin-right: 8px;" />
                            <span style="display: inline-flex; align-items: center; margin-right: 6px; vertical-align: middle;"><?php echo $icon_svg; ?></span>
                            <span style="font-size: 0.95em;"><strong><?php echo esc_html( ucfirst( $profile['service'] ) ); ?></strong>: <?php echo esc_html( $profile['name'] ); ?></span>
                        </label>
                    <?php endforeach; ?>
                </div>

                <?php
                $render_tag_pills = function( $target_id ) {
                    ?>
                    <div class="mkm-dspb-tag-pills" style="margin-top: 6px; font-size: 11px; color: #50575e; display: flex; align-items: center; gap: 4px; flex-wrap: wrap;">
                        <span style="font-weight: 600; margin-right: 2px;"><?php esc_html_e( 'Inserisci Tag:', 'mkmdigital-social-publisher-bridge' ); ?></span>
                        <button type="button" class="mkm-dspb-tag-pill" data-target="<?php echo esc_attr( $target_id ); ?>" data-tag="{link}" title="<?php esc_attr_e( 'Link completo al post', 'mkmdigital-social-publisher-bridge' ); ?>" style="background: #f0f0f1; border: 1px solid #c3c4c7; border-radius: 3px; padding: 2px 6px; font-size: 11px; cursor: pointer; font-family: monospace; color: #1d2327;">{link}</button>
                        <button type="button" class="mkm-dspb-tag-pill" data-target="<?php echo esc_attr( $target_id ); ?>" data-tag="{shortlink}" title="<?php esc_attr_e( 'Short URL nativo WordPress', 'mkmdigital-social-publisher-bridge' ); ?>" style="background: #e7f5fe; border: 1px solid #9ec5fe; border-radius: 3px; padding: 2px 6px; font-size: 11px; cursor: pointer; font-family: monospace; color: #0c4a6e; font-weight: bold;">{shortlink}</button>
                        <button type="button" class="mkm-dspb-tag-pill" data-target="<?php echo esc_attr( $target_id ); ?>" data-tag="{title}" title="<?php esc_attr_e( 'Titolo del post', 'mkmdigital-social-publisher-bridge' ); ?>" style="background: #f0f0f1; border: 1px solid #c3c4c7; border-radius: 3px; padding: 2px 6px; font-size: 11px; cursor: pointer; font-family: monospace; color: #1d2327;">{title}</button>
                        <button type="button" class="mkm-dspb-tag-pill" data-target="<?php echo esc_attr( $target_id ); ?>" data-tag="{excerpt}" title="<?php esc_attr_e( 'Estratto / Meta Description SEO', 'mkmdigital-social-publisher-bridge' ); ?>" style="background: #f0f0f1; border: 1px solid #c3c4c7; border-radius: 3px; padding: 2px 6px; font-size: 11px; cursor: pointer; font-family: monospace; color: #1d2327;">{excerpt}</button>
                    </div>
                    <?php
                };
                ?>

                <!-- Tab Panels for customizing per network -->
                <div class="mkm-dspb-network-tabs-wrapper" style="border: 1px solid #ccd0d4; border-radius: 4px; background: #fafafa; padding: 15px; margin-bottom: 20px;">
                    
                    <?php if ( in_array( 'facebook', $active_services ) ) : ?>
                    <!-- Facebook Tab Options -->
                    <div class="mkm-dspb-form-tab <?php echo ( $default_active_service === 'facebook' ) ? 'active' : ''; ?>" id="mkm-dspb-form-fb" style="display: <?php echo ( $default_active_service === 'facebook' ) ? 'block' : 'none'; ?>;">
                        <h4 style="margin: 0 0 10px 0; font-size: 1.1em; color: #1877f2; display: flex; align-items: center; gap: 6px;">
                            <?php echo $svg_facebook; ?> Facebook Options
                        </h4>
                        <p style="margin-top: 0; margin-bottom: 0;">
                            <label for="mkm_dspb_fb_text"><strong><?php esc_html_e( 'Custom Social Message:', 'mkmdigital-social-publisher-bridge' ); ?></strong></label><br/>
                            <textarea id="mkm_dspb_fb_text" name="mkm_dspb_fb_text" rows="4" style="width:100%; font-size:12px; margin-top:5px; padding: 8px; border-radius: 4px; border: 1px solid #ccd0d4;" placeholder="<?php esc_attr_e( 'Leave empty to use default template...', 'mkmdigital-social-publisher-bridge' ); ?>"><?php echo esc_textarea( $fb_text ); ?></textarea>
                            <?php $render_tag_pills( 'mkm_dspb_fb_text' ); ?>
                        </p>
                    </div>
                    <?php endif; ?>

                    <?php if ( in_array( 'instagram', $active_services ) ) : ?>
                    <!-- Instagram Tab Options -->
                    <div class="mkm-dspb-form-tab <?php echo ( $default_active_service === 'instagram' ) ? 'active' : ''; ?>" id="mkm-dspb-form-ig" style="display: <?php echo ( $default_active_service === 'instagram' ) ? 'block' : 'none'; ?>;">
                        <h4 style="margin: 0 0 10px 0; font-size: 1.1em; color: #cc2366; display: flex; align-items: center; gap: 6px;">
                            <?php echo $svg_instagram; ?> Instagram Options
                        </h4>
                        <p style="margin-top: 0; margin-bottom: 0;">
                            <label for="mkm_dspb_ig_text"><strong><?php esc_html_e( 'Custom Social Message:', 'mkmdigital-social-publisher-bridge' ); ?></strong></label><br/>
                            <textarea id="mkm_dspb_ig_text" name="mkm_dspb_ig_text" rows="4" style="width:100%; font-size:12px; margin-top:5px; padding: 8px; border-radius: 4px; border: 1px solid #ccd0d4;" placeholder="<?php esc_attr_e( 'Leave empty to use default template...', 'mkmdigital-social-publisher-bridge' ); ?>"><?php echo esc_textarea( $ig_text ); ?></textarea>
                            <?php $render_tag_pills( 'mkm_dspb_ig_text' ); ?>
                        </p>
                    </div>
                    <?php endif; ?>

                    <?php if ( in_array( 'linkedin', $active_services ) ) : ?>
                    <!-- LinkedIn Tab Options -->
                    <div class="mkm-dspb-form-tab <?php echo ( $default_active_service === 'linkedin' ) ? 'active' : ''; ?>" id="mkm-dspb-form-li" style="display: <?php echo ( $default_active_service === 'linkedin' ) ? 'block' : 'none'; ?>;">
                        <h4 style="margin: 0 0 10px 0; font-size: 1.1em; color: #0077b5; display: flex; align-items: center; gap: 6px;">
                            <?php echo $svg_linkedin; ?> LinkedIn Options
                        </h4>
                        <p style="margin-top: 0; margin-bottom: 0;">
                            <label for="mkm_dspb_li_text"><strong><?php esc_html_e( 'Custom Social Message:', 'mkmdigital-social-publisher-bridge' ); ?></strong></label><br/>
                            <textarea id="mkm_dspb_li_text" name="mkm_dspb_li_text" rows="4" style="width:100%; font-size:12px; margin-top:5px; padding: 8px; border-radius: 4px; border: 1px solid #ccd0d4;" placeholder="<?php esc_attr_e( 'Leave empty to use default template...', 'mkmdigital-social-publisher-bridge' ); ?>"><?php echo esc_textarea( $li_text ); ?></textarea>
                            <?php $render_tag_pills( 'mkm_dspb_li_text' ); ?>
                        </p>
                    </div>
                    <?php endif; ?>

                    <?php if ( in_array( 'googlebusiness', $active_services ) ) : ?>
                    <!-- Google Business Tab Options -->
                    <div class="mkm-dspb-form-tab <?php echo ( $default_active_service === 'googlebusiness' ) ? 'active' : ''; ?>" id="mkm-dspb-form-gmb" style="display: <?php echo ( $default_active_service === 'googlebusiness' ) ? 'block' : 'none'; ?>;">
                        <h4 style="margin: 0 0 10px 0; font-size: 1.1em; color: #4285f4; display: flex; align-items: center; gap: 6px;">
                            <?php echo $svg_google; ?> Google Business Options
                        </h4>
                        <p style="margin-top: 0; margin-bottom: 0;">
                            <label for="mkm_dspb_gmb_text"><strong><?php esc_html_e( 'Custom Social Message:', 'mkmdigital-social-publisher-bridge' ); ?></strong></label><br/>
                            <textarea id="mkm_dspb_gmb_text" name="mkm_dspb_gmb_text" rows="4" style="width:100%; font-size:12px; margin-top:5px; padding: 8px; border-radius: 4px; border: 1px solid #ccd0d4;" placeholder="<?php esc_attr_e( 'Leave empty to use default template...', 'mkmdigital-social-publisher-bridge' ); ?>"><?php echo esc_textarea( $gmb_text ); ?></textarea>
                            <?php $render_tag_pills( 'mkm_dspb_gmb_text' ); ?>
                        </p>
                    </div>
                    <?php endif; ?>

                    <?php if ( in_array( 'twitter', $active_services ) ) : ?>
                    <!-- X (Twitter) Tab Options -->
                    <div class="mkm-dspb-form-tab <?php echo ( $default_active_service === 'twitter' ) ? 'active' : ''; ?>" id="mkm-dspb-form-tw" style="display: <?php echo ( $default_active_service === 'twitter' ) ? 'block' : 'none'; ?>;">
                        <h4 style="margin: 0 0 10px 0; font-size: 1.1em; color: #000; display: flex; align-items: center; gap: 6px;">
                            <?php echo $svg_twitter; ?> X (Twitter) Options
                        </h4>
                        <p style="margin-top: 0; margin-bottom: 0;">
                            <label for="mkm_dspb_tw_text"><strong><?php esc_html_e( 'Custom Social Message:', 'mkmdigital-social-publisher-bridge' ); ?></strong></label><br/>
                            <textarea id="mkm_dspb_tw_text" name="mkm_dspb_tw_text" rows="4" style="width:100%; font-size:12px; margin-top:5px; padding: 8px; border-radius: 4px; border: 1px solid #ccd0d4;" placeholder="<?php esc_attr_e( 'Leave empty to use default template...', 'mkmdigital-social-publisher-bridge' ); ?>"><?php echo esc_textarea( $tw_text ); ?></textarea>
                            <?php $render_tag_pills( 'mkm_dspb_tw_text' ); ?>
                            <small id="mkm_dspb_tw_char_counter" style="display:block; margin-top: 4px; color: #666; font-weight: 500;">0 / 280</small>
                        </p>
                    </div>
                    <?php endif; ?>
                </div>

                <!-- Share Now Selector -->
                <p style="margin-bottom: 15px;">
                    <label style="cursor: pointer;">
                        <input type="checkbox" name="mkm_dspb_share_now" value="1" <?php checked( $share_now ); ?> style="margin-right: 6px;" />
                        <span style="font-size: 1em;"><strong><?php esc_html_e( 'Publish Immediately', 'mkmdigital-social-publisher-bridge' ); ?></strong></span>
                    </label>
                </p>

                <!-- Manual Share Button via AJAX -->
                <button type="button" id="mkm_dspb_btn_share" class="button button-primary button-large" style="width: 100%; font-weight: bold; background: #C59B27; border-color: #C59B27; text-shadow: none; box-shadow: none;">
                    <?php esc_html_e( 'Send to Buffer Now', 'mkmdigital-social-publisher-bridge' ); ?>
                </button>
                <div id="mkm_dspb_feedback" style="margin-top: 10px; font-size: 0.95em; font-weight: 600;"></div>
            </div>

            <!-- Right Panel: Live Social Preview -->
            <div class="mkm-dspb-preview-panel">
                <strong style="font-size: 1.2em; color: #333; display: block; margin-bottom: 12px;"><?php esc_html_e( 'Social Preview', 'mkmdigital-social-publisher-bridge' ); ?></strong>
                
                <!-- Tab headers -->
                <div class="mkm-dspb-preview-tabs" style="display: flex; margin-bottom: 15px; border-bottom: 1px solid #ddd; padding-bottom: 0; gap: 6px;">
                    <?php if ( in_array( 'facebook', $active_services ) ) : ?>
                        <button type="button" class="mkm-dspb-preview-tab-btn <?php echo ( $default_active_service === 'facebook' ) ? 'active' : ''; ?>" data-target="fb" style="display:inline-flex; align-items:center; gap:5px;"><?php echo $svg_facebook; ?> Facebook</button>
                    <?php endif; ?>
                    <?php if ( in_array( 'instagram', $active_services ) ) : ?>
                        <button type="button" class="mkm-dspb-preview-tab-btn <?php echo ( $default_active_service === 'instagram' ) ? 'active' : ''; ?>" data-target="ig" style="display:inline-flex; align-items:center; gap:5px;"><?php echo $svg_instagram; ?> Instagram</button>
                    <?php endif; ?>
                    <?php if ( in_array( 'linkedin', $active_services ) ) : ?>
                        <button type="button" class="mkm-dspb-preview-tab-btn <?php echo ( $default_active_service === 'linkedin' ) ? 'active' : ''; ?>" data-target="li" style="display:inline-flex; align-items:center; gap:5px;"><?php echo $svg_linkedin; ?> LinkedIn</button>
                    <?php endif; ?>
                    <?php if ( in_array( 'googlebusiness', $active_services ) ) : ?>
                        <button type="button" class="mkm-dspb-preview-tab-btn <?php echo ( $default_active_service === 'googlebusiness' ) ? 'active' : ''; ?>" data-target="gmb" style="display:inline-flex; align-items:center; gap:5px;"><?php echo $svg_google; ?> Google</button>
                    <?php endif; ?>
                    <?php if ( in_array( 'twitter', $active_services ) ) : ?>
                        <button type="button" class="mkm-dspb-preview-tab-btn <?php echo ( $default_active_service === 'twitter' ) ? 'active' : ''; ?>" data-target="tw" style="display:inline-flex; align-items:center; gap:5px;"><?php echo $svg_twitter; ?> X</button>
                    <?php endif; ?>
                </div>

                <?php if ( in_array( 'facebook', $active_services ) ) : ?>
                <!-- Facebook Preview Card -->
                <div class="mkm-dspb-preview-card <?php echo ( $default_active_service === 'facebook' ) ? 'active' : ''; ?>" id="mkm-dspb-card-fb" style="border: 1px solid #ddd; border-radius: 8px; background: #fff; padding: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; display: <?php echo ( $default_active_service === 'facebook' ) ? 'block' : 'none'; ?>; box-shadow: 0 1px 2px rgba(0,0,0,0.05);">
                    <div style="display: flex; align-items: center; margin-bottom: 10px;">
                        <?php if ( ! empty( $fb_avatar ) ) : ?>
                            <div style="width: 36px; height: 36px; border-radius: 50%; background-image: url('<?php echo esc_url( $fb_avatar ); ?>'); background-size: cover; background-position: center; margin-right: 10px; flex-shrink: 0; position: relative;">
                                <span style="position: absolute; bottom: -2px; right: -2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; border: 1px solid #fff;"><?php echo $svg_facebook; ?></span>
                            </div>
                        <?php else : ?>
                            <div style="width: 36px; height: 36px; border-radius: 50%; background: #1877f2; display: flex; align-items: center; justify-content: center; margin-right: 10px; flex-shrink: 0;">
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="#fff"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
                            </div>
                        <?php endif; ?>
                        <div>
                            <div style="font-weight: bold; font-size: 13px; color: #050505; line-height: 1.2;"><?php echo esc_html( $fb_name ); ?></div>
                            <div style="font-size: 11px; color: #65676b;"><?php esc_html_e( 'Just now', 'mkmdigital-social-publisher-bridge' ); ?> &bull; 🌐</div>
                        </div>
                    </div>
                    <div class="mkm-dspb-card-text" style="font-size: 13px; line-height: 1.4; color: #050505; white-space: pre-wrap; word-break: break-word; margin-bottom: 12px;"></div>
                    <?php if ( $img_url ) : ?>
                        <div class="mkm-dspb-preview-media" style="margin: 0 -12px 10px -12px; border-top: 1px solid #e5e5e5; background: #f0f2f5; overflow: hidden; display: flex; align-items: center; justify-content: center;">
                            <img src="<?php echo esc_url( $img_url ); ?>" style="width: 100%; height: auto; max-height: 420px; object-fit: contain; display: block;" />
                        </div>
                    <?php endif; ?>

                </div>
                <?php endif; ?>

                <?php if ( in_array( 'instagram', $active_services ) ) : ?>
                <!-- Instagram Preview Card -->
                <div class="mkm-dspb-preview-card <?php echo ( $default_active_service === 'instagram' ) ? 'active' : ''; ?>" id="mkm-dspb-card-ig" style="border: 1px solid #ddd; border-radius: 8px; background: #fff; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; display: <?php echo ( $default_active_service === 'instagram' ) ? 'block' : 'none'; ?>; overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,0.05);">
                    <div style="display: flex; align-items: center; padding: 10px 12px;">
                        <?php if ( ! empty( $ig_avatar ) ) : ?>
                            <div style="width: 32px; height: 32px; border-radius: 50%; background-image: url('<?php echo esc_url( $ig_avatar ); ?>'); background-size: cover; background-position: center; border: 1.5px solid #e6683c; margin-right: 10px; flex-shrink: 0;"></div>
                        <?php else : ?>
                            <div style="width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%); display: flex; align-items: center; justify-content: center; margin-right: 10px; flex-shrink: 0;">
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="#fff"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/><defs><linearGradient id="ig-grad-free" x1="0%" y1="100%" x2="100%" y2="0%"><stop offset="0%" stop-color="#f09433"/><stop offset="25%" stop-color="#e6683c"/><stop offset="50%" stop-color="#dc2743"/><stop offset="75%" stop-color="#cc2366"/><stop offset="100%" stop-color="#bc1888"/></linearGradient></defs></svg>
                            </div>
                        <?php endif; ?>
                        <div style="font-weight: 600; font-size: 12px; color: #262626;"><?php echo esc_html( strtolower( str_replace(' ', '', $ig_name) ) ); ?></div>
                    </div>
                    <div class="mkm-dspb-preview-media" style="background: #fafafa; border-top: 1px solid #efefef; border-bottom: 1px solid #efefef; display: flex; align-items: center; justify-content: center; min-height: 180px; overflow: hidden;">
                        <?php if ( $img_url ) : ?>
                            <img src="<?php echo esc_url( $img_url ); ?>" style="width: 100%; height: auto; max-height: 420px; object-fit: contain; display: block;" />
                        <?php else : ?>
                            <div style="width: 100%; min-height: 180px; display: flex; align-items: center; justify-content: center; background: #fafafa; color: #999; font-size: 12px; flex-direction: column; padding: 15px; text-align: center;">
                                <span style="font-size: 22px; margin-bottom: 5px;">📷</span>
                                <strong><?php esc_html_e( 'Nessuna immagine in evidenza', 'mkmdigital-social-publisher-bridge' ); ?></strong>
                                <span style="color:#d63638; font-size:10px; margin-top:5px; font-weight:600;"><?php esc_html_e( 'Richiesta per Instagram', 'mkmdigital-social-publisher-bridge' ); ?></span>
                            </div>
                        <?php endif; ?>
                    </div>
                    <div style="padding: 10px 12px; font-size: 16px; color: #262626; display: flex; align-items: center; gap: 14px;">
                        <!-- Official Instagram Action Vector Icons -->
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l8.72-8.72 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg>
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#262626" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left: auto;"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>
                    </div>
                    <div style="padding: 0 12px 12px 12px; font-size: 12px; line-height: 1.4; color: #262626;">
                        <span style="font-weight: 600; margin-right: 6px;"><?php echo esc_html( strtolower( str_replace(' ', '', $ig_name) ) ); ?></span>
                        <span class="mkm-dspb-card-text" style="white-space: pre-wrap;"></span>
                    </div>

                </div>
                <?php endif; ?>

                <?php if ( in_array( 'linkedin', $active_services ) ) : ?>
                <!-- LinkedIn Preview Card -->
                <div class="mkm-dspb-preview-card <?php echo ( $default_active_service === 'linkedin' ) ? 'active' : ''; ?>" id="mkm-dspb-card-li" style="border: 1px solid #ddd; border-radius: 8px; background: #fff; padding: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; display: <?php echo ( $default_active_service === 'linkedin' ) ? 'block' : 'none'; ?>; box-shadow: 0 1px 2px rgba(0,0,0,0.05);">
                    <div style="display: flex; align-items: center; margin-bottom: 10px;">
                        <div style="width: 36px; height: 36px; border-radius: 4px; background: #0077b5; display: flex; align-items: center; justify-content: center; margin-right: 10px; flex-shrink: 0; position: relative; overflow: visible;">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="#fff"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.779-1.75-1.75s.784-1.75 1.75-1.75 1.75.779 1.75 1.75-.784 1.75-1.75-1.75zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>
                            <?php if ( ! empty( $li_avatar ) ) : ?>
                                <img src="<?php echo esc_url( $li_avatar ); ?>" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 4px; display: block; z-index: 1;" onerror="this.style.display='none';" />
                            <?php endif; ?>
                            <span style="position: absolute; bottom: -2px; right: -2px; width: 14px; height: 14px; border-radius: 2px; background: #fff; display: flex; align-items: center; justify-content: center; border: 1px solid #fff; z-index: 2;"><?php echo $svg_linkedin; ?></span>
                        </div>
                        <div>
                            <div style="font-weight: bold; font-size: 13px; color: #000000; line-height: 1.2;"><?php echo esc_html( $li_name ); ?></div>
                            <div style="font-size: 11px; color: #666;"><?php esc_html_e( 'Just now', 'mkmdigital-social-publisher-bridge' ); ?> &bull; 🌐</div>
                        </div>
                    </div>
                    <div class="mkm-dspb-card-text" style="font-size: 13px; line-height: 1.4; color: #191919; white-space: pre-wrap; word-break: break-word; margin-bottom: 12px;"></div>
                    <?php if ( $img_url ) : ?>
                        <div class="mkm-dspb-preview-media" style="margin: 0 -12px 10px -12px; border-top: 1px solid #e5e5e5; background: #f3f2ef; overflow: hidden; display: flex; align-items: center; justify-content: center;">
                            <img src="<?php echo esc_url( $img_url ); ?>" style="width: 100%; height: auto; max-height: 420px; object-fit: contain; display: block;" />
                        </div>
                    <?php endif; ?>

                </div>
                <?php endif; ?>

                <?php if ( in_array( 'googlebusiness', $active_services ) ) : ?>
                <!-- Google Business Preview Card -->
                <div class="mkm-dspb-preview-card <?php echo ( $default_active_service === 'googlebusiness' ) ? 'active' : ''; ?>" id="mkm-dspb-card-gmb" style="border: 1px solid #ddd; border-radius: 8px; background: #fff; padding: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; display: <?php echo ( $default_active_service === 'googlebusiness' ) ? 'block' : 'none'; ?>; box-shadow: 0 1px 2px rgba(0,0,0,0.05);">
                    <div style="display: flex; align-items: center; margin-bottom: 10px;">
                        <?php if ( ! empty( $gmb_avatar ) ) : ?>
                            <div style="width: 32px; height: 32px; border-radius: 50%; background-image: url('<?php echo esc_url( $gmb_avatar ); ?>'); background-size: cover; background-position: center; margin-right: 10px; flex-shrink: 0; position: relative;">
                                <span style="position: absolute; bottom: -2px; right: -2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; border: 1px solid #fff;"><?php echo $svg_google; ?></span>
                            </div>
                        <?php else : ?>
                            <div style="width: 32px; height: 32px; border-radius: 50%; background: #ffffff; border: 1px solid #e0e0e0; display: flex; align-items: center; justify-content: center; margin-right: 10px; flex-shrink: 0;">
                                <?php echo $svg_google; ?>
                            </div>
                        <?php endif; ?>
                        <div>
                            <div style="font-weight: bold; font-size: 13px; color: #202124; line-height: 1.2;"><?php echo esc_html( $gmb_name ); ?></div>
                            <div style="font-size: 11px; color: #70757a;"><?php esc_html_e( 'Post sul profilo dell\'attività', 'mkmdigital-social-publisher-bridge' ); ?></div>
                        </div>
                    </div>
                    <?php if ( $img_url ) : ?>
                        <div class="mkm-dspb-preview-media" style="margin: 0 -12px 10px -12px; border-top: 1px solid #f1f3f4; background: #f8f9fa; overflow: hidden; display: flex; align-items: center; justify-content: center;">
                            <img src="<?php echo esc_url( $img_url ); ?>" style="width: 100%; height: auto; max-height: 420px; object-fit: contain; display: block;" />
                        </div>
                    <?php endif; ?>
                    <div class="mkm-dspb-card-text" style="font-size: 12px; line-height: 1.5; color: #3c4043; white-space: pre-wrap; word-break: break-word;"></div>
                </div>
                <?php endif; ?>

                <?php if ( in_array( 'twitter', $active_services ) ) : ?>
                <!-- X (Twitter) Preview Card -->
                <div class="mkm-dspb-preview-card <?php echo ( $default_active_service === 'twitter' ) ? 'active' : ''; ?>" id="mkm-dspb-card-tw" style="border: 1px solid #ddd; border-radius: 8px; background: #fff; padding: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; display: <?php echo ( $default_active_service === 'twitter' ) ? 'block' : 'none'; ?>; box-shadow: 0 1px 2px rgba(0,0,0,0.05);">
                    <div style="display: flex; align-items: center; margin-bottom: 10px;">
                        <div style="width: 36px; height: 36px; border-radius: 50%; background: #000; display: flex; align-items: center; justify-content: center; margin-right: 10px; flex-shrink: 0;">
                            <?php echo $svg_twitter; ?>
                        </div>
                        <div>
                            <div style="font-weight: bold; font-size: 13px; color: #000000; line-height: 1.2;"><?php echo esc_html( $tw_name ); ?></div>
                            <div style="font-size: 11px; color: #666;"><?php esc_html_e( 'Just now', 'mkmdigital-social-publisher-bridge' ); ?> &bull; 🌐</div>
                        </div>
                    </div>
                    <div class="mkm-dspb-card-text" style="font-size: 13px; line-height: 1.4; color: #191919; white-space: pre-wrap; word-break: break-word; margin-bottom: 12px;"></div>
                    <?php if ( $img_url ) : ?>
                        <div class="mkm-dspb-preview-media" style="margin: 0 -12px 10px -12px; border-top: 1px solid #e5e5e5; background: #f7f9f9; overflow: hidden; display: flex; align-items: center; justify-content: center;">
                            <img src="<?php echo esc_url( $img_url ); ?>" style="width: 100%; height: auto; max-height: 420px; object-fit: contain; display: block;" />
                        </div>
                    <?php endif; ?>
                </div>
                <?php endif; ?>
            </div>
        </div>
        <?php
    }

    /**
     * Save metabox data (currently just custom text placeholder or meta settings if saved traditionally)
     */
    public function save_metabox_data( $post_id ) {
        if ( ! isset( $_POST['mkm_dspb_metabox_nonce'] ) ) {
            return;
        }
        if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['mkm_dspb_metabox_nonce'] ) ), 'mkm_dspb_metabox_action' ) ) {
            return;
        }
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return;
        }
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }

        // Save selected channels
        $channels = isset( $_POST['mkm_dspb_share_channels'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['mkm_dspb_share_channels'] ) ) : array();
        update_post_meta( $post_id, '_mkm_dspb_share_channels', $channels );

        // Save share now flag
        $share_now = isset( $_POST['mkm_dspb_share_now'] ) ? '1' : '0';
        update_post_meta( $post_id, '_mkm_dspb_share_now', $share_now );

        // Save per-network settings
        $settings = get_post_meta( $post_id, '_mkm_dspb_post_settings', true );
        if ( ! is_array( $settings ) ) {
            $settings = array();
        }

        if ( isset( $_POST['mkm_dspb_fb_text'] ) ) {
            $settings['facebook'] = array(
                'custom_text' => sanitize_textarea_field( wp_unslash( $_POST['mkm_dspb_fb_text'] ) ),
            );
        }
        if ( isset( $_POST['mkm_dspb_ig_text'] ) ) {
            $settings['instagram'] = array(
                'custom_text' => sanitize_textarea_field( wp_unslash( $_POST['mkm_dspb_ig_text'] ) ),
            );
        }
        if ( isset( $_POST['mkm_dspb_li_text'] ) ) {
            $settings['linkedin'] = array(
                'custom_text' => sanitize_textarea_field( wp_unslash( $_POST['mkm_dspb_li_text'] ) ),
            );
        }
        if ( isset( $_POST['mkm_dspb_gmb_text'] ) ) {
            $settings['googlebusiness'] = array(
                'custom_text' => isset( $_POST['mkm_dspb_gmb_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['mkm_dspb_gmb_text'] ) ) : '',
            );
        }
        if ( isset( $_POST['mkm_dspb_tw_text'] ) ) {
            $settings['twitter'] = array(
                'custom_text' => isset( $_POST['mkm_dspb_tw_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['mkm_dspb_tw_text'] ) ) : '',
            );
        }
        update_post_meta( $post_id, '_mkm_dspb_post_settings', $settings );
    }

    /**
     * Smartly extract a clean excerpt prioritizing SEO meta descriptions and sentence boundaries.
     */
    private function smart_extract_excerpt( $post, $max_len = 240 ) {
        // 1. Check SEO plugin descriptions
        $seo_desc = get_post_meta( $post->ID, '_yoast_wpseo_metadesc', true );
        if ( empty( $seo_desc ) ) {
            $seo_desc = get_post_meta( $post->ID, 'rank_math_description', true );
        }
        if ( empty( $seo_desc ) ) {
            $seo_desc = get_post_meta( $post->ID, '_aioseo_description', true );
        }
        if ( empty( $seo_desc ) ) {
            $seo_desc = get_post_meta( $post->ID, '_seopress_titles_desc', true );
        }

        if ( ! empty( $seo_desc ) ) {
            $clean_seo = mkm_dspb_html_to_social_text( $seo_desc );
            if ( ! empty( $clean_seo ) ) {
                return $clean_seo;
            }
        }

        // 2. Check explicit post excerpt
        if ( ! empty( $post->post_excerpt ) ) {
            $clean_excerpt = mkm_dspb_html_to_social_text( $post->post_excerpt );
            if ( ! empty( $clean_excerpt ) ) {
                return $clean_excerpt;
            }
        }

        // 3. Fallback: Smart sentence extraction from content
        $content = mkm_dspb_html_to_social_text( $post->post_content );
        if ( empty( $content ) ) {
            return '';
        }

        if ( mb_strlen( $content ) <= $max_len ) {
            return $content;
        }

        // Try extracting complete sentences (. ! ?)
        preg_match_all( '/.*?[.!?](?:\s+|$)/s', $content, $matches );
        if ( ! empty( $matches[0] ) ) {
            $extracted = '';
            foreach ( $matches[0] as $sentence ) {
                $candidate = trim( $extracted . ' ' . trim( $sentence ) );
                if ( mb_strlen( $candidate ) <= $max_len ) {
                    $extracted = $candidate;
                } else {
                    break;
                }
            }
            if ( ! empty( $extracted ) ) {
                return $extracted;
            }
        }

        // Fallback: stop at last word boundary
        $truncated  = mb_substr( $content, 0, $max_len - 3 );
        $last_space = mb_strrpos( $truncated, ' ' );
        if ( $last_space !== false && $last_space > 40 ) {
            $truncated = mb_substr( $truncated, 0, $last_space );
        }
        return trim( $truncated ) . '...';
    }

    /**
     * Get TinyURL shortlink with post meta caching
     */
    private function get_tinyurl_shortlink( $post_id, $post_url ) {
        if ( empty( $post_id ) || empty( $post_url ) ) {
            return $post_url;
        }

        $cached = get_post_meta( $post_id, '_mkm_dspb_tinyurl', true );
        if ( ! empty( $cached ) && strpos( $cached, 'tinyurl.com' ) !== false ) {
            return $cached;
        }

        $api_url  = 'https://tinyurl.com/api-create.php?url=' . urlencode( $post_url );
        $response = wp_remote_get( $api_url, array( 'timeout' => 5 ) );

        if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
            $short_url = trim( wp_remote_retrieve_body( $response ) );
            if ( ! empty( $short_url ) && strpos( $short_url, 'tinyurl.com' ) !== false ) {
                update_post_meta( $post_id, '_mkm_dspb_tinyurl', $short_url );
                return $short_url;
            }
        }

        $wp_short = wp_get_shortlink( $post_id );
        return ! empty( $wp_short ) ? $wp_short : $post_url;
    }

    /**
     * Resolve shortlink according to shortener provider setting
     */
    public function resolve_post_shortlink( $post ) {
        if ( ! $post ) {
            return '';
        }
        $provider  = get_option( 'mkm_dspb_shortener_provider', 'none' );
        $permalink = mkm_dspb_get_clean_permalink( $post->ID );

        if ( 'tinyurl' === $provider ) {
            return $this->get_tinyurl_shortlink( $post->ID, $permalink );
        } elseif ( 'wp_shortlink' === $provider ) {
            $wp_short = wp_get_shortlink( $post->ID );
            return ! empty( $wp_short ) ? $wp_short : $permalink;
        }

        $wp_short = wp_get_shortlink( $post->ID );
        return ! empty( $wp_short ) ? $wp_short : $permalink;
    }

    /**
     * Format the social post template with placeholders
     */
    private function format_post_template( $post, $service = '' ) {
        $template   = get_option( 'mkm_dspb_template', "{title}\n\n{excerpt}\n\n{link}" );
        $provider   = get_option( 'mkm_dspb_shortener_provider', 'none' );
        $title      = mkm_dspb_html_to_social_text( $post->post_title );
        $permalink  = mkm_dspb_get_clean_permalink( $post->ID );
        $shortlink  = $this->resolve_post_shortlink( $post );
        $is_twitter = ( 'twitter' === $service || 'tw' === $service );
        $link_url   = ( $is_twitter && 'none' !== $provider ) ? $shortlink : $permalink;
        $excerpt    = $this->smart_extract_excerpt( $post, 240 );

        // Get Yoast SEO description
        $yoast_desc = get_post_meta( $post->ID, '_yoast_wpseo_metadesc', true );
        $yoast_desc = mkm_dspb_html_to_social_text( $yoast_desc );

        // Get All in One SEO description
        $aioseo_desc = get_post_meta( $post->ID, '_aioseo_description', true );
        $aioseo_desc = mkm_dspb_html_to_social_text( $aioseo_desc );

        $replacements = array(
            '{title}'       => $title,
            '{excerpt}'     => $excerpt,
            '{link}'        => $link_url,
            '{shortlink}'   => $shortlink,
            '{yoast_desc}'  => ! empty( $yoast_desc ) ? $yoast_desc : $excerpt,
            '{aioseo_desc}' => ! empty( $aioseo_desc ) ? $aioseo_desc : $excerpt,
        );

        return $this->parse_template_text( $template, $replacements );
    }

    /**
     * Parse template text with tag replacements and sanitize common tag typos (#post_excerpt, {post_excerpt}, etc.)
     */
    public function parse_template_text( $text, $replacements ) {
        if ( empty( $text ) ) {
            return '';
        }

        // Clean up common user typos like #post_excerpt, #post_title, #post_link
        if ( false !== strpos( $text, '#post_excerpt' ) ) {
            if ( false !== strpos( $text, '{excerpt}' ) || false !== strpos( $text, '{post_excerpt}' ) ) {
                $text = str_replace( '#post_excerpt', '', $text );
            } else {
                $text = str_replace( '#post_excerpt', '{excerpt}', $text );
            }
        }
        if ( false !== strpos( $text, '#post_title' ) ) {
            if ( false !== strpos( $text, '{title}' ) || false !== strpos( $text, '{post_title}' ) ) {
                $text = str_replace( '#post_title', '', $text );
            } else {
                $text = str_replace( '#post_title', '{title}', $text );
            }
        }
        if ( false !== strpos( $text, '#post_link' ) ) {
            if ( false !== strpos( $text, '{link}' ) || false !== strpos( $text, '{post_link}' ) ) {
                $text = str_replace( '#post_link', '', $text );
            } else {
                $text = str_replace( '#post_link', '{link}', $text );
            }
        }

        // Map tag aliases
        $all_replacements = array_merge(
            $replacements,
            array(
                '{post_title}'   => isset( $replacements['{title}'] ) ? $replacements['{title}'] : '',
                '{post_excerpt}' => isset( $replacements['{excerpt}'] ) ? $replacements['{excerpt}'] : '',
                '{post_link}'    => isset( $replacements['{link}'] ) ? $replacements['{link}'] : '',
            )
        );

        $social_text = str_replace( array_keys( $all_replacements ), array_values( $all_replacements ), $text );
        $social_text = str_replace( array( '#post_excerpt', '#post_title', '#post_link', '{post_excerpt}', '{post_title}', '{post_link}' ), '', $social_text );
        return mkm_dspb_clean_social_text( $social_text );
    }

    /**
     * Mark a post to be auto-published after save_post and REST handlers finish saving all data
     */
    public function mark_for_auto_publish( $new_status, $old_status, $post ) {
        // Only run when publishing a post (transitioning to publish from another state)
        if ( 'publish' !== $new_status || 'publish' === $old_status ) {
            return;
        }

        // Check if post type is enabled
        $enabled_types = get_option( 'mkm_dspb_post_types', array( 'post' ) );
        if ( ! in_array( $post->post_type, $enabled_types, true ) ) {
            return;
        }

        // Guardrail: Do not auto-publish if title is empty or is an Auto-Draft
        $title_clean = trim( strip_tags( $post->post_title ) );
        $title_lower = strtolower( $title_clean );
        if ( '' === $title_clean || 'auto draft' === $title_lower || 'bozza automatica' === $title_lower ) {
            return;
        }

        // Check if already auto-published to avoid duplicate triggers
        if ( get_post_meta( $post->ID, '_mkm_dspb_published', true ) ) {
            return;
        }
        
        // Mark it and queue it for deferred execution
        update_post_meta( $post->ID, '_mkm_dspb_needs_publish', '1' );
        self::$pending_posts[ $post->ID ] = $post->ID;
    }

    /**
     * Queue post for publishing during save_post
     */
    public function queue_auto_publish( $post_id, $post = null ) {
        if ( wp_is_post_revision( $post_id ) ) {
            return;
        }

        $needs_publish = get_post_meta( $post_id, '_mkm_dspb_needs_publish', true );
        if ( $needs_publish ) {
            self::$pending_posts[ $post_id ] = $post_id;
        }
    }

    /**
     * Handle REST API requests after all post attributes and media have been inserted
     */
    public function process_rest_publish( $post, $request = null ) {
        $post_id = is_object( $post ) ? $post->ID : intval( $post );
        if ( $post_id ) {
            $needs_publish = get_post_meta( $post_id, '_mkm_dspb_needs_publish', true );
            if ( $needs_publish ) {
                self::$pending_posts[ $post_id ] = $post_id;
                $this->process_deferred_publishes();
            }
        }
    }

    /**
     * Smartly truncate text to 280 characters for Twitter / X, ending cleanly at sentence or word boundaries.
     */
    private function truncate_for_twitter( $text, $max_len = 280 ) {
        if ( mb_strlen( $text ) <= $max_len ) {
            return $text;
        }

        $url         = '';
        $text_before = $text;
        if ( preg_match( '/\s*(https?:\/\/[^\s]+)\s*$/i', $text, $matches ) ) {
            $url          = $matches[1];
            $url_pos      = mb_strrpos( $text, $url );
            $text_before  = trim( mb_substr( $text, 0, $url_pos ) );
            $url_len      = mb_strlen( $url );
            $available_text_len = $max_len - $url_len - 5;
        } else {
            $available_text_len = $max_len - 3;
        }

        if ( $available_text_len > 20 ) {
            $sub = mb_substr( $text_before, 0, $available_text_len );

            // Try to end at a sentence completion (. ! ?)
            $last_dot   = mb_strrpos( $sub, '.' );
            $last_excl  = mb_strrpos( $sub, '!' );
            $last_q     = mb_strrpos( $sub, '?' );
            $last_punct = max( (int) $last_dot, (int) $last_excl, (int) $last_q );

            if ( $last_punct !== false && $last_punct > 40 ) {
                $clean_text = mb_substr( $sub, 0, $last_punct + 1 );
                return $url ? ( $clean_text . "\n\n" . $url ) : $clean_text;
            }

            // Otherwise end at a word boundary
            $last_space = mb_strrpos( $sub, ' ' );
            if ( $last_space !== false && $last_space > 40 ) {
                $clean_text = mb_substr( $sub, 0, $last_space ) . '...';
                return $url ? ( $clean_text . "\n\n" . $url ) : $clean_text;
            }

            $clean_text = $sub . '...';
            return $url ? ( $clean_text . "\n\n" . $url ) : $clean_text;
        }

        return mb_substr( $text, 0, $max_len - 3 ) . '...';
    }

    /**
     * Backward compatibility wrapper for execute_auto_publish
     */
    public function execute_auto_publish( $post_id, $post = null ) {
        $this->queue_auto_publish( $post_id, $post );
    }

    /**
     * Process all queued posts at shutdown / end of request when all meta & terms are fully saved
     */
    public function process_deferred_publishes() {
        if ( empty( self::$pending_posts ) ) {
            return;
        }

        $posts_to_process    = self::$pending_posts;
        self::$pending_posts = array();

        foreach ( $posts_to_process as $post_id ) {
            $needs_publish = get_post_meta( $post_id, '_mkm_dspb_needs_publish', true );
            if ( ! $needs_publish ) {
                continue;
            }

            delete_post_meta( $post_id, '_mkm_dspb_needs_publish' );

            if ( get_post_meta( $post_id, '_mkm_dspb_published', true ) ) {
                continue;
            }

            $post = get_post( $post_id );
            if ( ! $post || 'publish' !== $post->post_status ) {
                continue;
            }

            $title_clean = trim( strip_tags( $post->post_title ) );
            $title_lower = strtolower( $title_clean );
            if ( '' === $title_clean || 'auto draft' === $title_lower || 'bozza automatica' === $title_lower ) {
                continue;
            }

            $this->do_publish_post( $post );
        }
    }

    /**
     * Handles automatic publication of a single validated post
     */
    private function do_publish_post( $post ) {
        $token    = get_option( 'mkm_dspb_token', '' );
        $saved_ch = get_post_meta( $post->ID, '_mkm_dspb_share_channels', true );
        $defaults = is_array( $saved_ch ) ? $saved_ch : get_option( 'mkm_dspb_default_channels', array() );
        $profiles = get_option( 'mkm_dspb_profiles', array() );
        
        $saved_now = get_post_meta( $post->ID, '_mkm_dspb_share_now', true );
        if ( $saved_now !== '' && $saved_now !== false ) {
            $share_now = ( $saved_now === '1' );
        } else {
            $share_now = ( get_option( 'mkm_dspb_publish_mode', 'addToQueue' ) === 'shareNow' );
        }

        if ( empty( $token ) || empty( $defaults ) || empty( $profiles ) ) {
            return;
        }

        // Load specific network settings
        $settings = get_post_meta( $post->ID, '_mkm_dspb_post_settings', true );

        // Extract media using multi-source fallback
        $media_urls = $this->get_post_media_urls( $post->ID );
        $media_url  = ! empty( $media_urls ) ? $media_urls[0] : '';

        $post_url  = mkm_dspb_get_clean_permalink( $post->ID );
        $errors    = array();
        $successes = 0;

        foreach ( $defaults as $chan_key ) {
            if ( isset( $profiles[ $chan_key ] ) ) {
                $chan    = $profiles[ $chan_key ];
                $service = $chan['service'];

                // Retrieve settings for this service type
                $custom_text = isset( $settings[ $service ]['custom_text'] ) ? $settings[ $service ]['custom_text'] : '';
                if ( ! empty( $custom_text ) ) {
                    $provider   = get_option( 'mkm_dspb_shortener_provider', 'none' );
                    $shortlink  = $this->resolve_post_shortlink( $post );
                    $is_twitter = ( 'twitter' === $service || 'tw' === $service );
                    $link_url   = ( $is_twitter && 'none' !== $provider ) ? $shortlink : $post_url;
                    $title      = mkm_dspb_html_to_social_text( $post->post_title );
                    $excerpt    = $this->smart_extract_excerpt( $post, 240 );
                    $yoast_desc = mkm_dspb_html_to_social_text( get_post_meta( $post->ID, '_yoast_wpseo_metadesc', true ) );
                    $aioseo_desc= mkm_dspb_html_to_social_text( get_post_meta( $post->ID, '_aioseo_description', true ) );

                    $replacements = array(
                        '{title}'       => $title,
                        '{excerpt}'     => $excerpt,
                        '{link}'        => $link_url,
                        '{shortlink}'   => $shortlink,
                        '{yoast_desc}'  => ! empty( $yoast_desc ) ? $yoast_desc : $excerpt,
                        '{aioseo_desc}' => ! empty( $aioseo_desc ) ? $aioseo_desc : $excerpt,
                    );
                    $copy = $this->parse_template_text( $custom_text, $replacements );
                } else {
                    $copy = $this->format_post_template( $post, $service );
                }
                $copy = mkm_dspb_clean_social_text( $copy );

                if ( 'twitter' === $service || 'tw' === $service ) {
                    $copy = $this->truncate_for_twitter( $copy, 280 );
                }

                $res = $this->api->publish_post( $token, $copy, $chan['id'], $service, $media_url, $share_now, '' );
                
                if ( is_wp_error( $res ) ) {
                    $err_msg = $res->get_error_message();
                    $errors[] = sprintf( '%s: %s', $chan['name'], $err_msg );
                } else {
                    $successes++;
                }
            }
        }

        // Save status meta
        update_post_meta( $post->ID, '_mkm_dspb_published', true );
        
        $log_data = array(
            'time'      => current_time( 'mysql' ),
            'successes' => $successes,
            'errors'    => $errors,
        );
        update_post_meta( $post->ID, '_mkm_dspb_log', $log_data );
    }

    /**
     * AJAX action handler for manual sharing
     */
    public function handle_manual_share_ajax() {
        check_ajax_referer( 'mkm_dspb_manual_share_nonce', 'nonce' );

        if ( ! current_user_can( 'edit_posts' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'mkmdigital-social-publisher-bridge' ) ) );
        }

        $post_id   = isset( $_POST['post_id'] ) ? intval( wp_unslash( $_POST['post_id'] ) ) : 0;
        $channels  = isset( $_POST['channels'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['channels'] ) ) : array();
        $share_now = isset( $_POST['share_now'] ) ? (intval( wp_unslash( $_POST['share_now'] ) ) === 1) : false;

        // Custom overrides per social network
        $fb_text   = isset( $_POST['fb_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['fb_text'] ) ) : '';
        $ig_text   = isset( $_POST['ig_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['ig_text'] ) ) : '';
        $li_text   = isset( $_POST['li_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['li_text'] ) ) : '';
        $gmb_text  = isset( $_POST['gmb_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['gmb_text'] ) ) : '';
        $tw_text   = isset( $_POST['tw_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['tw_text'] ) ) : '';

        $post = get_post( $post_id );
        if ( ! $post ) {
            wp_send_json_error( array( 'message' => __( 'Post not found.', 'mkmdigital-social-publisher-bridge' ) ) );
        }

        // Extract media using multi-source fallback
        $media_urls = $this->get_post_media_urls( $post->ID );
        $media_url  = ! empty( $media_urls ) ? $media_urls[0] : '';

        $token    = get_option( 'mkm_dspb_token', '' );
        $profiles = get_option( 'mkm_dspb_profiles', array() );

        if ( empty( $token ) ) {
            wp_send_json_error( array( 'message' => __( 'Access token is missing.', 'mkmdigital-social-publisher-bridge' ) ) );
        }

        $post_url  = mkm_dspb_get_clean_permalink( $post->ID );
        $errors    = array();
        $successes = 0;

        foreach ( $channels as $chan_key ) {
            if ( isset( $profiles[ $chan_key ] ) ) {
                $chan    = $profiles[ $chan_key ];
                $service = $chan['service'];

                // Select corresponding texts and comment settings
                if ( 'facebook' === $service ) {
                    $custom_text   = $fb_text;
                } elseif ( 'instagram' === $service ) {
                    $custom_text   = $ig_text;
                } elseif ( 'linkedin' === $service ) {
                    $custom_text   = $li_text;
                } elseif ( 'googlebusiness' === $service ) {
                    $custom_text   = $gmb_text;
                } elseif ( 'twitter' === $service ) {
                    $custom_text   = $tw_text;
                } else {
                    $custom_text   = '';
                }

                if ( ! empty( $custom_text ) ) {
                    $provider   = get_option( 'mkm_dspb_shortener_provider', 'none' );
                    $shortlink  = $this->resolve_post_shortlink( $post );
                    $is_twitter = ( 'twitter' === $service || 'tw' === $service );
                    $link_url   = ( $is_twitter && 'none' !== $provider ) ? $shortlink : $post_url;
                    $title      = mkm_dspb_html_to_social_text( $post->post_title );
                    $excerpt    = $this->smart_extract_excerpt( $post, 240 );
                    $yoast_desc = mkm_dspb_html_to_social_text( get_post_meta( $post->ID, '_yoast_wpseo_metadesc', true ) );
                    $aioseo_desc= mkm_dspb_html_to_social_text( get_post_meta( $post->ID, '_aioseo_description', true ) );

                    $replacements = array(
                        '{title}'       => $title,
                        '{excerpt}'     => $excerpt,
                        '{link}'        => $link_url,
                        '{shortlink}'   => $shortlink,
                        '{yoast_desc}'  => ! empty( $yoast_desc ) ? $yoast_desc : $excerpt,
                        '{aioseo_desc}' => ! empty( $aioseo_desc ) ? $aioseo_desc : $excerpt,
                    );
                    $copy = $this->parse_template_text( $custom_text, $replacements );
                } else {
                    $copy = $this->format_post_template( $post, $service );
                }
                $copy = mkm_dspb_clean_social_text( $copy );

                if ( 'twitter' === $service || 'tw' === $service ) {
                    $copy = $this->truncate_for_twitter( $copy, 280 );
                }

                $res = $this->api->publish_post( $token, $copy, $chan['id'], $service, $media_url, $share_now, '' );
                
                if ( is_wp_error( $res ) ) {
                    $err_msg = $res->get_error_message();
                    $errors[] = sprintf( '<strong>%s (%s)</strong>: %s', $chan['name'], ucfirst( $chan['service'] ), $err_msg );
                } else {
                    $successes++;
                }
            }
        }

        if ( $successes > 0 ) {
            // Update publish status
            update_post_meta( $post->ID, '_mkm_dspb_published', true );
            
            $log_data = array(
                'time'      => current_time( 'mysql' ),
                'successes' => $successes,
                'errors'    => $errors,
            );
            update_post_meta( $post->ID, '_mkm_dspb_log', $log_data );

            /* translators: %d: Number of channels successfully posted to */
            $msg = sprintf( __( 'Successfully sent to %d Buffer channel(s).', 'mkmdigital-social-publisher-bridge' ), $successes );
            if ( ! empty( $errors ) ) {
                $msg .= '<br/><span style="color:#d63638;">Errors:<br/>' . implode( '<br/>', $errors ) . '</span>';
            }
            wp_send_json_success( array( 'message' => $msg ) );
        } else {
            $msg = __( 'Failed to send to any Buffer channels.', 'mkmdigital-social-publisher-bridge' );
            if ( ! empty( $errors ) ) {
                $msg .= '<br/>' . implode( '<br/>', $errors );
            }
            wp_send_json_error( array( 'message' => $msg ) );
        }
    }

    /**
     * Get fallback media URL from plugin settings or site icon
     */
    public static function get_fallback_media_url() {
        $fallback_opt = get_option( 'mkm_dspb_fallback_image', '' );
        if ( ! empty( $fallback_opt ) ) {
            return self::get_compatible_media_url( $fallback_opt );
        }
        if ( function_exists( 'get_site_icon_url' ) && get_site_icon_url( 512 ) ) {
            return self::get_compatible_media_url( get_site_icon_url( 512 ) );
        }
        return '';
    }

    /**
     * Extract images from Gutenberg blocks recursively
     */
    public static function extract_images_from_blocks( $blocks, &$media_urls ) {
        if ( ! is_array( $blocks ) ) {
            return;
        }

        foreach ( $blocks as $block ) {
            if ( empty( $block['blockName'] ) ) {
                continue;
            }

            // Single image block
            if ( 'core/image' === $block['blockName'] ) {
                if ( ! empty( $block['attrs']['id'] ) ) {
                    $img_url = wp_get_attachment_image_url( $block['attrs']['id'], 'full' );
                    if ( ! empty( $img_url ) ) {
                        $media_urls[] = self::get_compatible_media_url( $img_url );
                    }
                } elseif ( ! empty( $block['attrs']['url'] ) ) {
                    $media_urls[] = self::get_compatible_media_url( $block['attrs']['url'] );
                }
            }

            // Gallery block
            if ( 'core/gallery' === $block['blockName'] && ! empty( $block['attrs']['ids'] ) ) {
                foreach ( $block['attrs']['ids'] as $attachment_id ) {
                    $img_url = wp_get_attachment_image_url( $attachment_id, 'full' );
                    if ( ! empty( $img_url ) ) {
                        $media_urls[] = self::get_compatible_media_url( $img_url );
                    }
                }
            }

            // Cover block
            if ( 'core/cover' === $block['blockName'] ) {
                if ( ! empty( $block['attrs']['id'] ) ) {
                    $img_url = wp_get_attachment_image_url( $block['attrs']['id'], 'full' );
                    if ( ! empty( $img_url ) ) {
                        $media_urls[] = self::get_compatible_media_url( $img_url );
                    }
                } elseif ( ! empty( $block['attrs']['url'] ) ) {
                    $media_urls[] = self::get_compatible_media_url( $block['attrs']['url'] );
                }
            }

            // Media & Text block
            if ( 'core/media-text' === $block['blockName'] ) {
                if ( ! empty( $block['attrs']['mediaId'] ) ) {
                    $img_url = wp_get_attachment_image_url( $block['attrs']['mediaId'], 'full' );
                    if ( ! empty( $img_url ) ) {
                        $media_urls[] = self::get_compatible_media_url( $img_url );
                    }
                } elseif ( ! empty( $block['attrs']['mediaUrl'] ) ) {
                    $media_urls[] = self::get_compatible_media_url( $block['attrs']['mediaUrl'] );
                }
            }

            // Recurse inner blocks
            if ( ! empty( $block['innerBlocks'] ) ) {
                self::extract_images_from_blocks( $block['innerBlocks'], $media_urls );
            }
        }
    }

    /**
     * Get all media URLs for a post with 6-level multi-source fallback:
     * 1. Featured image (Thumbnail ID & Post Thumbnail URL)
     * 2. SEO Plugins OpenGraph / Social Image metadata (AIOSEO, Yoast, Rank Math, SEOPress)
     * 3. Gutenberg blocks (core/image, core/gallery, core/cover, core/media-text)
     * 4. HTML <img> tags in content
     * 5. Attached media library images
     * 6. Site fallback image / Site icon
     */
    public static function get_post_media_urls( $post_id ) {
        $media_urls = array();

        // 1. Featured image
        if ( has_post_thumbnail( $post_id ) ) {
            $featured_url = get_the_post_thumbnail_url( $post_id, 'full' );
            if ( empty( $featured_url ) ) {
                $thumb_id = get_post_thumbnail_id( $post_id );
                if ( $thumb_id ) {
                    $featured_url = wp_get_attachment_image_url( $thumb_id, 'full' );
                }
            }
            if ( ! empty( $featured_url ) ) {
                $media_urls[] = self::get_compatible_media_url( $featured_url );
            }
        }

        // 2. SEO Plugins Social/OpenGraph Image Metadata
        // All in One SEO (AIOSEO)
        $aioseo_img = get_post_meta( $post_id, '_aioseo_og_image', true );
        if ( ! empty( $aioseo_img ) ) {
            $aioseo_url = is_numeric( $aioseo_img ) ? wp_get_attachment_image_url( intval( $aioseo_img ), 'full' ) : $aioseo_img;
            if ( ! empty( $aioseo_url ) ) {
                $media_urls[] = self::get_compatible_media_url( $aioseo_url );
            }
        }
        $aioseo_custom = get_post_meta( $post_id, '_aioseo_og_image_custom_url', true );
        if ( ! empty( $aioseo_custom ) ) {
            $media_urls[] = self::get_compatible_media_url( $aioseo_custom );
        }
        $aioseo_tw = get_post_meta( $post_id, '_aioseo_twitter_image', true );
        if ( ! empty( $aioseo_tw ) ) {
            $aioseo_tw_url = is_numeric( $aioseo_tw ) ? wp_get_attachment_image_url( intval( $aioseo_tw ), 'full' ) : $aioseo_tw;
            if ( ! empty( $aioseo_tw_url ) ) {
                $media_urls[] = self::get_compatible_media_url( $aioseo_tw_url );
            }
        }

        // Yoast SEO
        $yoast_img = get_post_meta( $post_id, '_yoast_wpseo_opengraph-image', true );
        if ( ! empty( $yoast_img ) ) {
            $media_urls[] = self::get_compatible_media_url( $yoast_img );
        }
        $yoast_img_id = get_post_meta( $post_id, '_yoast_wpseo_opengraph-image-id', true );
        if ( ! empty( $yoast_img_id ) ) {
            $yoast_url = wp_get_attachment_image_url( intval( $yoast_img_id ), 'full' );
            if ( ! empty( $yoast_url ) ) {
                $media_urls[] = self::get_compatible_media_url( $yoast_url );
            }
        }
        $yoast_tw = get_post_meta( $post_id, '_yoast_wpseo_twitter-image', true );
        if ( ! empty( $yoast_tw ) ) {
            $media_urls[] = self::get_compatible_media_url( $yoast_tw );
        }

        // Rank Math
        $rm_img = get_post_meta( $post_id, 'rank_math_facebook_image', true );
        if ( empty( $rm_img ) ) {
            $rm_img = get_post_meta( $post_id, 'rank_math_og_image', true );
        }
        if ( ! empty( $rm_img ) ) {
            $media_urls[] = self::get_compatible_media_url( $rm_img );
        }
        $rm_tw = get_post_meta( $post_id, 'rank_math_twitter_image', true );
        if ( ! empty( $rm_tw ) ) {
            $media_urls[] = self::get_compatible_media_url( $rm_tw );
        }

        // SEOPress
        $seopress_img = get_post_meta( $post_id, '_seopress_social_fb_img', true );
        if ( ! empty( $seopress_img ) ) {
            $media_urls[] = self::get_compatible_media_url( $seopress_img );
        }

        // 3. Content Blocks & Embedded Images
        $post = get_post( $post_id );
        if ( $post && ! empty( $post->post_content ) ) {
            if ( function_exists( 'has_blocks' ) && has_blocks( $post->post_content ) ) {
                $blocks = parse_blocks( $post->post_content );
                self::extract_images_from_blocks( $blocks, $media_urls );
            }

            // Classic HTML <img> fallback if still empty
            if ( empty( $media_urls ) ) {
                if ( preg_match_all( '/<img[^>]+src=[\'"]([^\'"]+)[\'"]/i', $post->post_content, $img_matches ) ) {
                    if ( ! empty( $img_matches[1] ) ) {
                        foreach ( $img_matches[1] as $img_src ) {
                            if ( ! empty( $img_src ) && 0 !== strpos( $img_src, 'data:' ) ) {
                                $media_urls[] = self::get_compatible_media_url( $img_src );
                            }
                        }
                    }
                }
            }
        }

        // 4. Attached Media in WordPress Media Library
        if ( empty( $media_urls ) ) {
            $attachments = get_attached_media( 'image', $post_id );
            if ( ! empty( $attachments ) ) {
                foreach ( $attachments as $att ) {
                    $att_url = wp_get_attachment_image_url( $att->ID, 'full' );
                    if ( ! empty( $att_url ) ) {
                        $media_urls[] = self::get_compatible_media_url( $att_url );
                        break;
                    }
                }
            }
        }

        // 5. Site Fallback Image / Site Icon
        if ( empty( $media_urls ) ) {
            $fallback = self::get_fallback_media_url();
            if ( ! empty( $fallback ) ) {
                $media_urls[] = $fallback;
            }
        }

        return array_values( array_unique( array_filter( $media_urls ) ) );
    }

    /**
     * If the media URL is a WebP or AVIF image, check if the original JPG/PNG exists
     * in the uploads directory and return its URL instead (since Google Business Profile rejects WebP/AVIF).
     */
    public static function get_compatible_media_url( $media_url ) {
        if ( empty( $media_url ) || ! is_string( $media_url ) ) {
            return '';
        }

        $final_url = trim( $media_url );

        // Extract pure path extension without query params
        $url_path = wp_parse_url( $final_url, PHP_URL_PATH );
        $ext      = $url_path ? pathinfo( $url_path, PATHINFO_EXTENSION ) : '';

        if ( in_array( strtolower( $ext ), array( 'webp', 'avif' ), true ) ) {
            $upload_dir = wp_upload_dir();
            $base_url   = $upload_dir['baseurl'];
            $base_dir   = $upload_dir['basedir'];

            // If the image is inside the WordPress uploads directory
            if ( 0 === strpos( $final_url, $base_url ) ) {
                $relative_path       = str_replace( $base_url, '', $final_url );
                $relative_path_clean = strtok( $relative_path, '?' );
                $local_path          = $base_dir . $relative_path_clean;

                // Extensions to look for
                $possible_exts = array( 'jpg', 'jpeg', 'png' );
                foreach ( $possible_exts as $p_ext ) {
                    // Test 1: replace the extension (e.g. image.webp -> image.jpg)
                    $test_path_1 = preg_replace( '/\.' . preg_quote( $ext, '/' ) . '$/i', '.' . $p_ext, $local_path );
                    if ( file_exists( $test_path_1 ) ) {
                        $final_url = preg_replace( '/\.' . preg_quote( $ext, '/' ) . '(\?|$)/i', '.' . $p_ext . '$1', $final_url );
                        break;
                    }

                    // Test 2: remove the extension if it was appended (e.g. image.jpg.webp -> image.jpg)
                    $test_path_2 = preg_replace( '/\.' . preg_quote( $ext, '/' ) . '$/i', '', $local_path );
                    $test_ext    = pathinfo( $test_path_2, PATHINFO_EXTENSION );
                    if ( in_array( strtolower( $test_ext ), $possible_exts, true ) && file_exists( $test_path_2 ) ) {
                        $final_url = preg_replace( '/\.' . preg_quote( $ext, '/' ) . '(\?|$)/i', '$1', $final_url );
                        break;
                    }
                }
            }
        }

        return self::encode_media_url( $final_url );
    }

    /**
     * Safely encode a media URL according to RFC 3986 so that non-ASCII characters
     * (such as emojis, accented characters, spaces, and special symbols) are percent-encoded
     * while preserving the host, scheme, and existing percent-encodings without double-encoding.
     *
     * @param string $url
     * @return string
     */
    public static function encode_media_url( $url ) {
        if ( empty( $url ) || ! is_string( $url ) ) {
            return $url;
        }

        $url    = trim( $url );
        $parsed = wp_parse_url( $url );
        if ( empty( $parsed['host'] ) || empty( $parsed['path'] ) ) {
            return esc_url_raw( $url );
        }

        $path_segments    = explode( '/', $parsed['path'] );
        $encoded_segments = array_map( function( $seg ) {
            return rawurlencode( rawurldecode( $seg ) );
        }, $path_segments );
        $new_path         = implode( '/', $encoded_segments );

        if ( 0 !== strpos( $new_path, '/' ) ) {
            $new_path = '/' . $new_path;
        }

        $scheme   = isset( $parsed['scheme'] ) ? $parsed['scheme'] . '://' : '//';
        $host     = isset( $parsed['host'] ) ? $parsed['host'] : '';
        $port     = isset( $parsed['port'] ) ? ':' . $parsed['port'] : '';
        $query    = isset( $parsed['query'] ) ? '?' . $parsed['query'] : '';
        $fragment = isset( $parsed['fragment'] ) ? '#' . $parsed['fragment'] : '';

        return $scheme . $host . $port . $new_path . $query . $fragment;
    }
    }
}
