<?php

namespace DiviBooster\GalleryBooster\SliderImageCount;

// === Constants ===
const DIVI4_MODULE_SLUG = 'et_pb_gallery';
const DIVI5_MODULE_SLUG = 'divi/gallery';
const DIVI4_SETTING_SLUG = 'dbdb_image_count'; // keep existing slug
const DIVI5_SETTING_SLUG = 'diviboosterImageCount'; // camelCase for D5
const ADVANCED_FIELD_SLUG = 'dbdb_image_count'; // font group slug (kept same for compatibility)

// === Divi 4: Add Field ===
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__('Show Slider Image Count', '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'        => 'general',
        'toggle_slug'     => 'elements',
        'description'     => esc_html__('Display current image number / total images below the slider.', 'divi-booster'),
        'show_if'         => array(
            'fullwidth' => 'on',
        ),
    );
    $fields['dbdb_image_count_warning'] = array(
        'type'        => 'warning',
        'tab_slug'    => 'general',
        'toggle_slug' => 'elements',
        'message'     => esc_html__('This feature will only show on the front end, not in the Visual Builder preview.', 'divi-booster'),
        'show_if'     => array(
            DIVI4_SETTING_SLUG => 'on',
            'fullwidth'        => 'on',
        ),
        'value'      => true,
        'display_if' => true,
    );
    return $fields;
}

// === Divi 4: Advanced Fields (Fonts) ===
add_filter('et_pb_gallery_advanced_fields', __NAMESPACE__ . '\\add_advanced_fields', 10, 3);
function add_advanced_fields($fields, $slug, $main_css_element) {
    if (!is_array($fields) || !isset($fields['fonts'])) {
        return $fields;
    }
    $fields['fonts'][ADVANCED_FIELD_SLUG] = array(
        'label'      => esc_html__('Image Count', 'divi-booster'),
        'css'        => array(
            'main'       => "$main_css_element .dbdb-slide-counter",
            'hover'      => "$main_css_element .dbdb-slide-counter:hover",
            'text_align' => "$main_css_element .dbdb-slide-counter",
        ),
        'text_align' => array(
            'options' => function_exists('et_builder_get_text_orientation_options') ? et_builder_get_text_orientation_options(array('justified')) : array(),
        ),
    );
    return $fields;
}

// === Utilities (Common) ===
function is_builder_active() {
    return (function_exists('et_core_is_fb_enabled') && \et_core_is_fb_enabled());
}
function is_slider_layout($props_or_attrs) {
    // Divi 4
    if (isset($props_or_attrs['fullwidth'])) {
        return ($props_or_attrs['fullwidth'] === 'on');
    }
    // Divi 5
    if (isset($props_or_attrs['module']['advanced']['fullwidth']['desktop']['value'])) {
        return ($props_or_attrs['module']['advanced']['fullwidth']['desktop']['value'] === 'on');
    }
    return false;
}
function should_show_counter($props_or_attrs) {
    if (!is_slider_layout($props_or_attrs)) return false;
    // Divi 4 stored value
    if (isset($props_or_attrs[DIVI4_SETTING_SLUG]) && $props_or_attrs[DIVI4_SETTING_SLUG] === 'on') return true;
    // Divi 5 responsive value
    if (isset($props_or_attrs[DIVI5_SETTING_SLUG]['desktop']['value']) && $props_or_attrs[DIVI5_SETTING_SLUG]['desktop']['value'] === 'on') return true;
    // Divi 5 flat fallback
    if (isset($props_or_attrs[DIVI5_SETTING_SLUG]['value']) && $props_or_attrs[DIVI5_SETTING_SLUG]['value'] === 'on') return true;
    return false;
}
function add_feature_class_to_wrapper($html) {
    if (!is_string($html) || $html === '') return $html;
    return preg_replace_callback(
        '/class="([^"]*?\bet_pb_gallery\b[^"]*?)"/i',
        function ($m) {
            $classes = preg_split('/\s+/', $m[1], -1, PREG_SPLIT_NO_EMPTY);
            if (!in_array('dbdb-gallery-with-image-count', $classes, true)) {
                $classes[] = 'dbdb-gallery-with-image-count';
            }
            return 'class="' . implode(' ', $classes) . '"';
        },
        $html,
        1
    );
}
function count_total_slides_from_html($html) {
    if (!is_string($html) || $html === '') return 0;
    if (preg_match_all('/<div\s+class="[^"]*\bet_pb_gallery_item\b/i', $html, $mm)) {
        return (int) count($mm[0]);
    }
    return 0;
}
function inject_counter_markup($html, $total) {
    if (!is_string($html) || $html === '') return $html;
    if (strpos($html, 'dbdb-slide-counter') !== false) return $html; // avoid double inject
    $total = max(0, (int) $total);
    $counter = '<div class="dbdb-slide-counter"><span class="dbdb-slide-counter-active">1</span> ' . esc_html__('of', 'divi-booster') . ' <span class="dbdb-slide-counter-total">' . intval($total) . '</span></div>';
    return preg_replace('/<\/div>\s*$/s', $counter . '</div>', $html, 1);
}
function ensure_scripts_enqueued_once() {
    if (!has_action('wp_footer', __NAMESPACE__ . '\\output_scripts_once')) {
        add_action('wp_footer', __NAMESPACE__ . '\\output_scripts_once');
    }
}

