<?php
namespace DiviBooster\Divi\Slide\Button2;

/**
 * Feature: Slide Second Button (Divi 4/5)
 * - Adds a second button to Slide module output.
 * - Registers Divi 4 fields and maps them to Divi 5 attributes.
 * - Provides Divi 5 builder attributes/groups and front-end styles.
 *
 * Note: Keep functionality identical; this pass applies small formatting and comments only.
 */

// === Constants ===
const DIVI4_SLIDE_SLUG = 'et_pb_slide';
const DIVI4_SLIDER_SLUG = 'et_pb_slider';
const DIVI4_FULLWIDTH_SLIDER_SLUG = 'et_pb_fullwidth_slider';
const DIVI5_SLIDE_SLUG = 'divi/slide';
const DIVI5_SLIDER_SLUG = 'divi/slider';
const DIVI5_FULLWIDTH_SLIDER_SLUG = 'divi/fullwidth-slider';
const DIVI5_SETTING_TEXT = 'diviboosterButton2Text';
const DIVI5_SETTING_LINK = 'diviboosterButton2Link';
const DIVI5_SETTING_BUTTON = 'diviboosterButton2Button';

// === Divi 5: PHP conversion outline registration ===
/**
 * Register conversion mapping for Divi 4 -> Divi 5 attributes.
 */
function dbdb_register_divi5_slide_button2_conversion( $conversion_outline, $module_name ) {
    $is_slide     = ( DIVI5_SLIDE_SLUG === $module_name );
    $is_slider    = ( DIVI5_SLIDER_SLUG === $module_name );
    $is_fw_slider = ( DIVI5_FULLWIDTH_SLIDER_SLUG === $module_name );
    if ( ! $is_slide && ! $is_slider && ! $is_fw_slider ) {
        return $conversion_outline;
    }
    if ( ! isset( $conversion_outline['module'] ) || ! is_array( $conversion_outline['module'] ) ) {
        $conversion_outline['module'] = array();
    }
    // Slide-only: map Divi 4 fields to Divi 5 attributes
    if ( $is_slide ) {
        $conversion_outline['module']['button_text_2'] = DIVI5_SETTING_TEXT . '.*';
        $conversion_outline['module']['button_link_2'] = DIVI5_SETTING_LINK . '.*';
    }
    // All: map Divi 4 "Use Custom Button Styles" toggle to Button 2 design attribute
    $conversion_outline['advanced']['button']['db_slide_button_2'] = DIVI5_SETTING_BUTTON;
    return $conversion_outline;
}
add_filter( 'divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\\dbdb_register_divi5_slide_button2_conversion', 10, 2 );

// === Divi 4: Field Registration ===
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_SLIDE_SLUG, __NAMESPACE__ . '\append_d4_fields');
/**
 * Append Divi 4 fields for Button 2 after the primary button fields.
 */
function append_d4_fields($fields) {
    if (!is_array($fields)) return $fields;
    $new = [];
    foreach ($fields as $k => $v) {
        $new[$k] = $v;
        if ($k === 'button_text') {
            $new['button_text_2'] = [
                'label'           => 'Button #2 Text',
                'type'            => 'text',
                'option_category' => 'basic_option',
                'description'     => 'Define the text for the second slide button.',
                'default'         => '',
                'toggle_slug'     => 'main_content',
            ];
        }
        if ($k === 'button_link') {
            $new['button_link_2'] = [
            /**
             * Register Button 2 design target for individual Slide modules.
             */
                'label'           => 'Button #2 Link URL',
                'type'            => 'text',
                'option_category' => 'basic_option',
                'description'     => 'Input a destination URL for the second slide button.',
                'default'         => '#',
                'toggle_slug'     => 'link_options',
            ];
        }
    }
    return $new;
            /**
             * Register Button 2 design target for Slider and Fullwidth Slider modules.
             */
}

// === Divi 4: Advanced Fields (Design) for Button 2 ===
add_filter(DIVI4_SLIDE_SLUG . '_advanced_fields', __NAMESPACE__ . '\d4_slide_button2_styles', 10, 3);
function d4_slide_button2_styles($fields, $slug, $main_css_element) {
    if (!is_array($fields)) return $fields;
    if (!isset($fields['button']) || !is_array($fields['button'])) $fields['button'] = [];
    $fields['button']['db_slide_button_2'] = [
        'css' => [
            'main'      => "div.et_pb_slides div.et_pb_slide{$main_css_element} a.et_pb_more_button.db_pb_button_2",
            'important' => 'all',
        ],
        'label'        => esc_html__('Button 2', 'et_builder'),
        'use_alignment'=> false,
    ];
    return $fields;
}

