<?php // https://divibooster.com/make-divi-accordion-module-closable/
namespace DiviBooster\DiviBooster\Modules\Accordion\Closeable;

const DIVI5_MODULE_SLUG = 'divi/accordion';
const DIVI4_MODULE_SLUG = 'et_pb_accordion';
const DIVI5_SETTING_SLUG = 'diviboosterCloseable';
const DIVI4_SETTING_SLUG = 'db_closeable';

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

add_filter('et_pb_module_shortcode_attributes', __NAMESPACE__ . '\\dbmo_et_pb_accordion_item_inherit_closed_icon_styles', 10, 3);

function dbmo_et_pb_accordion_item_inherit_closed_icon_styles($props, $attrs, $render_slug) {
    if ($render_slug !== 'et_pb_accordion_item' || !is_array($props)) { return $props; }
    foreach(array('icon_color', 'use_icon_font_size', 'icon_font_size') as $prefix) {
        foreach($props as $k=>$v) {
            if (strpos($k, $prefix) === 0) {
                $props["open_{$k}"] = $v;
            }
        }
    }
    return $props;
}

// Divi 5: Add attribute definition and conversion (builder/editor side)
function enqueue_divi5_conversion_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 . '-' . DIVI5_SETTING_SLUG);
    \dbdb_enqueue_inline_script_if_dependencies_available($handle, get_divi5_conversion_js(), array('lodash', array('divi-vendor-wp-hooks', 'wp-hooks')));
}
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_divi5_conversion_script');

function get_divi5_conversion_js() {
    $attribute_json = wp_json_encode(get_attribute_definition());
    $divi5_slug = wp_json_encode(DIVI5_MODULE_SLUG);
    $divi4_slug = wp_json_encode(DIVI4_MODULE_SLUG);
    $divi5_setting_slug = wp_json_encode(DIVI5_SETTING_SLUG);
    $divi4_setting_slug = wp_json_encode(DIVI4_SETTING_SLUG);
    return <<<END
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleMapping', 'divi', modules => {
    const path = [{$divi5_slug}, 'metadata', 'attributes'];
    const { set, get, has } = window.lodash;
    const target = get(modules, path) ? get(modules, path) : set(modules, path, {});
    if (has(modules, path)) {
        target[{$divi5_setting_slug}] = $attribute_json;
    }
    return modules;
});
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (conversionOutline, name) => {
    if (name !== {$divi4_slug}) return conversionOutline;
    conversionOutline.module[{$divi4_setting_slug}] = {$divi5_setting_slug} + '.*';
    return conversionOutline;
});
END;
}

// Divi 5: Register custom attribute in module attrs
add_filter('divi_module_library_register_module_attrs', function($module_attrs, $filter_args) {
    if (($filter_args['name'] ?? '') !== DIVI5_MODULE_SLUG) {
        return $module_attrs;
    }
    $module_attrs[DIVI5_SETTING_SLUG] = get_attribute_definition();
    return $module_attrs;
}, 10, 2);

function get_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'closeableToggle' => [
                        'groupSlug'   => 'designToggle',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => 'Closeable',
                        'description' => 'Choose whether individual accordion toggles can be closed.',
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'content',
                        ],
                        'render'   => true,
                        'priority' => 20,
                        'component' => [
                            'type' => 'field',
                            'name' => 'divi/toggle',
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => 'off' ] ],
                    ],
                ],
            ],
        ],
    ];
}

// Divi 4: Add field to options panel
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\\add_closeable_field_divi4', 10, 2);
function add_closeable_field_divi4($fields) {
    $def = get_attribute_definition();
    $toggle = $def['settings']['innerContent']['items']['closeableToggle'];
    $fields[DIVI4_SETTING_SLUG] = [
        'label'           => $toggle['label'],
        'description'     => $toggle['description'],
        'type'            => 'yes_no_button',
        'option_category' => 'configuration',
        'options'         => [
            'off' => esc_html__('No', 'et_builder'),
            'on'  => esc_html__('Yes', 'et_builder'),
        ],
        'tab_slug'        => 'advanced',
        'toggle_slug'     => 'toggle_layout',
        'default'         => 'off',
        'priority'        => $toggle['priority'],
    ];
    return $fields;
}

