<?php
namespace DiviBooster\GalleryBooster\SliderSwipeMode;

// === Divi 5/4 Constants ===
const DIVI5_MODULE_SLUG = 'divi/gallery';
const DIVI4_MODULE_SLUG = 'et_pb_gallery';
const DIVI5_SETTING_SLUG = 'diviboosterSliderSwipeMode';
const DIVI4_SETTING_SLUG = 'dbdb_slider_swipe_mode';

// === Divi 5 Attribute Registration ===
add_filter('divi_module_library_register_module_attrs', function($attrs, $args) {
    if (($args['name'] ?? '') !== DIVI5_MODULE_SLUG) {
        return $attrs;
    }
    $attrs[DIVI5_SETTING_SLUG] = get_d5_attribute_definition();
    return $attrs;
}, 10, 2);

function get_d5_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'sliderSwipeToggle' => [
                        'groupSlug'   => 'designLayout', 
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => __('Enable Touchscreen Swiping', 'et_builder'),
                        'description' => __('Enable swipe functionality for the gallery slider. On touch screen devices, swiping left or right will navigate through the slides.', 'divi-booster'),
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'advanced',
                        ],
                        'showIf' => [
                            'fullwidth' => [
                                'desktop' => ['value' => 'on'],
                            ]
                        ],
                        'render'   => true,
                        'priority' => 81, // After built-in fields
                        'component' => [
                            'type' => 'field',
                            'name' => 'divi/toggle',
                        ],
                        'defaultAttr' => ['desktop' => ['value' => 'off']],
                    ],
                ],
            ],
        ],
    ];
}

// === Divi 5 JS â€“ Add Attribute & Conversion ===
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_divi5_script');
function enqueue_divi5_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-gallery-slider-swipe');
    \dbdb_enqueue_inline_script_if_dependencies_available($handle, get_divi5_inline_js(), array('lodash', array('divi-vendor-wp-hooks', 'wp-hooks')));
}
function get_divi5_inline_js() {
    $attr = wp_json_encode(get_d5_attribute_definition());
    $d4slug = wp_json_encode(DIVI4_MODULE_SLUG);
    $d5key = wp_json_encode(DIVI5_SETTING_SLUG);
    $d4key = wp_json_encode(DIVI4_SETTING_SLUG);
    return <<<JS
// Adds the custom attribute to the Gallery module.
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleAttributes.divi.gallery', 'divi', (attributes, metadata) => {
    attributes[{$d5key}] = {$attr};
    return attributes;
});
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (conversionOutline, name) => {
    if (name !== {$d4slug}) return conversionOutline;
    conversionOutline.module[{$d4key}] = {$d5key} + '.*';
    return conversionOutline;
});
JS;
}

// === Divi 4 Field Integration ===
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\add_field');
// === Divi 5: PHP conversion outline registration ===
function dbdb_register_divi5_slider_swipe_mode_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'][DIVI4_SETTING_SLUG] = DIVI5_SETTING_SLUG . '.*';
    return $conversion_outline;
}
add_filter( 'divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\dbdb_register_divi5_slider_swipe_mode_conversion', 10, 2 );
function add_field($fields) {
    if (!is_array($fields)) {
        return $fields;
    }
    $fields[DIVI4_SETTING_SLUG] = array(
        'label'             => esc_html__('Enable Touchscreen Swiping', 'et_builder'),
        'type'              => 'yes_no_button',
        'option_category'   => 'configuration',
        'options'           => array(
            'on'  => esc_html__('Yes', 'et_builder'),
            'off' => esc_html__('No', 'et_builder'),
        ),
        'default'  => 'off',
        'tab_slug'        => 'advanced',
        'toggle_slug'        => 'layout',
        'description'       => esc_html__('Enable swipe functionality for the gallery slider. On touch screen devices, swiping left or right will navigate through the slides.', 'divi-booster'),
        'show_if' => array(
            'fullwidth' => 'on',
        ),
        'class' => 'hide-warning',
    );
    return $fields;
}

// === Common: Detect if swipe mode is enabled and output script / class ===
function gallery_layout($props) {
    if (isset($props['fullwidth'])) {
        return ($props['fullwidth'] === 'on') ? 'slider' : 'grid';
    }
    if (isset($props['module']) && isset($props['module']['advanced']['fullwidth']['desktop']['value'])) {
        return ($props['module']['advanced']['fullwidth']['desktop']['value'] === 'on') ? 'slider' : 'grid';
    }
    return 'grid';
}

