<?php

namespace DiviBooster\GalleryBooster\DotNavigationStyles;

// === Constants ===
const DIVI4_MODULE_SLUG = 'et_pb_gallery';
const DIVI5_MODULE_SLUG = 'divi/gallery';

// Divi 4 field slugs (must not change)
const D4_INACTIVE_COLOR = 'dbdb_dot_nav_color_inactive';
const D4_ACTIVE_COLOR   = 'dbdb_dot_nav_color_active';
const D4_SIZE           = 'dbdb_dot_nav_size';

// Divi 5 attribute slugs
const D5_ATTR_INACTIVE  = 'diviboosterDotNavColorInactive';
const D5_ATTR_ACTIVE    = 'diviboosterDotNavColorActive';
const D5_ATTR_SIZE      = 'diviboosterDotNavSize';
const D5_ATTR_BORDER    = 'diviboosterDotNavBorder';
const D5_ATTR_SHADOW    = 'diviboosterDotNavShadow';

// Advanced group slug used in Divi 4 to hold fields
const D4_ADV_GROUP_SLUG = 'dbdb_dot_navigation';

// === Hooks Registration ===
if (function_exists('add_filter')) {
    // Divi 4: Fields and output
    \add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\\add_field');
    \add_filter('et_pb_gallery_advanced_fields', __NAMESPACE__ . '\\add_advanced_fields', 10, 3);
    \add_filter('et_module_shortcode_output', __NAMESPACE__ . '\\divi4_output', 10, 3);

    // Divi 5: Register custom attributes in block metadata (front-end + builder)
    \add_filter('block_type_metadata_settings', __NAMESPACE__ . '\\register_divi5_attributes');

    // Divi 5: Conversion outline (PHP fallback for migration + runtime)
    \add_filter('divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\\register_divi5_conversion_outline', 10, 2);

    // Divi 5: Front-end and builder style printing via Style::add
    \add_filter('divi_module_wrapper_render', __NAMESPACE__ . '\\divi5_style_add', 10, 2);

    // Divi 5: Rendered block post-processing (fallback per-instance CSS)
    \add_filter('render_block_' . DIVI5_MODULE_SLUG, __NAMESPACE__ . '\\divi5_output', 10, 3);
}

if (function_exists('add_action')) {
    // Divi 5: VB-only JS for attribute + group + conversion mapping + builder styles
    \add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_divi5_vb_js');
}

// === Divi 4: Add option fields ===
function add_field($fields) {
    if (!is_array($fields)) {
        return $fields;
    }

    $new_fields = array(
        D4_INACTIVE_COLOR    => array(
            'label'            => esc_html__('Dot Navigation Inactive Color', 'divi-gallery-booster'),
            'type'             => 'color-alpha',
            'option_category'  => 'configuration',
            'default'          => '',
            'tab_slug'         => 'advanced',
            'toggle_slug'      => D4_ADV_GROUP_SLUG,
            'description'      => esc_html__('Choose the inactive dot color for the navigation dots at the bottom of the slider.', 'divi-gallery-booster'),
            'show_if'          => array(
                'fullwidth' => 'on',
            ),
        ),
        D4_ACTIVE_COLOR      => array(
            'label'            => esc_html__('Dot Navigation Active Color', 'divi-gallery-booster'),
            'type'             => 'color-alpha',
            'option_category'  => 'configuration',
            'default'          => '',
            'tab_slug'         => 'advanced',
            'toggle_slug'      => D4_ADV_GROUP_SLUG,
            'description'      => esc_html__('Choose the active dot color for the navigation dots at the bottom of the slider.', 'divi-gallery-booster'),
            'show_if'          => array(
                'fullwidth' => 'on',
            ),
        ),
        D4_SIZE              => array(
            'label'            => esc_html__('Dot Navigation Size', 'divi-gallery-booster'),
            'type'             => 'range',
            'option_category'  => 'configuration',
            'default'          => '7px',
            'default_unit'     => 'px',
            'default_on_front' => '',
            'range_settings'   => array(
                'min'  => '1',
                'max'  => '120',
                'step' => '1',
            ),
            'allowed_units'    => array('%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw'),
            'tab_slug'         => 'advanced',
            'toggle_slug'      => D4_ADV_GROUP_SLUG,
            'description'      => esc_html__('Choose the size of the navigation dots at the bottom of the slider.', 'divi-gallery-booster'),
            'show_if'          => array(
                'fullwidth' => 'on',
            ),
        ),
    );

    // Prepend to keep compatibility with original behavior
    return array_merge($new_fields, $fields);
}