add_filter(DIVI4_SLIDER_SLUG . '_advanced_fields', __NAMESPACE__ . '\d4_slider_button2_styles', 10, 3);
add_filter(DIVI4_FULLWIDTH_SLIDER_SLUG . '_advanced_fields', __NAMESPACE__ . '\d4_slider_button2_styles', 10, 3);
function d4_slider_button2_styles($fields, $slug, $main_css_element) {
    if (!is_array($fields)) return $fields;
    if (!isset($fields['button']) || !is_array($fields['button'])) $fields['button'] = [];
    $fields['button']['db_slide_button_2'] = [
        'css' => [
            'main'      => "{$main_css_element} a.et_pb_more_button.db_pb_button_2",
            'important' => 'all',
        ],
        'label'        => esc_html__('Button 2', 'et_builder'),
        'use_alignment'=> false,
    ];
    return $fields;
}

// === Shared Helpers ===
/** Normalize a URL for the second button href. */
function canonicalize_url($url) {
    $url = is_string($url) ? trim($url) : '';
    if ($url === '') return $url;
    if (!parse_url($url, PHP_URL_SCHEME) && !in_array(substr($url, 0, 1), ['#', '/'], true)) {
        $url = 'http://' . $url;
    }
    return $url;
}

/** Extract the unique order class from slide markup for scoped CSS. */
function extract_order_class($html) {
    if (!is_string($html) || $html === '') return '';
    if (preg_match('/\bet_pb_slide_(\d+(?:_[a-z0-9_]+)?)\b/i', $html, $m)) {
        return 'et_pb_slide_' . $m[1];
    }
    return '';
}

/** Add a feature class to the slide wrapper to assist styling. */
function add_db_second_more_button_class($html) {
    // Add db_second_more_button to the slide wrapper element that already has class et_pb_slide
    return preg_replace(
        '/(<[^>]+class="[^"]*\bet_pb_slide\b)([^"]*)"/i',
        '$1 db_second_more_button$2"',
        $html,
        1
    );
}

/** Ensure CSS for button spacing is printed once per slide instance. */
function ensure_scoped_css_once(&$html, $order_class) {
    static $done = [];
    if (!$order_class || isset($done[$order_class])) return;
    $done[$order_class] = true;
    $css  = '.' . esc_attr($order_class) . '.db_second_more_button .et_pb_more_button{margin-left:15px;margin-right:15px;}';
    $css .= '@media only screen and ( min-width: 981px ) {';
    $css .= '.' . esc_attr($order_class) . '.db_second_more_button.et_pb_slide_with_image .et_pb_more_button:first-child{margin-left:0px;}';
    $css .= '.' . esc_attr($order_class) . '.db_second_more_button.et_pb_slide_with_image .et_pb_more_button:last-child{margin-right:0px;}';
    $css .= '}';
    $html .= '<style>' . $css . '</style>';
}

/** Apply a custom icon to Button 2 if enabled in Divi 4 props. */
function apply_button2_icon($html, $props) {
    $use    = isset($props['db_slide_button_2_use_icon']) ? $props['db_slide_button_2_use_icon'] : '';
    $icon   = isset($props['db_slide_button_2_icon']) ? $props['db_slide_button_2_icon'] : '';
    if ($icon === '') return $html;
    $should_apply = ($use === 'on');
    if (! $should_apply) return $html;
    if (function_exists('et_pb_process_font_icon')) {
        $icon_code = et_pb_process_font_icon($icon);
        // Replace existing data-icon value if present on Button 2
        if (preg_match('#<a[^>]+class="[^"]*db_pb_button_2[^"]*"[^>]+data-icon="([^"]+)"[^>]*>#i', $html, $matches)) {
            $html = str_replace($matches[0], str_replace($matches[1], $icon_code, $matches[0]), $html);
        } else {
            // Insert data-icon attribute if not present
            $html = preg_replace('#(<a[^>]+class="[^"]*db_pb_button_2[^"]*"[^>]*)(>)#i', '$1 data-icon="' . esc_attr($icon_code) . '"$2', $html, 1);
        }
    }
    return $html;
}