// Field needs to be whitelisted (handled by Divi 4, no longer needed Divi 5)
// Divi 5: No whitelist necessary

// COMMON: Helper to inject JS/CSS for closeable accordions
function inject_closeable_js_and_css($output, $order_class) {
    $js = js_closeable($order_class);
    $css = css_closeable($order_class);
    if (!empty($css)) { $output.="<style>$css</style>"; }
    if (!empty($js)) { $output.="<script>$js</script>"; }
    return $output;
}
function js_closeable($order_class) {
    return <<<END
jQuery(function($){
  $('.{$order_class} .et_pb_toggle_title').click(function(){
    var toggle = $(this).closest('.et_pb_toggle');
    if (!toggle.hasClass('et_pb_accordion_toggling')) {
      var accordion = toggle.closest('.et_pb_accordion');
      if (toggle.hasClass('et_pb_toggle_open')) {
        accordion.addClass('et_pb_accordion_toggling');
        toggle.find('.et_pb_toggle_content').slideUp(700, function() { 
          toggle.toggleClass('et_pb_toggle_open et_pb_toggle_close'); 
        });
      }
      setTimeout(function(){ 
        accordion.removeClass('et_pb_accordion_toggling'); 
      }, 750);
    }
  });
});
END;
}
function css_closeable($order_class) {
    return <<<END
.{$order_class} .et_pb_toggle_open .et_pb_toggle_title:before {
	display: block !important;
	content: "\\e04f";
}
END;
}

// Divi 4: Render filter for shortcode output
add_filter('et_module_shortcode_output', function($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props)) {
        return $output;
    }
    // Add a unique class for this accordion instance
    $order_class = '';
    if (preg_match('/class=["\']([^"\']*)["\']/', $output, $match)) {
        $classes = preg_split('/\s+/', $match[1]);
        foreach ($classes as $c) {
            if (strpos($c, 'et_pb_accordion_') === 0) {
                $order_class = $c;
                break;
            }
        }
    }
    if (!$order_class) { return $output; }

    // Check global closeable option
    $globallyCloseable = function_exists('dbdb_option') ? dbdb_option('106-make-accordions-closable', 'enabled') : false;

    $is_closeable = $module->props[DIVI4_SETTING_SLUG] ?? 'off';
    if (!$globallyCloseable && $is_closeable === 'on') {
        $output = inject_closeable_js_and_css($output, $order_class);
    }
    return $output;
}, 10, 3);

// Divi 5: Render filter for block output
add_filter('render_block_' . DIVI5_MODULE_SLUG, function($block_content, $parsed_block, $block) {
    // Divi 5 block always adds a unique class to its wrapper: e.g. et_pb_accordion_xxx
    $order_class = '';
    if (preg_match('/class=["\']([^"\']*)["\']/', $block_content, $match)) {
        $classes = preg_split('/\s+/', $match[1]);
        foreach ($classes as $c) {
            if (strpos($c, 'et_pb_accordion_') === 0) {
                $order_class = $c;
                break;
            }
        }
    }
    if (!$order_class) { return $block_content; }

    // Check global closeable option
    $globallyCloseable = function_exists('dbdb_option') ? dbdb_option('106-make-accordions-closable', 'enabled') : false;

    $is_closeable = $parsed_block['attrs'][DIVI5_SETTING_SLUG]['desktop']['value'] ?? 'off';
    if (!$globallyCloseable && $is_closeable === 'on') {
        $block_content = inject_closeable_js_and_css($block_content, $order_class);
    }
    return $block_content;
}, 10, 3);