// === Divi 4: Advanced fields (fonts group placeholder + borders) ===
function add_advanced_fields($fields, $slug, $main_css_element) {
    if (!is_array($fields)) {
        return $fields;
    }

    if (!isset($fields['fonts']) || !is_array($fields['fonts'])) {
        $fields['fonts'] = array();
    }

    $fields['fonts'][D4_ADV_GROUP_SLUG] = array(
        'label'               => esc_html__('Dot Navigation', 'divi-booster'),
        'hide_text_color'     => true,
        'hide_font_size'      => true,
        'hide_text_shadow'    => true,
        'hide_text_align'     => true,
        'hide_font'           => true,
        'hide_line_height'    => true,
        'hide_letter_spacing' => true,
    );

    if (!isset($fields['borders'])) {
        $fields['borders'] = array();
    }

    $fields['borders']['dot_navigation'] = array(
        'css'      => array(
            'main' => array(
                'border_styles' => "{$main_css_element} div.et-pb-controllers a",
                'border_radii'  => "div{$main_css_element} div.et-pb-controllers a",
            ),
            'important' => 'all',
        ),
        'defaults' => array(
            'border_radii'  => 'on|50%|50%|50%|50%',
            'border_styles' => array(
                'width' => '0px',
                'color' => '#333333',
                'style' => 'solid',
            ),
        ),
        'tab_slug'   => 'advanced',
        'toggle_slug'=> D4_ADV_GROUP_SLUG,
        'show_if'    => array(
            'fullwidth' => 'on',
        ),
    );

    // Add box shadow controls for dot navigation
    if (!isset($fields['box_shadow'])) {
        $fields['box_shadow'] = array();
    }
    $fields['box_shadow']['dot_navigation'] = array(
        'css' => array(
            'main' => "%%order_class%% .et-pb-controllers a",
            'important' => 'all',
        ),
        'tab_slug'    => 'advanced',
        'toggle_slug' => D4_ADV_GROUP_SLUG,
        'show_if'     => array(
            'fullwidth' => 'on',
        ),
    );

    return $fields;
}

// === Divi 4: Output processing ===
function divi4_output($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }

    $props = $module->props;
    if (empty($props['fullwidth']) || $props['fullwidth'] !== 'on') {
        return $output;
    }

    // Active color
    if (!empty($props[D4_ACTIVE_COLOR]) && class_exists('ET_Builder_Element') && is_callable(array('ET_Builder_Element', 'set_style'))) {
        \ET_Builder_Element::set_style(
            $render_slug,
            array(
                'selector'    => '%%order_class%% .et-pb-controllers a.et-pb-active-control',
                'declaration' => 'background-color: ' . esc_html($props[D4_ACTIVE_COLOR]) . ' !important; opacity: 1 !important;'
            )
        );
    }

    // Inactive color
    if (!empty($props[D4_INACTIVE_COLOR]) && class_exists('ET_Builder_Element') && is_callable(array('ET_Builder_Element', 'set_style'))) {
        \ET_Builder_Element::set_style(
            $render_slug,
            array(
                'selector'    => '%%order_class%% .et-pb-controllers a:not(.et-pb-active-control)',
                'declaration' => 'background-color: ' . esc_html($props[D4_INACTIVE_COLOR]) . ' !important; opacity: 1 !important;'
            )
        );
    }

    // Size
    if (!empty($props[D4_SIZE]) && class_exists('ET_Builder_Element') && is_callable(array('ET_Builder_Element', 'set_style'))) {
        $size = sanitize_size_value($props[D4_SIZE]);
        if ($size !== '') {
            \ET_Builder_Element::set_style(
                $render_slug,
                array(
                    'selector'    => 'div%%order_class%% .et-pb-controllers a',
                    'declaration' => 'width: ' . $size . ' !important; height: ' . $size . ' !important; border-radius: 50%;'
                )
            );
        }
    }

    // Ensure border-style is solid per instance (for visibility of borders when configured)
    if (class_exists('ET_Builder_Element') && is_callable(array('ET_Builder_Element', 'set_style'))) {
        \ET_Builder_Element::set_style(
            $render_slug,
            array(
                'selector'    => '%%order_class%% .et-pb-controllers a',
                'declaration' => 'border-style: solid !important;'
            )
        );
    }

    return $output;
}