/** Inject the second button anchor into the slide markup. */
function inject_button2($html, $text, $url, $props = []) {
    if (!is_string($html) || trim((string)$text) === '') return $html;
    if (strpos($html, 'db_pb_button_2') !== false) return $html; // already injected

    $text = str_replace('$', '&#36;', (string)$text);
    $url  = canonicalize_url((string)$url);

    // Add feature class to slide wrapper
    $html = add_db_second_more_button_class($html);

    $replaced = $html;

    // Attempt old Divi markup: href first
    $replaced = preg_replace(
        '#(<a href=".*?" class="(et_pb_more_button[^"]+et_pb_button[^"]*)"([^>]*)>.*?</a>)#i',
        '$1<a href="' . esc_attr($url) . '" class="$2 db_pb_button_2"$3>' . esc_html($text) . '</a>',
        $replaced,
        1
    );

    if ($replaced === $html) {
        // Attempt newer Divi markup: class first
        $replaced = preg_replace(
            '#(<a class="(et_pb_button[^"]+et_pb_more_button[^"]*)" href=".*?"([^>]*)>.*?</a>)#i',
            '$1<a class="$2 db_pb_button_2" href="' . esc_attr($url) . '"$3>' . esc_html($text) . '</a>',
            $replaced,
            1
        );
    }

    if ($replaced !== $html) {
        $html = $replaced;
        // Apply icon if configured (Divi 4 props only)
        $html = apply_button2_icon($html, is_array($props) ? $props : []);
        // Inject scoped CSS once per slide instance
        $order_class = extract_order_class($html);
        if ($order_class) ensure_scoped_css_once($html, $order_class);
    }

    return $html;
}

// === Divi 4: Frontend Output Filter ===
add_filter('et_module_shortcode_output', function($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_SLIDE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }
    $props = $module->props;
    $text  = isset($props['button_text_2']) ? $props['button_text_2'] : '';
    $link  = isset($props['button_link_2']) ? $props['button_link_2'] : '';

    // Only inject when a primary button exists: try to detect primary button anchor quickly
    if (!preg_match('#<a[^>]+class="[^"]*\bet_pb_more_button\b[^"]*"#i', $output)) {
        return $output; // no primary button, skip
    }

    return inject_button2($output, $text, $link, $props);
}, 10, 3);

// === Divi 5: Attribute Registration (PHP, front-end) ===
if (function_exists('add_filter')) {
    add_filter('block_type_metadata_settings', function($settings) {
        $module_name      = $settings['name'] ?? '';
        $module_attributes = $settings['attributes'] ?? false;
        if ($module_name !== DIVI5_SLIDE_SLUG && $module_name !== DIVI5_SLIDER_SLUG && $module_name !== DIVI5_FULLWIDTH_SLIDER_SLUG) {
            return $settings;
        }
        if (!$module_attributes) {
            return $settings;
        }
        // Register Button 2 attributes for Divi 5 front-end
        if ($module_name === DIVI5_SLIDE_SLUG) {
            $settings['attributes'][DIVI5_SETTING_TEXT]   = get_d5_text_attribute_definition();
            $settings['attributes'][DIVI5_SETTING_LINK]   = get_d5_link_attribute_definition();
            $settings['attributes'][DIVI5_SETTING_BUTTON] = get_d5_button_attribute_definition();
        } else {
            // Slider and fullwidth slider: only design attribute
            $settings['attributes'][DIVI5_SETTING_BUTTON] = get_d5_slider_button_attribute_definition();
        }
        return $settings;
    });
}

/** Divi 5 attribute definition: text field (Button #2 Text). */
function get_d5_text_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'button2Text' => [
                        'groupSlug'   => 'contentText',
                        'attrName'    => DIVI5_SETTING_TEXT,
                        'label'       => 'Button 2',
                        'description' => 'Define the text for the second slide button.',
                        'features'    => [ 'hover' => false, 'sticky' => false, 'responsive' => false, 'preset' => 'content' ],
                        'render'      => true,
                        'priority'    => 11,
                        'component'   => [ 'type' => 'field', 'name' => 'divi/text' ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => '' ] ],
                    ],
                ],
            ],
        ],
    ];
}

