<?php // https://divibooster.com/customize-slider-arrows-in-the-divi-gallery-module-slider-layout/

namespace DiviBooster\GalleryBooster\ArrowIcons;

const DIVI4_MODULE_SLUG = 'et_pb_gallery';
const DIVI5_MODULE_SLUG = 'divi/gallery';
const DBDB_PREV_ICON_SLUG = 'dbdb_prev_icon';
const DBDB_NEXT_ICON_SLUG = 'dbdb_next_icon';

// === Divi 4 Field Registration ===
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\add_fields');
function add_fields($fields) {
    if (!is_array($fields)) {
        return $fields;
    }
    $new_fields = array(
        DBDB_PREV_ICON_SLUG => array(
            'label'          => esc_html__( 'Previous Slide Icon', 'divi-gallery-booster' ),
            'toggle_slug'    => 'dbdb_arrows',
            'type'           => 'select_icon',
            'class'          => array( 'et-pb-font-icon' ),
            'description'    => esc_html__( 'Choose an icon to display for the previous slide arrow.', 'divi-gallery-booster' ),
            'mobile_options' => true,
            'hover'          => 'tabs',
            'sticky'         => true,
            'tab_slug'       => 'advanced',
            'show_if'        => array('fullwidth' => 'on'),
        ),
        DBDB_NEXT_ICON_SLUG => array(
            'label'          => esc_html__( 'Next Slide Icon', 'divi-gallery-booster' ),
            'toggle_slug'    => 'dbdb_arrows',
            'type'           => 'select_icon',
            'class'          => array( 'et-pb-font-icon' ),
            'description'    => esc_html__( 'Choose an icon to display for the next slide arrow.', 'divi-gallery-booster' ),
            'mobile_options' => true,
            'hover'          => 'tabs',
            'sticky'         => true,
            'tab_slug'       => 'advanced',
            'show_if'        => array('fullwidth' => 'on'),
        ),
    );
    return array_merge($fields, $new_fields);
}

// === Divi 5 Attribute Registration & Conversion Mapping (JS) ===
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_d5_booster_script');
function enqueue_d5_booster_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('divi-booster-' . DIVI5_MODULE_SLUG . '-arrow-icons');
    \dbdb_enqueue_inline_script_if_dependencies_available($handle, get_d5_inline_js(), array('lodash', array('divi-vendor-wp-hooks', 'wp-hooks')));
}
function get_d5_inline_js() {
    $prev_attr = wp_json_encode(get_d5_icon_attribute_definition(DBDB_PREV_ICON_SLUG, 'Previous Slide Icon'));
    $next_attr = wp_json_encode(get_d5_icon_attribute_definition(DBDB_NEXT_ICON_SLUG, 'Next Slide Icon'));
    $d4slug = wp_json_encode(DIVI4_MODULE_SLUG);
    $prev_key = wp_json_encode(DBDB_PREV_ICON_SLUG);
    $next_key = wp_json_encode(DBDB_NEXT_ICON_SLUG);
    return <<<JS
// Adds the custom attributes to the Gallery module.
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleAttributes.divi.gallery', 'divi', (attributes, metadata) => {
    attributes[{$prev_key}] = $prev_attr;
    attributes[{$next_key}] = $next_attr;
    return attributes;
});

window.vendor.wp.hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (outline, name) => {
    if (name !== {$d4slug}) return outline;
    const { convertFontIcon } = window?.divi?.conversion || {};
    if (!outline.module) outline.module = {};
    outline.module[{$prev_key}] = {$prev_key} + '.innerContent.*';
    outline.module[{$next_key}] = {$next_key} + '.innerContent.*';
    outline.valueExpansionFunctionMap = outline.valueExpansionFunctionMap || {};
    outline.valueExpansionFunctionMap[{$prev_key}] = convertFontIcon;
    outline.valueExpansionFunctionMap[{$next_key}] = convertFontIcon;
    return outline;
});
JS;
}

function get_d5_icon_attribute_definition($slug, $label) {
    return [
        'type' => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items' => [
                    $slug => [
                        'groupSlug' => 'designSliderArrows',
                        'attrName' => $slug . '.innerContent',
                        'label' => __($label, 'divi-gallery-booster'),
                        'description' => __('Choose an icon to display for the slider arrow.', 'divi-gallery-booster'),
                        'features' => [
                            'hover' => false,
                        ],
                        'render' => true,
                        'priority' => 30,
                        'component' => [
                            'type' => 'field',
                            'name' => 'divi/icon-picker',
                        ],
                    ],
                ],
            ],
        ],
    ];
}

