<?php
namespace DiviBooster\DiviBooster\Modules\Accordion\InitialState;

const DIVI4_MODULE_SLUG = 'et_pb_accordion';
const DIVI5_MODULE_SLUG = 'divi/accordion';
const DIVI4_SETTING_SLUG = 'db_initial_state';
const DIVI5_SETTING_SLUG = 'dbInitialState';

// ===============
// Divi 5 Attribute Registration and Conversion
// ===============
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_script');
function enqueue_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);
    wp_register_script($handle, '', ['lodash', 'divi-vendor-wp-hooks'], null, true);
    wp_enqueue_script($handle);
    wp_add_inline_script($handle, get_inline_js());
}

function get_inline_js() {
    $attribute_json = json_encode(get_attribute_definition());
    $divi5_slug = json_encode(DIVI5_MODULE_SLUG);
    $divi4_slug = json_encode(DIVI4_MODULE_SLUG);
    $divi5_setting_slug = json_encode(DIVI5_SETTING_SLUG);
    $divi4_setting_slug = 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;
}

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'     => [
                    'dbInitialStateToggle' => [
                        'groupSlug'   => 'designToggle',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => 'Initial State',
                        'description' => 'Set the initial open / closed state of the accordion.',
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'advanced',
                        ],
                        'render'   => true,
                        'priority' => 20,
                        'component' => [
                            'type' => 'field',
                            'name' => 'divi/select',
                            'props' => [
                                'options' => [
                                    'default' => [
                                        'label' => 'Default',
                                    ],
                                    'all_closed' => [
                                        'label' => 'All Closed',
                                    ],
                                    'all_open' => [
                                        'label' => 'All Open',
                                    ],
                                ],
                            ],
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => 'default' ] ],
                    ],
                ],
            ],
        ],
    ];
}

// =====================
// Shared: Output utility
// =====================
function add_initial_state_code_to_content($content, $state) {
    $order_class = get_order_class_from_content($content);
    if (!$order_class) { return $content; }
    $js = '';
    if ($state === 'all_closed') {
        $js .= js_all_closed($order_class);
        $hide_flash_of_toggle_content = "<style>.{$order_class} .et_pb_toggle_content { display: none; }</style>";
        $content = $hide_flash_of_toggle_content . $content;
    } elseif ($state === 'all_open') {
        $js .= js_all_open($order_class);
    }
    if (!empty($js)) {
        $content .= '<script data-name="dbdb-accordion-initial-state">' . $js . '</script>';
    }
    return $content;
}

function js_all_closed($order_class) {
    return <<<END
jQuery(function($){
    $('.et_pb_accordion.{$order_class} .et_pb_toggle_open').toggleClass('et_pb_toggle_open et_pb_toggle_close');
    $('.et_pb_accordion.{$order_class} .et_pb_toggle').click(function() {
      var toggle = $(this);
      setTimeout(function(){
         toggle.closest('.et_pb_accordion').removeClass('et_pb_accordion_toggling');
      },700);
    });
});
END;
}

function js_all_open($order_class) {
    return <<<END
jQuery(function($){
    $('.et_pb_accordion.{$order_class} .et_pb_toggle_close').toggleClass('et_pb_toggle_open et_pb_toggle_close');
    $('.et_pb_accordion.{$order_class} .et_pb_toggle').click(function() {
      var toggle = $(this);
      setTimeout(function(){
         toggle.closest('.et_pb_accordion').removeClass('et_pb_accordion_toggling');
      },700);
    });
});
END;
}

// Get the order class from a list of module classes
// Return false if no order class found
function get_order_class_from_content($content) {
    $module_slug = DIVI4_MODULE_SLUG;
    $classes = get_classes_from_content($content);
    foreach ($classes as $class) {
        if (preg_match("#^{$module_slug}_\d+(_tb_header|_tb_footer)?$#", $class)) {
            return $class;
        }
    }
    return false;
}

// get the classes assigned to the module
function get_classes_from_content($content) {
    // Match the first div with a class containing 'et_pb_accordion' and 'et_pb_module'
    if (preg_match('#<div [^>]*class="([^"]*\bet_pb_accordion\b[^"]*\bet_pb_module\b[^"]*)"#', $content, $m)) {
        $classes = explode(' ', trim($m[1]));
        return $classes;
    }
    // Fallback: match any div with 'et_pb_module'
    if (preg_match('#<div [^>]*class="([^"]*\bet_pb_module\b[^"]*)"#', $content, $m)) {
        $classes = explode(' ', trim($m[1]));
        return $classes;
    }
    return array();
}

// =====================
// Divi 4 Classic Builder Integration
// =====================
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\\add_divi4_field');
function add_divi4_field($fields) {
    $fields[DIVI4_SETTING_SLUG] = array(
        'label' => 'Initial State',
        'type' => 'select',
        'option_category' => 'layout',
        'options' => array(
            'default'   => esc_html__( 'Default', 'et_builder' ),
            'all_closed'  => esc_html__( 'All Closed', 'et_builder' ),
            'all_open' => esc_html__( 'All Open', 'et_builder' ),
        ),
        'description' => 'Set the initial open / closed state of the accordion.',
        'default' => 'default',
        'tab_slug'          => 'advanced',
        'toggle_slug'       => 'toggle_layout',
    );
    return $fields;
}

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;
    }
    $state = $module->props[DIVI4_SETTING_SLUG] ?? 'default';
    return add_initial_state_code_to_content($output, $state);
}, 10, 3);

// =====================
// Divi 5 Block Output Filter
// =====================
add_filter('render_block_' . DIVI5_MODULE_SLUG, function($block_content, $parsed_block, $block) {
    $state = $parsed_block['attrs'][DIVI5_SETTING_SLUG]['desktop']['value'] ?? 'default';
    return add_initial_state_code_to_content($block_content, $state);
}, 10, 3);