/** Divi 5 attribute definition: link field (Button #2 Link URL). */
function get_d5_link_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'button2Link' => [
                        'groupSlug'   => 'contentLink',
                        'attrName'    => DIVI5_SETTING_LINK,
                        'label'       => 'Button 2 Link URL',
                        'description' => 'Input a destination URL for the second slide button.',
                        'features'    => [ 'hover' => false, 'sticky' => false, 'responsive' => false, 'preset' => 'content' ],
                        'render'      => true,
                        'priority'    => 11,
                        'component'   => [ 'type' => 'field', 'name' => 'divi/text' ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => '#' ] ],
                    ],
                ],
            ],
        ],
    ];
}

/** Divi 5 attribute definition: button design group (Button 2 styles). */
function get_d5_button_attribute_definition() {
    return [
        'type'       => 'object',
        // Target Button 2 element inside the Slide
    // Increase slide-level specificity slightly (duplicate order class)
    'selector'   => '{{selector}}.et_pb_slide a.et_pb_more_button.db_pb_button_2, body #page-container {{selector}}.et_pb_slide a.et_pb_more_button.db_pb_button_2, {{selector}}{{selector}}.et_pb_slide a.et_pb_more_button.db_pb_button_2, body #page-container {{selector}}{{selector}}.et_pb_slide a.et_pb_more_button.db_pb_button_2',
        'styleProps' => [ 'spacing' => [ 'important' => true ] ],
        'settings'   => [
            'decoration' => [
                'button' => [
                    'groupType' => 'group-item',
                    'item'      => [
                        'groupSlug' => 'designButton2',
                        'priority'  => 10,
                        'render'    => true,
                        'component' => [
                            'type' => 'group',
                            'name' => 'divi/button',
                            'props' => [
                                'grouped'    => false,
                                'fieldLabel' => 'Button 2',
                                'attrName'   => DIVI5_SETTING_BUTTON
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ];
}

/** Divi 5 attribute definition: slider-level button design group (all slides). */
function get_d5_slider_button_attribute_definition() {
    return [
        'type'       => 'object',
        // Target Button 2 elements inside all child Slides of the Slider
        'selector'   => '{{selector}} .et_pb_slide a.et_pb_more_button.db_pb_button_2, body #page-container {{selector}} .et_pb_slide a.et_pb_more_button.db_pb_button_2',
        'styleProps' => [ 'spacing' => [ 'important' => true ] ],
        'settings'   => [
            'decoration' => [
                'button' => [
                    'groupType' => 'group-item',
                    'item'      => [
                        'groupSlug' => 'designButton2',
                        'priority'  => 10,
                        'render'    => true,
                        'component' => [
                            'type' => 'group',
                            'name' => 'divi/button',
                            'props' => [
                                'grouped'    => false,
                                'fieldLabel' => 'Button 2',
                                'attrName'   => DIVI5_SETTING_BUTTON
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ];
}

// === Divi 5: Frontend Output Filter ===
add_filter('render_block_' . DIVI5_SLIDE_SLUG, function($block_content, $parsed_block, $block) {
    $attrs = $parsed_block['attrs'] ?? [];
    $text  = '';
    $link  = '';
    if (isset($attrs[DIVI5_SETTING_TEXT]['desktop']['value'])) $text = $attrs[DIVI5_SETTING_TEXT]['desktop']['value'];
    elseif (isset($attrs[DIVI5_SETTING_TEXT]['value'])) $text = $attrs[DIVI5_SETTING_TEXT]['value'];
    if (isset($attrs[DIVI5_SETTING_LINK]['desktop']['value'])) $link = $attrs[DIVI5_SETTING_LINK]['desktop']['value'];
    elseif (isset($attrs[DIVI5_SETTING_LINK]['value'])) $link = $attrs[DIVI5_SETTING_LINK]['value'];

    // Only inject when a primary button exists
    if (!preg_match('#<a[^>]+class="[^"]*\bet_pb_more_button\b[^"]*"#i', $block_content)) {
        return $block_content;
    }

    return inject_button2($block_content, $text, $link, []);
}, 10, 3);

// === Divi 5: JS Attribute Registration + Groups (Builder only) ===
// Enqueue for front-end/VB and also early in VB assets to ensure attributes register before UI renders
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_d5_script');
add_action('divi_visual_builder_assets_before_enqueue_scripts', __NAMESPACE__ . '\enqueue_d5_script');
/** Enqueue minimal inline JS to register attributes and settings groups in VB. */
function enqueue_d5_script() {
    if ((!function_exists('et_builder_d5_enabled') || !\et_builder_d5_enabled()) || (!function_exists('et_core_is_fb_enabled') || !\et_core_is_fb_enabled())) {
        return;
    }
    $handle = sanitize_title('divibooster-d5-slide-button2');
    wp_register_script($handle, '', ['lodash', 'divi-vendor-wp-hooks'], null, true);
    wp_enqueue_script($handle);
    wp_add_inline_script($handle, get_d5_inline_js());
}

/** Return inline JS used to register attributes and groups in the Divi 5 builder. */
function get_d5_inline_js() {
    $defText = wp_json_encode(get_d5_text_attribute_definition());
    $defLink = wp_json_encode(get_d5_link_attribute_definition());
    $defBtn  = wp_json_encode(get_d5_button_attribute_definition());
    $defBtnSlider = wp_json_encode(get_d5_slider_button_attribute_definition());
    $attrHook = wp_json_encode('divi.moduleLibrary.moduleAttributes.divi.slide');
    $attrHookSlider = wp_json_encode('divi.moduleLibrary.moduleAttributes.divi.slider');
    $attrHookFullwidth = wp_json_encode('divi.moduleLibrary.moduleAttributes.divi.fullwidth-slider');
    $groupHook = wp_json_encode('divi.moduleLibrary.moduleSettings.groups.divi.slide');
    $groupHookSlider = wp_json_encode('divi.moduleLibrary.moduleSettings.groups.divi.slider');
    $groupHookFullwidth = wp_json_encode('divi.moduleLibrary.moduleSettings.groups.divi.fullwidth-slider');
    $d5Text  = wp_json_encode(DIVI5_SETTING_TEXT);
    $d5Link  = wp_json_encode(DIVI5_SETTING_LINK);
    $d5Btn   = wp_json_encode(DIVI5_SETTING_BUTTON);
    return <<<JS
(function(){
  const hooks = window.vendor && window.vendor.wp && window.vendor.wp.hooks; if (!hooks) return;
  const { addFilter } = hooks;
    // Ensure Button 2 groups exist
    addFilter({$groupHook}, 'divi', (groups) => {
        groups.designButton2 = groups.designButton2 || {
            groupName:     'designButton2',
            panel:         'design',
            priority:      71,
            multiElements: true,
            component:     { name: 'divi/composite', props: { groupLabel: 'Button 2' } },
        };
        return groups;
    });
    // Slider-level groups
    addFilter({$groupHookSlider}, 'divi', (groups) => {
        groups.designButton2 = groups.designButton2 || {
            groupName:     'designButton2',
            panel:         'design',
            priority:      60,
            multiElements: true,
            component:     { name: 'divi/composite', props: { groupLabel: 'Button 2' } },
        };
        return groups;
    });
    addFilter({$groupHookFullwidth}, 'divi', (groups) => {
        groups.designButton2 = groups.designButton2 || {
            groupName:     'designButton2',
            panel:         'design',
            priority:      60,
            multiElements: true,
            component:     { name: 'divi/composite', props: { groupLabel: 'Button 2' } },
        };
        return groups;
    });
  // Register custom attributes for divi/slide
  addFilter({$attrHook}, 'divi', (attributes, metadata) => {
      attributes[{$d5Text}] = {$defText};
      attributes[{$d5Link}] = {$defLink};
            // Button 2 design attribute (divi/button group)
            attributes[{$d5Btn}]  = {$defBtn};
      return attributes;
  });
  // Slider-level attribute registration (design only)
  addFilter({$attrHookSlider}, 'divi', (attributes) => {
      attributes[{$d5Btn}] = {$defBtnSlider};
      return attributes;
  });
  addFilter({$attrHookFullwidth}, 'divi', (attributes) => {
      attributes[{$d5Btn}] = {$defBtnSlider};
      return attributes;
  });

  // Ensure global builder spacing CSS is present so margins persist in all VB contexts
  (function ensureGlobalSpacing(){
      const id = 'dbdb-button2-global-spacing';
      const add = () => {
          if (document.getElementById(id)) return;
          const css = '.et_pb_slide .et_pb_more_button{margin-left:15px;margin-right:15px;}';
          const style = document.createElement('style');
          style.id = id;
          style.appendChild(document.createTextNode(css));
          document.head && document.head.appendChild(style);
      };
      if (document.readyState === 'loading') {
          document.addEventListener('DOMContentLoaded', add, { once: true });
      } else {
          add();
      }
  })();

        // Render Second Button in Visual Builder preview and apply its styles
        addFilter('divi.module.wrapper.render', 'divi', (moduleWrapper, param) => {
            const { name: moduleName, attrs: moduleAttrs, elements: moduleElements, state: moduleState } = param || {};
            if ('divi/slide' !== moduleName) return moduleWrapper;

            // Helpers
            const el     = window.vendor?.wp?.element?.createElement;
            const clone  = window.vendor?.wp?.element?.cloneElement;
            const Mod    = window.divi?.module || {};
            const SC     = Mod.StyleContainer;
                if (!el || !clone) return moduleWrapper;

                // Prepare children array and remove any previously injected elements (idempotent)
                const INJECTED_KEYS = new Set(['dbdb-button2-styles', 'dbdb-button2-wrapper', 'dbdb-button2-spacing']);
                const baseChildren = moduleWrapper?.props?.children;
                const filteredChildren = Array.isArray(baseChildren)
                    ? baseChildren.filter((c) => !c || !INJECTED_KEYS.has(c.key))
                    : (baseChildren ? (INJECTED_KEYS.has(baseChildren.key) ? [] : [baseChildren]) : []);

            // Extract text/link from attributes (mirror PHP resolution order)
            const textAttr = moduleAttrs?.[{$d5Text}] || {};
            const linkAttr = moduleAttrs?.[{$d5Link}] || {};
            const getVal = (attr) => {
                if (!attr || typeof attr !== 'object') return '';
                if (attr.desktop && typeof attr.desktop.value !== 'undefined') return String(attr.desktop.value || '');
                if (typeof attr.value !== 'undefined') return String(attr.value || '');
                return '';
            };
            const btnText = getVal(textAttr);
            const btnHref = getVal(linkAttr) || '#';

                // If no text, return wrapper without any previously injected Button 2 elements
                if (!btnText.trim()) {
                    return clone(moduleWrapper, {}, filteredChildren);
                }

                // Require moduleElements and StyleContainer to append styles/button
                if (!SC || !moduleElements) {
                    return clone(moduleWrapper, {}, filteredChildren);
                }

            // Additional styles for the Button 2 design attribute
            const isEdited = !!(moduleWrapper && moduleWrapper.props && moduleWrapper.props.isEdited);
            const additionalStyles = el(
                SC,
                { key: 'dbdb-button2-styles', mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false },
                moduleElements.style({ attrName: {$d5Btn} })
            );

            // Render the button anchor (will be moved into the primary wrapper once available)
            const btn = el('a', { className: 'et_pb_button et_pb_more_button db_pb_button_2', href: btnHref }, btnText);

            // Placeholder wrapper to hold the button temporarily; hidden to avoid flash before move
            const wrappedBtn = el('div', { key: 'dbdb-button2-wrapper', 'data-dbdb-button2-wrapper': '1', style: { display: 'none' } }, btn);

                    // Schedule a move into the main button wrapper with retries (to handle delayed primary button render)
                    const scheduleMove = () => {
                        const RETRY_MAX = 12; // < ~1s
                        const RETRY_DELAY = 80;
                        const tryMoveAll = () => {
                            const placeholders = document.querySelectorAll('div[data-dbdb-button2-wrapper]');
                            placeholders.forEach((el) => {
                                const attempts = parseInt(el.getAttribute('data-dbdb-attempts') || '0', 10);
                                const anchor = el.querySelector('a.db_pb_button_2');
                                if (!anchor) { el.remove(); return; }
                                const slide = el.closest('.et_pb_slide');
                                if (!slide) { el.remove(); return; }
                                const wrappers = slide.querySelectorAll('.et_pb_button_wrapper');
                                let target = null;
                                for (let i = 0; i < wrappers.length; i++) {
                                    const w = wrappers[i];
                                    if (w.querySelector('.et_pb_more_button:not(.db_pb_button_2)')) { target = w; break; }
                                }
                                            if (target) {
                                    // Remove any previously moved Button 2 to avoid duplicates
                                    const existing = target.querySelectorAll('a.db_pb_button_2');
                                    existing.forEach((e) => { if (e !== anchor) e.remove(); });
                                    target.appendChild(anchor);
                                                // Mark slide so spacing CSS can target it (mirrors front-end helper)
                                                slide.classList.add('db_second_more_button');
                                    // Show now that it's placed and remove placeholder
                                    el.remove();
                                } else if (attempts < RETRY_MAX) {
                                    el.setAttribute('data-dbdb-attempts', String(attempts + 1));
                                    setTimeout(tryMoveAll, RETRY_DELAY);
                                } else {
                                    // Give up: remove placeholder to avoid stray hidden nodes
                                    el.remove();
                                }
                            });
                        };
                        setTimeout(tryMoveAll, 0);
                    };
                    scheduleMove();

                        // Scoped spacing CSS to mimic front-end margins between buttons
                        const spacingStyle = el('style', { key: 'dbdb-button2-spacing' }, '.et_pb_slide.db_second_more_button .et_pb_more_button{margin-left:15px;margin-right:15px;}');

                        // Append styles + button to current wrapper children (after filtering duplicates)
                    return clone(moduleWrapper, {}, [
                    ...filteredChildren,
                            spacingStyle,
                additionalStyles,
                wrappedBtn,
            ]);
        });

                // Append slider-level styles in VB so global Button 2 styles apply across slides
                addFilter('divi.module.wrapper.render', 'divi', (moduleWrapper, param) => {
                        const { name: moduleName, elements: moduleElements, state: moduleState } = param || {};
                        if (moduleName !== 'divi/slider' && moduleName !== 'divi/fullwidth-slider') return moduleWrapper;
                        const el    = window.vendor?.wp?.element?.createElement;
                        const clone = window.vendor?.wp?.element?.cloneElement;
                        const Mod   = window.divi?.module || {};
                        const SC    = Mod.StyleContainer;
                        if (!el || !clone || !SC || !moduleElements) return moduleWrapper;
                        const baseChildren = moduleWrapper?.props?.children;
                        const filteredChildren = Array.isArray(baseChildren)
                            ? baseChildren.filter((c) => !c || c.key !== 'dbdb-button2-slider-styles')
                            : (baseChildren ? (baseChildren.key === 'dbdb-button2-slider-styles' ? [] : [baseChildren]) : []);
                        const isEdited = !!(moduleWrapper && moduleWrapper.props && moduleWrapper.props.isEdited);
                        const styles = el(
                            SC,
                            { key: 'dbdb-button2-slider-styles', mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false },
                            moduleElements.style({ attrName: {$d5Btn} })
                        );
                        return clone(moduleWrapper, {}, [ ...filteredChildren, styles ]);
                });
})();
JS;
}

// === Divi 5: Front-end style injection (Button 2 design attribute) ===
/**
 * Inject styles for the Button 2 design attribute in the front-end render pipeline.
 */
function filter_wrapper_render_styles( $module_wrapper, $args ): string {
    $module_id            = $args['id'] ?? '';
    $module_name          = $args['name'] ?? '';
    $module_order_index   = $args['orderIndex'] ?? 0;
    $module_store_instance= $args['storeInstance'] ?? 0;
    $module_elements      = $args['elements'] ?? null;

    $is_slide     = ( DIVI5_SLIDE_SLUG === $module_name );
    $is_slider    = ( defined('DiviBooster\\Divi\\Slide\\Button2\\DIVI5_SLIDER_SLUG') && DIVI5_SLIDER_SLUG === $module_name );
    $is_fw_slider = ( defined('DiviBooster\\Divi\\Slide\\Button2\\DIVI5_FULLWIDTH_SLIDER_SLUG') && DIVI5_FULLWIDTH_SLIDER_SLUG === $module_name );
    if ( ! $is_slide && ! $is_slider && ! $is_fw_slider ) {
        return $module_wrapper;
    }

    // Guard against unexpected element structure.
    if ( ! is_object( $module_elements ) || ! method_exists( $module_elements, 'style' ) ) {
        return $module_wrapper;
    }

    // Add the appropriate styles for the current module (slide: slide-level; slider/fullwidth: slider-level)
    \ET\Builder\FrontEnd\Module\Style::add([
        'id'            => $module_id,
        'name'          => $module_name,
        'orderIndex'    => $module_order_index,
        'storeInstance' => $module_store_instance,
        'styles'        => [
            $module_elements->style([
                'attrName' => DIVI5_SETTING_BUTTON,
            ]),
        ],
    ]);

    return $module_wrapper;
}

add_filter('divi_module_wrapper_render', __NAMESPACE__ . '\\filter_wrapper_render_styles', 10, 2);


// Created at 1760416436.