function should_enable_swipe_mode($props) {
    // $props may be Divi 4 or Divi 5 attributes
    if (isset($props[DIVI4_SETTING_SLUG]) && $props[DIVI4_SETTING_SLUG] === 'on') {
        return gallery_layout($props) === 'slider';
    }
    if (isset($props[DIVI5_SETTING_SLUG]['desktop']['value']) && $props[DIVI5_SETTING_SLUG]['desktop']['value'] === 'on') {
        return gallery_layout($props) === 'slider';
    }
    // fallback: Divi 5 flat value
    if (isset($props[DIVI5_SETTING_SLUG]['value']) && $props[DIVI5_SETTING_SLUG]['value'] === 'on') {
        return gallery_layout($props) === 'slider';
    }
    return false;
}

function add_swipe_class_to_module($content) {
    // Add dbdb-slider-swipe-mode to the first .et_pb_gallery.et_pb_slider in $content, regardless of class order
    return preg_replace_callback(
        '/class="([^"]*)"/i',
        function ($matches) {
            $classes = preg_split('/\s+/', $matches[1], -1, PREG_SPLIT_NO_EMPTY);
            if (
                in_array('et_pb_gallery', $classes, true) &&
                in_array('et_pb_slider', $classes, true) &&
                !in_array('dbdb-slider-swipe-mode', $classes, true)
            ) {
                $classes[] = 'dbdb-slider-swipe-mode';
                // Only add to the first matching element
                static $done = false;
                if (!$done) {
                    $done = true;
                    return 'class="' . implode(' ', $classes) . '"';
                }
            }
            return $matches[0];
        },
        $content,
        1 // Only replace the first occurrence
    );
}

function inject_swipe_script_once() {
    static $done = false;
    if ($done) return;
    $done = true;
    // Output JS same as legacy
    ?>
    <script>
    jQuery(document).ready(function($) {
        $('.et_pb_gallery.dbdb-slider-swipe-mode.et_pb_slider').on('touchstart', function(e) {
            var startTouch = e.originalEvent.touches[0];
            var startX = startTouch.pageX;
            var startY = startTouch.pageY;
            var scrolledVertically = false;
            var $thisGallery = $(this);

            $thisGallery.on('touchmove', function(moveEvent) {
                var moveTouch = moveEvent.originalEvent.touches[0];
                var changeX = moveTouch.pageX - startX;
                var changeY = moveTouch.pageY - startY;

                if (Math.abs(changeY) > Math.abs(changeX)) {
                    scrolledVertically = true;
                    return;
                }
                moveEvent.preventDefault();
            }).on('touchend', function(endEvent) {
                $thisGallery.off('touchmove touchend');

                if (scrolledVertically) {
                    scrolledVertically = false;
                    return;
                }

                var endTouch = endEvent.originalEvent.changedTouches[0];
                var endX = endTouch.pageX;
                var changeX = endX - startX;

                if (Math.abs(changeX) > 0) {
                    if (changeX > 0) {
                        $thisGallery.find('.et-pb-arrow-prev').click();
                    } else {
                        $thisGallery.find('.et-pb-arrow-next').click();
                    }
                }
                var event = $.Event('divi-booster:gallery-slide-changed');
                $thisGallery.trigger(event);
            });

            e.stopPropagation();
        });
    });
    </script>
    <?php
}

// === Divi 4 Output Integration ===
add_filter('et_module_shortcode_output', function($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }
    if (!should_enable_swipe_mode($module->props)) {
        return $output;
    }
    if (!has_action('wp_footer', __NAMESPACE__ . '\inject_swipe_script_once')) {
        add_action('wp_footer', __NAMESPACE__ . '\inject_swipe_script_once');
    }
    return add_swipe_class_to_module($output);
}, 10, 3);

// === Divi 5 Output Integration ===
add_filter('render_block_' . DIVI5_MODULE_SLUG, function($block_content, $parsed_block, $block) {
    $attrs = $parsed_block['attrs'] ?? array();
    if (!should_enable_swipe_mode($attrs)) {
        return $block_content;
    }
    if (!has_action('wp_footer', __NAMESPACE__ . '\inject_swipe_script_once')) {
        add_action('wp_footer', __NAMESPACE__ . '\inject_swipe_script_once');
    }
    return add_swipe_class_to_module($block_content);
}, 10, 3);