// === Divi 5: Attribute registration (PHP) ===
function register_divi5_attributes($settings) {
    $module_name       = $settings['name'] ?? '';
    $module_attributes = $settings['attributes'] ?? false;
    if ($module_name !== DIVI5_MODULE_SLUG) {
        return $settings;
    }
    if (!$module_attributes) {
        return $settings;
    }

    $settings['attributes'][D5_ATTR_INACTIVE] = get_divi5_attr_def_inactive();
    $settings['attributes'][D5_ATTR_ACTIVE]   = get_divi5_attr_def_active();
    $settings['attributes'][D5_ATTR_SIZE]     = get_divi5_attr_def_size();
    $settings['attributes'][D5_ATTR_BORDER]   = get_divi5_attr_def_border();
    $settings['attributes'][D5_ATTR_SHADOW]   = get_divi5_attr_def_shadow();

    return $settings;
}

// === Divi 5: Conversion Outline (PHP) ===
function register_divi5_conversion_outline($conversion_outline, $module_name) {
    if ($module_name !== DIVI5_MODULE_SLUG) {
        return $conversion_outline;
    }

    if (!isset($conversion_outline['module']) || !is_array($conversion_outline['module'])) {
        $conversion_outline['module'] = array();
    }
    if (!isset($conversion_outline['advanced']) || !is_array($conversion_outline['advanced'])) {
        $conversion_outline['advanced'] = array();
    }
    if (!isset($conversion_outline['advanced']['borders']) || !is_array($conversion_outline['advanced']['borders'])) {
        $conversion_outline['advanced']['borders'] = array();
    }
    if (!isset($conversion_outline['advanced']['box_shadow']) || !is_array($conversion_outline['advanced']['box_shadow'])) {
        $conversion_outline['advanced']['box_shadow'] = array();
    }

    // Map Divi 4 simple fields -> Divi 5 attributes (entire attribute; avoid background path)
    $conversion_outline['module'][D4_INACTIVE_COLOR] = D5_ATTR_INACTIVE . '.*';
    $conversion_outline['module'][D4_ACTIVE_COLOR]   = D5_ATTR_ACTIVE   . '.*';
    $conversion_outline['module'][D4_SIZE]           = D5_ATTR_SIZE     . '.*';

    // Map Divi 4 advanced borders subgroup -> Divi 5 custom border attribute path
    $conversion_outline['advanced']['borders']['dot_navigation'] = D5_ATTR_BORDER . '.decoration.border';
    // Map Divi 4 advanced box shadow subgroup -> Divi 5 custom box shadow attribute path
    $conversion_outline['advanced']['box_shadow']['dot_navigation'] = D5_ATTR_SHADOW . '.decoration.boxShadow';

    return $conversion_outline;
}

// === Divi 5: Front-end / Builder styles via Style::add ===
function divi5_style_add($module_wrapper, $args) {
    $module_name     = $args['name'] ?? '';
    $module_elements = $args['elements'] ?? null;
    if ($module_name !== DIVI5_MODULE_SLUG || !$module_elements) {
        return $module_wrapper;
    }

    if (is_callable('\\ET\\Builder\\FrontEnd\\Module\\Style::add')) {
        \ET\Builder\FrontEnd\Module\Style::add([
            'id'            => $args['id'] ?? '',
            'name'          => $module_name,
            'orderIndex'    => $args['orderIndex'] ?? 0,
            'storeInstance' => $args['storeInstance'] ?? 0,
            'styles'        => [
                $module_elements->style(['attrName' => D5_ATTR_INACTIVE]),
                $module_elements->style(['attrName' => D5_ATTR_ACTIVE]),
                $module_elements->style(['attrName' => D5_ATTR_BORDER]),
                $module_elements->style(['attrName' => D5_ATTR_SHADOW]),
                // Size is handled via render_block fallback to ensure width+height+radius
            ],
        ]);
    }

    return $module_wrapper;
}