// === Divi 5 Attribute Registration (PHP fallback, for server-side context) ===
add_filter('divi_module_library_register_module_attrs', function($attrs, $args) {
    if (($args['name'] ?? '') !== DIVI5_MODULE_SLUG) {
        return $attrs;
    }
    $attrs[DBDB_PREV_ICON_SLUG] = get_d5_icon_attribute_definition(DBDB_PREV_ICON_SLUG, 'Previous Slide Icon');
    $attrs[DBDB_NEXT_ICON_SLUG] = get_d5_icon_attribute_definition(DBDB_NEXT_ICON_SLUG, 'Next Slide Icon');
    return $attrs;
}, 10, 2);

// === Divi 5: PHP conversion outline registration ===
function dbdb_register_divi5_arrow_icons_conversion( $conversion_outline, $module_name ) {
    if ( DIVI5_MODULE_SLUG !== $module_name ) {
        return $conversion_outline;
    }
    if (!isset($conversion_outline['module']) || !is_array($conversion_outline['module'])) {
        $conversion_outline['module'] = array();
    }
    $conversion_outline['module'][DBDB_PREV_ICON_SLUG] = DBDB_PREV_ICON_SLUG . '.innerContent.*';
    $conversion_outline['module'][DBDB_NEXT_ICON_SLUG] = DBDB_NEXT_ICON_SLUG . '.innerContent.*';
    // Set valueExpansionFunctionMap to convertFontIcon for both keys
    if (!isset($conversion_outline['valueExpansionFunctionMap']) || !is_array($conversion_outline['valueExpansionFunctionMap'])) {
        $conversion_outline['valueExpansionFunctionMap'] = array();
    }
    $conversion_outline['valueExpansionFunctionMap'][DBDB_PREV_ICON_SLUG] = 'convertFontIcon';
    $conversion_outline['valueExpansionFunctionMap'][DBDB_NEXT_ICON_SLUG] = 'convertFontIcon';
    return $conversion_outline;
}
add_filter( 'divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\dbdb_register_divi5_arrow_icons_conversion', 10, 2 );

// === Divi 4 Output Filter ===
add_filter('et_module_shortcode_output', __NAMESPACE__ . '\output_icon_styles_divi4', 10, 3);
function output_icon_styles_divi4($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }
    // Only apply on slider layout
    if (!isset($module->props['fullwidth']) || $module->props['fullwidth'] !== 'on') {
        return $output;
    }

    // Use Divi's style processor for icons (restores compatibility)
    if (method_exists($module, 'generate_styles')) {
        $module->generate_styles([

            'utility_arg'    => 'icon_font_family_and_content',
            'render_slug'    => $render_slug,
            'base_attr_name' => DBDB_PREV_ICON_SLUG,
            'important'      => true,
            'selector'       => "%%order_class%% .et-pb-slider-arrows a.et-pb-arrow-prev:before",
            'processor'      => ['ET_Builder_Module_Helper_Style_Processor', 'process_extended_icon'],
        ]);
        $module->generate_styles([
            'utility_arg'    => 'icon_font_family_and_content',
            'render_slug'    => $render_slug,
            'base_attr_name' => DBDB_NEXT_ICON_SLUG,
            'important'      => true,
            'selector'       => "%%order_class%% .et-pb-slider-arrows a.et-pb-arrow-next:before",
            'processor'      => ['ET_Builder_Module_Helper_Style_Processor', 'process_extended_icon'],
        ]);
    }

    return $output;
}

// === Divi 5 Output Filter ===
add_filter('render_block_' . DIVI5_MODULE_SLUG, __NAMESPACE__ . '\output_icon_styles_divi5', 10, 3);
function output_icon_styles_divi5($block_content, $parsed_block, $block) {
    // For the front-end only.
    $attrs = isset($parsed_block['attrs']) ? $parsed_block['attrs'] : array();
    // Only apply on slider layout
    $is_slider = false;
    if (isset($attrs['module']['advanced']['fullwidth']['desktop']['value']) && $attrs['module']['advanced']['fullwidth']['desktop']['value'] === 'on') {
        $is_slider = true;
    }
    if (!$is_slider) return $block_content;
    // Extract order_class (e.g. et_pb_gallery_5 or similar)
    $order_class = false;
    if (preg_match('/class="([^"]+)"/i', $block_content, $match)) {
        if (preg_match('/\b(et_pb_gallery_[^\s"]+)/', $match[1], $class_match)) {
            $order_class = $class_match[1];
        }
    }
    if (!$order_class) return $block_content;
    $css = generate_icons_css($attrs, ".{$order_class}");
    if ($css) {
        // Prepend the style to the block content.
        $block_content = $css . $block_content;
    }
    return $block_content;
}