// === Divi 4 Output Filter ===
add_filter('et_module_shortcode_output', __NAMESPACE__ . '\\d4_output_filter', 10, 3);
function d4_output_filter($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }
    if (is_builder_active()) {
        return $output;
    }
    $props = $module->props;
    if (!should_show_counter($props)) {
        return $output;
    }
    $output = add_feature_class_to_wrapper($output);
    $total = count_total_slides_from_html($output);
    $output = inject_counter_markup($output, $total);
    ensure_scripts_enqueued_once();
    return $output;
}

// === Front-end JS & CSS (Once) ===
function output_scripts_once() {
    static $done = false;
    if ($done) return; $done = true;
?>
<style>
    .dbdb-gallery-with-image-count .dbdb-slide-counter { position: absolute; width: 100%; text-align: center; left: 0; bottom: 0; transform: translateY(100%); color: #666 !important; }
    .dbdb-gallery-with-image-count { overflow: visible !important; }
    .dbdb-gallery-with-image-count .et_pb_gallery_items { overflow: hidden; }
    /* Fix divi gallery layout change on first slide change bug (as this causes the counter to jump too) */
    .dbdb-gallery-with-image-count .et_pb_gallery_item.et_slide_transition { display: block !important; }
</style>
<script>
(function($){
    $(function(){
        function updateCounter($gallery){
            setTimeout(function(){
                var $items = $gallery.find('.et_pb_gallery_items .et_pb_gallery_item');
                if (!$items.length) return;
                var idx = $items.filter('.et-pb-active-slide').index();
                var current = (idx >= 0 ? idx + 1 : 1);
                $gallery.find('.dbdb-slide-counter-active').text(current);
                $gallery.find('.dbdb-slide-counter-total').text($items.length);
            }, 50);
        }
        function triggerChanged($gallery){ $gallery.trigger('divi-booster:gallery-slide-changed'); }

        $('.dbdb-gallery-with-image-count').each(function(){
            var $g = $(this);
            updateCounter($g);
            // Observe class changes to catch autoplay / JS-driven transitions
            var target = $g.find('.et_pb_gallery_items')[0];
            if (target && 'MutationObserver' in window) {
                var mo = new MutationObserver(function(){ updateCounter($g); });
                mo.observe(target, { subtree:true, attributes:true, attributeFilter:['class'] });
            }
        });

        // Arrow or dot interactions
        $(document).on('mouseup', '.dbdb-gallery-with-image-count .et-pb-slider-arrows a, .dbdb-gallery-with-image-count .et-pb-controllers a', function(){
            var $gallery = $(this).closest('.dbdb-gallery-with-image-count');
            triggerChanged($gallery);
        });

        // Shared custom event
        $(document).on('divi-booster:gallery-slide-changed', '.dbdb-gallery-with-image-count', function(){
            updateCounter($(this));
        });
    });
})(jQuery);
</script>
<?php
}


// === Divi 5: Attribute Registration (Block metadata fallback) ===
add_filter('block_type_metadata_settings', __NAMESPACE__ . '\\d5_register_block_metadata');
function d5_register_block_metadata($settings) {
    $module_name = $settings['name'] ?? '';
    if ($module_name !== DIVI5_MODULE_SLUG) return $settings;
    if (!isset($settings['attributes']) || !is_array($settings['attributes'])) return $settings;
    $settings['attributes'][DIVI5_SETTING_SLUG]  = get_d5_toggle_attr_definition();
    $settings['attributes'][ADVANCED_FIELD_SLUG] = get_d5_font_attr_definition();
    return $settings;
}


function get_d5_toggle_attr_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'sliderImageCountToggle' => [
                        'groupSlug'   => 'contentElements',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => __('Show Slider Image Count', 'divi-booster'),
                        'description' => __('Display current image number / total images below the slider.', 'divi-booster'),
                        'features'    => [ 'hover' => false, 'sticky' => false, 'responsive' => false, 'preset' => 'elements' ],
                        'render'      => true,
                        'priority'    => 98,
                        'component'   => [ 'type' => 'field', 'name' => 'divi/toggle' ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => 'off' ] ],
                        'showIf'      => [ 'fullwidth' => [ 'desktop' => [ 'value' => 'on' ] ] ],
                        'options'     => [ 'on' => __('Yes', 'divi-booster'), 'off' => __('No', 'divi-booster') ],
                    ],
                ],
            ],
        ],
    ];
}