// === Divi 5: Output processing (fallback CSS) ===
function divi5_output($block_content, $parsed_block, $block) {
    $attrs = isset($parsed_block['attrs']) && is_array($parsed_block['attrs']) ? $parsed_block['attrs'] : array();

    if (!is_slider_layout($attrs)) {
        return $block_content;
    }

    $order_class = extract_order_class_from_html($block_content);
    if ($order_class === '') {
        return $block_content;
    }

    $css_rules = array();

    // Colors (opacity fix included)
    $inactive_color = divi5_read_color_value($attrs, D5_ATTR_INACTIVE);
    if ($inactive_color !== '') {
        $css_rules[] = '.' . $order_class . ' .et-pb-controllers a:not(.et-pb-active-control){background-color:' . esc_html($inactive_color) . ' !important;opacity:1!important;}';
    }
    $active_color = divi5_read_color_value($attrs, D5_ATTR_ACTIVE);
    if ($active_color !== '') {
        $css_rules[] = '.' . $order_class . ' .et-pb-controllers a.et-pb-active-control{background-color:' . esc_html($active_color) . ' !important;opacity:1!important;}';
    }

    // Size
    $size_val = divi5_read_measure($attrs, D5_ATTR_SIZE);
    if ($size_val !== '') {
        $size_val = sanitize_size_value($size_val);
        if ($size_val !== '') {
            $css_rules[] = '.' . $order_class . ' .et-pb-controllers a{width:' . $size_val . ' !important;height:' . $size_val . ' !important;border-radius:50%;}';
        }
    }

    // Note: Do not force a border-style here; allow configured styles (e.g., dashed) to apply.

    if (!empty($css_rules)) {
        $block_content .= '<style>' . implode('', $css_rules) . '</style>';
    }

    return $block_content;
}

// === Divi 5: VB-only JS (attributes + group + conversion + StyleContainer) ===
function enqueue_divi5_vb_js() {
    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('divi-booster-' . DIVI5_MODULE_SLUG . '-dot-navigation');
    \wp_register_script($handle, '', array('lodash', 'divi-vendor-wp-hooks'), null, true);
    \wp_enqueue_script($handle);
    \wp_add_inline_script($handle, get_divi5_inline_js());
}

function get_divi5_inline_js() {
    $defInactive = wp_json_encode(get_divi5_attr_def_inactive());
    $defActive   = wp_json_encode(get_divi5_attr_def_active());
    $defSize     = wp_json_encode(get_divi5_attr_def_size());
    $defBorder   = wp_json_encode(get_divi5_attr_def_border());
    $defShadow   = wp_json_encode(get_divi5_attr_def_shadow());
    $d4slug      = wp_json_encode(DIVI4_MODULE_SLUG);

    $d5Inactive  = wp_json_encode(D5_ATTR_INACTIVE);
    $d5Active    = wp_json_encode(D5_ATTR_ACTIVE);
    $d5Size      = wp_json_encode(D5_ATTR_SIZE);
    $d5Border    = wp_json_encode(D5_ATTR_BORDER);
    $d5Shadow    = wp_json_encode(D5_ATTR_SHADOW);

    $d4Inactive  = wp_json_encode(D4_INACTIVE_COLOR);
    $d4Active    = wp_json_encode(D4_ACTIVE_COLOR);
    $d4Size      = wp_json_encode(D4_SIZE);

    return <<<JS
// Register custom attributes on Gallery module
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleAttributes.divi.gallery', 'divi', (attributes) => {
  attributes[{$d5Inactive}] = {$defInactive};
  attributes[{$d5Active}]   = {$defActive};
  attributes[{$d5Size}]     = {$defSize};
  attributes[{$d5Border}]   = {$defBorder};
  attributes[{$d5Shadow}]   = {$defShadow};
  return attributes;
});

// Create Design > Dot Navigation group
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleSettings.groups.divi.gallery', 'divi', (groups) => {
  groups.designDotNavigation = {
    groupName: 'designDotNavigation',
    panel: 'design',
    priority: 25,
    multiElements: true,
    component: {
      name: 'divi/composite',
      props: {
        groupLabel: 'Dot Navigation',
        visible: ({ attrs }) => {
          return attrs?.module?.advanced?.fullwidth?.desktop?.value === 'on';
        }
      }
    }
  };
  return groups;
});

// Conversion outline mapping (Divi 4 -> Divi 5)
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (outline, name) => {
    // no-op
  if (name !== {$d4slug}) return outline;
  if (!outline.module) outline.module = {};
  if (!outline.advanced) outline.advanced = {};
  if (!outline.advanced.borders) outline.advanced.borders = {};
  if (!outline.advanced.box_shadow) outline.advanced.box_shadow = {};
    outline.module[{$d4Inactive}] = {$d5Inactive} + '.*';
    outline.module[{$d4Active}]   = {$d5Active}   + '.*';
  outline.module[{$d4Size}]     = {$d5Size}     + '.*';
    outline.advanced.borders['dot_navigation']    = {$d5Border} + '.decoration.border';
    outline.advanced.box_shadow['dot_navigation'] = {$d5Shadow} + '.decoration.boxShadow';
  return outline;
});

