<?php
namespace DiviBooster\GalleryBooster\LightboxSwipe;

// === Constants ===
const DIVI4_MODULE_SLUG = 'et_pb_gallery';
const DIVI5_MODULE_SLUG = 'divi/gallery';
const DIVI4_SETTING_SLUG = 'dbdb_lightbox_swipe';
const DIVI5_SETTING_SLUG = 'diviboosterLightboxSwipe';
const DIVI4_ENABLE_LIGHTBOX_SLUG = 'dbdb_show_in_lightbox';
const DIVI5_ENABLE_LIGHTBOX_SLUG = 'diviboosterShowInLightbox';

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

// === Divi 5: VB-only JS to register attribute and conversion mapping ===
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_divi5_vb_js');
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 . '-' . DIVI5_SETTING_SLUG);
    wp_register_script($handle, '', ['lodash', 'divi-vendor-wp-hooks'], null, true);
    wp_enqueue_script($handle);
    wp_add_inline_script($handle, get_divi5_inline_js());
}

// === Divi 5: PHP conversion outline registration ===
function dbdb_register_divi5_lightbox_swipe_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_lightbox_swipe_conversion', 10, 2);

// === Divi 4: Field Registration ===
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\add_field');
function add_field($fields) {
    if (!is_array($fields)) {
        return $fields;
    }
    $fields[DIVI4_SETTING_SLUG] = array(
        'label'           => esc_html__('Enable Lightbox Swiping', 'divi-gallery-booster'),
        'type'            => 'yes_no_button',
        'option_category' => 'configuration',
        'options'         => array(
            'on'  => esc_html__('Yes', 'divi-gallery-booster'),
            'off' => esc_html__('No', 'divi-gallery-booster'),
        ),
        'default'         => 'off',
        'tab_slug'        => 'advanced',
        'toggle_slug'     => 'layout',
        'description'     => esc_html__('Enable swipe functionality inside the lightbox. On touch devices, swiping left or right in the lightbox will navigate through images.', 'divi-gallery-booster'),
        'show_if'         => array(
            DIVI4_ENABLE_LIGHTBOX_SLUG => 'on',
        ),
        'class'           => 'hide-warning',
    );
    return $fields;
}

// === 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_lightbox_swipe($module->props)) {
        return $output;
    }
    $output = inject_data_attr_into_gallery($output, 'data-dbdb-lightbox-swipe', '1');
    if (!has_action('wp_footer', __NAMESPACE__ . '\output_lightbox_swipe_script_once')) {
        add_action('wp_footer', __NAMESPACE__ . '\output_lightbox_swipe_script_once');
    }
    return $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_lightbox_swipe($attrs)) {
        return $block_content;
    }
    $block_content = inject_data_attr_into_gallery($block_content, 'data-dbdb-lightbox-swipe', '1');
    if (!has_action('wp_footer', __NAMESPACE__ . '\output_lightbox_swipe_script_once')) {
        add_action('wp_footer', __NAMESPACE__ . '\output_lightbox_swipe_script_once');
    }
    return $block_content;
}, 10, 3);

// === One-time Front-end Script Injection ===
function output_lightbox_swipe_script_once() {
    static $done = false;
    if ($done) return;
    $done = true;
    ?>
    <script>
    jQuery(document).ready(function($) {
        function clearDbdbLightboxSwipe() {
            $('body').removeClass(function(index, className) {
                return (className.match(/(^|\s)et_pb_gallery_\d+(?:_[^\s]+)?_dbdb_lightbox_swipe/g) || []).join(' ');
            });
        }

        // Per-instance activation: when a gallery image is clicked
        $(document).on('click', '.et_pb_gallery .et_pb_gallery_image a', function () {
            clearDbdbLightboxSwipe();
            var $gallery = $(this).closest('.et_pb_gallery');
            if (!$gallery.length) return;
            var classMatches = ($gallery.attr('class') || '').match(/et_pb_gallery_\d+(?:_[^\s]+)?/);
            if (!classMatches) return;
            var orderClass = classMatches[0];
            if ($gallery.is('[data-dbdb-lightbox-swipe]')) {
                $('body').addClass(orderClass + '_dbdb_lightbox_swipe');
            }
        });

        // Swipe handling on Magnific Popup wrapper
        $(document).on('touchstart.dbdbLightboxSwipe', '.mfp-wrap', function(e) {
            // Only activate if a module instance requested lightbox swiping
            var hasActive = /et_pb_gallery_\d+(?:_[^\s]+)?_dbdb_lightbox_swipe/.test(document.body.className || '');
            if (!hasActive) return;
            if (!e.originalEvent || !e.originalEvent.touches || !e.originalEvent.touches[0]) return;
            var startTouch = e.originalEvent.touches[0];
            var startX = startTouch.pageX;
            var startY = startTouch.pageY;
            var scrolledVertically = false;
            var $wrap = $(this);

            $wrap.on('touchmove.dbdbLightboxSwipe', function(moveEvent) {
                if (!moveEvent.originalEvent || !moveEvent.originalEvent.touches || !moveEvent.originalEvent.touches[0]) return;
                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.dbdbLightboxSwipe', function(endEvent) {
                $wrap.off('touchmove.dbdbLightboxSwipe touchend.dbdbLightboxSwipe');
                if (scrolledVertically) { scrolledVertically = false; return; }
                if (!endEvent.originalEvent || !endEvent.originalEvent.changedTouches || !endEvent.originalEvent.changedTouches[0]) return;
                var endTouch = endEvent.originalEvent.changedTouches[0];
                var endX = endTouch.pageX;
                var changeX = endX - startX;
                if (Math.abs(changeX) > 0) {
                    if (changeX > 0) {
                        $('.mfp-wrap .mfp-arrow-left').trigger('click');
                    } else {
                        $('.mfp-wrap .mfp-arrow-right').trigger('click');
                    }
                }
            });

            e.stopPropagation();
        });

        // Cleanup on close
        $(document).on('click', '.mfp-close, .mfp-bg', function() { clearDbdbLightboxSwipe(); });
        $(document).on('keyup', function(e) { if (e.key === 'Escape') { clearDbdbLightboxSwipe(); } });
    });
    </script>
    <?php
}