function get_d5_font_attr_definition() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}} .dbdb-slide-counter',
        'settings' => [
            'decoration' => [
                'font' => [
                    'groupType' => 'group-item',
                    'item'      => [
                        'groupSlug' => 'designImageCount',
                        'render'    => true,
                        'component' => [
                            'name' => 'divi/font',
                            'type' => 'group',
                            'props' => [
                                'grouped'     => false,
                                'fieldLabel'  => __('Slider Image Count', 'divi-booster'),
                                'defaultGroupAttr' => [ 'font' => [ 'desktop' => [ 'value' => [ ] ] ] ]
                            ],
                        ],
                    ],
                ],
            ],
        ],
        'styleProps' => [
            'font' => [
                'important' => [
                    'font' => [ 'desktop' => [ 'value' => [ 'color' => true ] ] ],
                ],
                'propertySelectors' => [
                    'font' => [
                        'desktop' => [ 'value' => [ 'text-align' => '{{selector}}' ] ],
                    ],
                ],
            ],
        ],
    ];
}

// === Divi 5: VB Attribute & Conversion + Style Container ===
add_action('divi_visual_builder_assets_before_enqueue_scripts', __NAMESPACE__ . '\\enqueue_d5_vb_script');
function enqueue_d5_vb_script() {
    $handle = sanitize_title('divibooster-d5-gallery-slider-image-count');
    wp_register_script($handle, '', ['lodash', 'divi-vendor-wp-hooks'], null, true);
    wp_enqueue_script($handle);
    wp_add_inline_script($handle, get_d5_vb_inline_js());
}
function get_d5_vb_inline_js() {
    $attr_toggle = wp_json_encode(get_d5_toggle_attr_definition());
    $attr_font   = wp_json_encode(get_d5_font_attr_definition());
    $d4slug      = wp_json_encode(DIVI4_MODULE_SLUG);
    $d5_toggle   = wp_json_encode(DIVI5_SETTING_SLUG);
    $adv_key     = wp_json_encode(ADVANCED_FIELD_SLUG);
    return <<<JS
(function(){
  const hooks = window.vendor?.wp?.hooks; if (!hooks) return; const { addFilter } = hooks;
  addFilter('divi.moduleLibrary.moduleAttributes.divi.gallery', 'divi', (attributes) => {
    attributes[{$d5_toggle}] = {$attr_toggle};
    // Add visible callback to sliderImageCountToggle
    if (attributes[{$d5_toggle}]?.settings?.innerContent?.items?.sliderImageCountToggle) {
      attributes[{$d5_toggle}].settings.innerContent.items.sliderImageCountToggle.visible = function({ attrs }) {
        // Only show if fullwidth is on (slider mode)
        return attrs?.module?.advanced?.fullwidth?.desktop?.value === 'on';
      };
    }
    attributes[{$adv_key}]   = {$attr_font};
    return attributes;
  });
  addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (outline, name) => {
    if (name !== {$d4slug}) return outline;
    if (!outline.module) outline.module = {};
    outline.module['dbdb_image_count'] = {$d5_toggle} + '.*';
    if (!outline.advanced) outline.advanced = {};
    if (!outline.advanced.fonts) outline.advanced.fonts = {};
    outline.advanced.fonts[{$adv_key}] = {$adv_key} + '.decoration.font';
    return outline;
  });
  // Add Design group for Image Count
  addFilter('divi.moduleLibrary.moduleSettings.groups.divi.gallery', 'divi', (groups) => {
    groups.designImageCount = {
      groupName: 'designImageCount', panel: 'design', priority: 21, multiElements: true,
      component: { name: 'divi/composite', props: { groupLabel: 'Slider Image Count', visible: ({ attrs }) => {
        return attrs?.module?.advanced?.fullwidth?.desktop?.value === 'on';
      }}}
    };
    return groups;
  });
  // Render advanced font styles in VB
  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 styles = window.vendor.wp.element.createElement(StyleContainer, { key: 'dbdb-image-count-styles', mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false }, moduleElements.style({ attrName: {$adv_key} }));
    return window.vendor.wp.element.cloneElement(moduleWrapper, {}, moduleWrapper.props.children, [ styles ]);
  });
})();
JS;
}