// Ensure builder prints attribute styles (StyleContainer)
window.vendor.wp.hooks.addFilter('divi.module.wrapper.render', 'divi', (moduleWrapper, param) => {
  const { name: moduleName, elements: moduleElements, state: moduleState } = param;
  if ('divi/gallery' !== moduleName || !moduleElements) return moduleWrapper;
  const { StyleContainer } = window.divi.module;
  const { isEdited } = moduleWrapper.props;
  const children = [
    window.vendor.wp.element.createElement(StyleContainer, { key: 'dbdb-dotnav-inactive', mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false }, moduleElements.style({ attrName: {$d5Inactive} })),
    window.vendor.wp.element.createElement(StyleContainer, { key: 'dbdb-dotnav-active',   mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false }, moduleElements.style({ attrName: {$d5Active} })),
    window.vendor.wp.element.createElement(StyleContainer, { key: 'dbdb-dotnav-border',   mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false }, moduleElements.style({ attrName: {$d5Border} })),
    window.vendor.wp.element.createElement(StyleContainer, { key: 'dbdb-dotnav-shadow',   mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false }, moduleElements.style({ attrName: {$d5Shadow} })),
  ];
  return window.vendor.wp.element.cloneElement(moduleWrapper, {}, moduleWrapper.props.children, children);
});
JS;
}

// === Divi 5: Attribute Definitions ===
function get_divi5_attr_def_inactive() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}} .et-pb-controllers a:not(.et-pb-active-control)',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'dotNavInactiveColor' => [
                        'groupSlug'   => 'designDotNavigation',
                        'attrName'    => D5_ATTR_INACTIVE,
                        'label'       => __('Dot Navigation Inactive Color', 'divi-gallery-booster'),
                        'description' => __('Choose the inactive dot color for the navigation dots at the bottom of the slider.', 'divi-gallery-booster'),
                        'features'    => [ 'hover' => false, 'sticky' => false, 'responsive' => false, 'preset' => 'design' ],
                        'render'      => true,
                        'priority'    => 10,
                        'showIf'      => [ 'fullwidth' => [ 'desktop' => [ 'value' => 'on' ] ] ],
                        'component'   => [
                            'type'  => 'field',
                            'name'  => 'divi/color-picker',
                            'props' => [ 'isAlpha' => true ],
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => '' ] ],
                    ],
                ],
            ],
        ],
    ];
}

function get_divi5_attr_def_active() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}} .et-pb-controllers a.et-pb-active-control',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'dotNavActiveColor' => [
                        'groupSlug'   => 'designDotNavigation',
                        'attrName'    => D5_ATTR_ACTIVE,
                        'label'       => __('Dot Navigation Active Color', 'divi-gallery-booster'),
                        'description' => __('Choose the active dot color for the navigation dots at the bottom of the slider.', 'divi-gallery-booster'),
                        'features'    => [ 'hover' => false, 'sticky' => false, 'responsive' => false, 'preset' => 'design' ],
                        'render'      => true,
                        'priority'    => 15,
                        'showIf'      => [ 'fullwidth' => [ 'desktop' => [ 'value' => 'on' ] ] ],
                        'component'   => [
                            'type'  => 'field',
                            'name'  => 'divi/color-picker',
                            'props' => [ 'isAlpha' => true ],
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => '' ] ],
                    ],
                ],
            ],
        ],
    ];
}

function get_divi5_attr_def_size() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}} .et-pb-controllers a',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'dotSizeMeasure' => [
                        'groupSlug'   => 'designDotNavigation',
                        'attrName'    => D5_ATTR_SIZE,
                        'label'       => __('Dot Navigation Size', 'divi-gallery-booster'),
                        'description' => __('Choose the size of the navigation dots at the bottom of the slider.', 'divi-gallery-booster'),
                        'features'    => [ 'hover' => false, 'sticky' => false, 'responsive' => false, 'preset' => 'advanced' ],
                        'showIf'      => [ 'fullwidth' => [ 'desktop' => [ 'value' => 'on' ] ] ],
                        'render'      => true,
                        'priority'    => 20,
                        'component'   => [
                            'type' => 'field',
                            'name' => 'divi/range',
                            'props' => [
                                'allowedUnits' => ['px','%','em','rem','vh','vw','cm','mm','in','pt','pc','ex']
                            ]
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => '7px' ] ],
                    ],
                ],
            ],
        ],
    ];
}