// === CSS Generation ===
function generate_icons_css($props, $selector) {
    $prev_icon = get_icon_value($props, DBDB_PREV_ICON_SLUG);
    $next_icon = get_icon_value($props, DBDB_NEXT_ICON_SLUG);
    if (!$prev_icon && !$next_icon) {
        return '';
    }
    $output = "<style type=\"text/css\">\n";
    if ($prev_icon && !empty($prev_icon['content'])) {
        $font_family = isset($prev_icon['font_family']) ? $prev_icon['font_family'] : 'ETmodules';
        $icon_content = $prev_icon['content'];
        $output .= "{$selector} .et-pb-slider-arrows a.et-pb-arrow-prev:before { font-family: '{$font_family}' !important; content: '{$icon_content}' !important; }\n";
    }
    if ($next_icon && !empty($next_icon['content'])) {
        $font_family = isset($next_icon['font_family']) ? $next_icon['font_family'] : 'ETmodules';
        $icon_content = $next_icon['content'];
        $output .= "{$selector} .et-pb-slider-arrows a.et-pb-arrow-next:before { font-family: '{$font_family}' !important; content: '{$icon_content}' !important; }\n";
    }
    $output .= '</style>';
    return $output;
}

function get_icon_value($props, $slug) {
    // Divi 4 flat
    if (isset($props[$slug]) && is_array($props[$slug]) && isset($props[$slug]['content'])) {
        return $props[$slug];
    }
    // Divi 5 deeply nested (block editor)
    if (
        isset($props[$slug]['innerContent']['desktop']['value']) &&
        is_array($props[$slug]['innerContent']['desktop']['value']) &&
        isset($props[$slug]['innerContent']['desktop']['value']['unicode'])
    ) {
        $icon = $props[$slug]['innerContent']['desktop']['value'];
        $font_family = 'ETmodules';
        $unicode = $icon['unicode'];
        // Convert HTML entity (e.g., '&#x41;') to CSS unicode (e.g., '\e041')
        $css_unicode = '';
        if (preg_match('/&#x([0-9a-fA-F]+);/', $unicode, $m)) {
            $hex = strtolower($m[1]);
            // Pad to 4 digits (Divi icons are usually in the e000+ range)
            $hex = str_pad($hex, 4, '0', STR_PAD_LEFT);
            $css_unicode = '\\' . $hex;
        } else {
            // fallback: use as-is
            $css_unicode = $unicode;
        }
        return [
            'content' => $css_unicode,
            'font_family' => $font_family,
        ];
    }
    // Divi 5 attribute (block, legacy fallback)
    if (isset($props[$slug]['icon']) && is_array($props[$slug]['icon'])) {
        return $props[$slug]['icon'];
    }
    return false;
}

// === Divi 5 Group Mapping JS ===
add_action('divi_visual_builder_assets_before_enqueue_scripts', __NAMESPACE__ . '\enqueue_d5_slider_arrows_group_script');
function enqueue_d5_slider_arrows_group_script() {
    $handle = sanitize_title('divibooster-slider-arrows-group');
    \dbdb_enqueue_inline_script_if_dependencies_available($handle, get_d5_slider_arrows_group_js(), array('lodash', array('divi-vendor-wp-hooks', 'wp-hooks')));
}
function get_d5_slider_arrows_group_js() {
    return <<<JS
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleSettings.groups.divi.gallery', 'divi', (groups, metadata) => {
  groups.designSliderArrows = {
    groupName: 'designSliderArrows',
    panel: 'design',
    priority: 21,
    multiElements: true,
    component: {
        name: 'divi/composite',
        props: {
          groupLabel: 'Slider Arrows',
          visible: ({ attrs }) => {
            return attrs?.module?.advanced?.fullwidth?.desktop?.value === 'on';
          },
        },
    },
  };
  return groups;
});
JS;
}

// Created at 1753753871.