// === Divi 5: PHP conversion outline registration ===
add_filter('divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\\d5_register_conversion_outline', 10, 2);
function d5_register_conversion_outline($outline, $module_name) {
    if ($module_name !== DIVI5_MODULE_SLUG) return $outline;
    if (!isset($outline['module']) || !is_array($outline['module'])) $outline['module'] = array();
    if (!isset($outline['advanced']) || !is_array($outline['advanced'])) $outline['advanced'] = array();
    if (!isset($outline['advanced']['fonts']) || !is_array($outline['advanced']['fonts'])) $outline['advanced']['fonts'] = array();
    $outline['module'][DIVI4_SETTING_SLUG] = DIVI5_SETTING_SLUG . '.*';
    $outline['advanced']['fonts'][ADVANCED_FIELD_SLUG] = ADVANCED_FIELD_SLUG . '.decoration.font';
    return $outline;
}

// === Divi 5: Front-end Styles printing ===
add_filter('divi_module_wrapper_render', __NAMESPACE__ . '\\d5_frontend_styles', 10, 2);
function d5_frontend_styles($module_wrapper, $args) {
    $module_name = $args['name'] ?? '';
    $elements    = $args['elements'] ?? null;
    if ($module_name !== DIVI5_MODULE_SLUG || !$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'        => [ $elements->style([ 'attrName' => ADVANCED_FIELD_SLUG ]) ],
        ]);
    }
    return $module_wrapper;
}

// === Divi 5 Block Output Filter ===
add_filter('render_block_' . DIVI5_MODULE_SLUG, __NAMESPACE__ . '\\d5_output_filter', 10, 3);
function d5_output_filter($block_content, $parsed_block, $block) {
    $attrs = $parsed_block['attrs'] ?? array();
    if (is_builder_active()) return $block_content; // front-end preview only
    if (!should_show_counter($attrs)) return $block_content;
    if (!is_string($block_content) || $block_content === '') return $block_content;
    $block_content = add_feature_class_to_wrapper($block_content);
    $total = count_total_slides_from_html($block_content);
    $block_content = inject_counter_markup($block_content, $total);
    ensure_scripts_enqueued_once();
    return $block_content;
}

// Created at 1756847789.