function get_divi5_attr_def_border() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}} .et-pb-controllers a',
        'settings' => [
            'decoration' => [
                'border' => [
                    'groupType' => 'group-item',
                    'item'      => [
                        'groupSlug' => 'designDotNavigation',
                        'priority'  => 30,
                        'render'    => true,
                        'component' => [
                            'name'  => 'divi/border',
                            'type'  => 'group',
                            'props' => [ 'grouped' => false ],
                        ],
                    ],
                ],
            ],
        ],
        'styleProps' => [
            'border' => [
                'selector' => '{{selector}} .et-pb-controllers a',
                'important' => [
                    'border' => [
                        'desktop' => [
                            'value' => [
                                'border' => true,
                                'border-color' => true,
                                'border-style' => true,
                                'border-width' => true,
                                'border-radius' => true,
                                'border-top-left-radius' => true,
                                'border-top-right-radius' => true,
                                'border-bottom-right-radius' => true,
                                'border-bottom-left-radius' => true,
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ];
}

function get_divi5_attr_def_shadow() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}} .et-pb-controllers a',
        'settings' => [
            'decoration' => [
                'boxShadow' => [
                    'groupType' => 'group-item',
                    'item'      => [
                        'groupSlug' => 'designDotNavigation',
                        'priority'  => 35,
                        'render'    => true,
                        'component' => [
                            'name'  => 'divi/box-shadow',
                            'type'  => 'group',
                            'props' => [ 'grouped' => false ],
                        ],
                    ],
                ],
            ],
        ]
    ];
}

// === Helpers ===
function extract_order_class_from_html($html) {
    if (!is_string($html) || $html === '') return '';
    if (!preg_match('/<div[^>]*class=\"([^\"]*\bet_pb_gallery\b[^\"]*)\"/i', $html, $m)) {
        return '';
    }
    $classes = preg_split('/\s+/', $m[1], -1, PREG_SPLIT_NO_EMPTY);
    foreach ($classes as $c) {
        if (preg_match('/^et_pb_gallery_\d+(?:_[^\s]+)?$/', $c)) {
            return $c;
        }
    }
    if (preg_match('/et_pb_gallery_\d+(?:_[^\s]+)?/', $m[1], $m2)) {
        return $m2[0];
    }
    return '';
}

function sanitize_size_value($value) {
    if (!is_string($value)) {
        return '';
    }
    $value = trim($value);
    if ($value === '') return '';
    // Allow numeric with unit, or just number -> add px
    if (preg_match('/^\d+(?:\.\d+)?(px|%|em|rem|vh|vw|cm|mm|in|pt|pc|ex)$/', $value)) {
        return $value;
    }
    if (preg_match('/^\d+(?:\.\d+)?$/', $value)) {
        return $value . 'px';
    }
    return '';
}

function is_slider_layout($props) {
    // Divi 4
    if (isset($props['fullwidth'])) {
        return ($props['fullwidth'] === 'on');
    }
    // Divi 5
    if (isset($props['module']['advanced']['fullwidth']['desktop']['value'])) {
        return ($props['module']['advanced']['fullwidth']['desktop']['value'] === 'on');
    }
    return false;
}

function divi5_read_color_value($attrs, $attr_key) {
    if (!is_array($attrs) || !isset($attrs[$attr_key]) || !is_array($attrs[$attr_key])) return '';
    $p = $attrs[$attr_key];
    // New structure (color-picker field): directly on value / desktop.value
    $color = $p['desktop']['value'] ?? $p['value'] ?? '';
    if (is_string($color) && $color !== '') return $color;
    // Backward compatibility with prior background-based structure
    $color = $p['decoration']['background']['desktop']['value']['color'] ??
             $p['decoration']['background']['value']['color'] ??
             $p['decoration']['background']['color'] ??
             '';
    return is_string($color) ? $color : '';
}

function divi5_read_measure($attrs, $attr_key) {
    if (!is_array($attrs) || !isset($attrs[$attr_key]) || !is_array($attrs[$attr_key])) return '';
    $p = $attrs[$attr_key];
    $val = $p['desktop']['value'] ?? $p['value'] ?? '';
    return is_string($val) ? $val : '';
}

// Created at 1759240955.