// === Helpers: Divi 5 Inline JS for Attribute & Conversion ===
function get_divi5_inline_js() {
    $attr = wp_json_encode(get_divi5_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) => {
    attributes[{$d5key}] = {$attr};
    return attributes;
});

// Conversion map (Divi 4 -> Divi 5)
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (conversionOutline, name) => {
    if (name !== {$d4slug}) return conversionOutline;
    if (!conversionOutline.module) conversionOutline.module = {};
    conversionOutline.module[{$d4key}] = {$d5key} + '.*';
    return conversionOutline;
});
JS;
}

// === Helpers: Attribute Definition ===
function get_divi5_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'lightboxSwipeToggle' => [
                        'groupSlug'   => 'designLayout',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => __('Enable Lightbox Swiping', 'divi-gallery-booster'),
                        'description' => __('Enable swipe functionality inside the lightbox. On touch devices, swiping left or right in the lightbox will navigate through images.', 'divi-gallery-booster'),
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'advanced',
                        ],
                        'showIf' => [
                            DIVI5_ENABLE_LIGHTBOX_SLUG => [
                                'desktop' => ['value' => 'on']
                            ]
                        ],
                        'render'      => true,
                        'priority'    => 82, // Immediately after slider swipe (81)
                        'component'   => [
                            'type' => 'field',
                            'name' => 'divi/toggle',
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => 'off' ] ],
                    ],
                ],
            ],
        ],
    ];
}

// === Common Helpers ===
function lightbox_enabled($props) {
    // Divi 4 flat
    if (isset($props[DIVI4_ENABLE_LIGHTBOX_SLUG])) {
        return ($props[DIVI4_ENABLE_LIGHTBOX_SLUG] === 'on');
    }
    // Divi 5 structured
    if (isset($props[DIVI5_ENABLE_LIGHTBOX_SLUG]['desktop']['value'])) {
        return ($props[DIVI5_ENABLE_LIGHTBOX_SLUG]['desktop']['value'] === 'on');
    }
    if (isset($props[DIVI5_ENABLE_LIGHTBOX_SLUG]['value'])) {
        return ($props[DIVI5_ENABLE_LIGHTBOX_SLUG]['value'] === 'on');
    }
    // Default to enabled if not specified
    return true;
}

function should_enable_lightbox_swipe($props) {
    if (!lightbox_enabled($props)) {
        return false;
    }
    // Divi 4 flat value
    if (isset($props[DIVI4_SETTING_SLUG]) && $props[DIVI4_SETTING_SLUG] === 'on') {
        return true;
    }
    // Divi 5 structured value
    if (isset($props[DIVI5_SETTING_SLUG]['desktop']['value']) && $props[DIVI5_SETTING_SLUG]['desktop']['value'] === 'on') {
        return true;
    }
    // Divi 5 fallback flat value
    if (isset($props[DIVI5_SETTING_SLUG]['value']) && $props[DIVI5_SETTING_SLUG]['value'] === 'on') {
        return true;
    }
    return false;
}

function inject_data_attr_into_gallery($content, $attr_name, $attr_value) {
    if (!is_string($content) || $content === '') return $content;
    $attr_value_esc = esc_attr($attr_value);
    return preg_replace_callback(
        '/<div([^>]*)class=\"([^\"]*\\bet_pb_gallery\\b[^\"]*)\"/i',
        function($m) use ($attr_name, $attr_value_esc) {
            $before  = $m[1];
            $classes = $m[2];
            if (strpos($before, $attr_name) === false) {
                $before .= ' ' . $attr_name . '="' . $attr_value_esc . '"';
            } else {
                $before = preg_replace('/' . preg_quote($attr_name, '/') . '\\s*=\\s*\"[^\"]*\"/i', $attr_name . '="' . $attr_value_esc . '"', $before);
            }
            return '<div' . $before . 'class="' . $classes . '"';
        },
        $content,
        1 // first gallery wrapper only
    );
}
// Created at 1757623259.
