<?php
namespace DiviBooster\DiviBooster\Modules\PostTitle\Tags;

// Constants
const DIVI4_MODULE_SLUG = 'et_pb_post_title';
const DIVI5_MODULE_SLUG = 'divi/post-title';
const DIVI4_SETTING_SLUG = 'dbdb_show_tags';
const DIVI5_SETTING_SLUG = 'diviboosterShowTags';

// Register filters / hooks at top-level
if (function_exists('add_filter')) {
    // Divi 4: Field registration
    add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, __NAMESPACE__ . '\\d4_register_field');

    // Divi 4: Toggle check via filter (back-compat)
    add_filter('dbdbptst_show_tags', __NAMESPACE__ . '\\d4_enabled_based_on_setting', 10, 2);

    // Divi 4: Output filter
    add_filter('et_module_shortcode_output', __NAMESPACE__ . '\\d4_output_filter', 10, 3);

    // Divi 5: Register custom attribute in module library (PHP)
    // Divi 5: Attribute registration (front-end PHP) via block_type_metadata_settings
    add_filter('block_type_metadata_settings', __NAMESPACE__ . '\\d5_block_type_metadata_settings', 10, 2);

    // Divi 5: Front-end render filter
    add_filter('render_block_' . DIVI5_MODULE_SLUG, __NAMESPACE__ . '\\d5_render_filter', 10, 3);

    // Divi 5: Conversion outline mapping (PHP)
    add_filter('divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\\d5_conversion_outline', 10, 2);
}

// Enqueue a tiny builder mapping to ensure the attribute appears in Divi 5 Visual Builder UI
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_builder_mapping_script');

// ===== Divi 4 Implementation =====
function d4_register_field($fields) {
    if (isset($fields['meta']['affects']) && is_array($fields['meta']['affects'])) {
        $fields['meta']['affects'][] = DIVI4_SETTING_SLUG;
    }

    // Preserve existing field definition and enhance with show_if for better UI.
    $fields = $fields + array(
        DIVI4_SETTING_SLUG => array(
            'label'             => esc_html__( 'Show Post Tags', 'et_builder' ),
            'type'              => 'yes_no_button',
            'option_category'   => 'configuration',
            'options'           => array(
                'on'  => esc_html__( 'Yes', 'et_builder' ),
                'off' => esc_html__( 'No', 'et_builder' ),
            ),
            'default_on_front'  => 'off',
            'depends_show_if'   => 'on',
            'toggle_slug'       => 'elements',
            'description'       => esc_html__( 'Here you can choose whether or not display the Tags in Post Meta.', 'et_builder' ),
            'mobile_options'    => true,
            'hover'             => 'tabs',
            'show_if'           => array(
                'meta' => 'on',
            ),
        ),
    );

    return $fields;
}

function d4_enabled_based_on_setting($enabled, $module) {
    return (isset($module->props) && isset($module->props[DIVI4_SETTING_SLUG]) && $module->props[DIVI4_SETTING_SLUG] === 'on');
}

function d4_output_filter($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props)) {
        return $output;
    }

    if (!d4_show_meta($module) || !d4_show_tags($module)) {
        return $output;
    }
    $output = ensure_meta_container_exists($output);
    $output = preg_replace_callback('/(<p class="[^"]*et_pb_title_meta_container[^"]*">)(.*?)(<\/p>)/', __NAMESPACE__ . '\\add_tags_to_meta', $output);

    // Per-instance CSS for comma separators
    if (is_callable('ET_Builder_Element::set_style')) {
        \ET_Builder_Element::set_style($render_slug, array(
            'selector'    => '%%order_class%% .dbdb_posttitle_tags a:not(:last-child):after',
            'declaration' => 'content: ",";',
        ));
    }

    return $output;
}

function d4_show_tags($module) {
    return apply_filters('dbdbptst_show_tags', true, $module);
}

function d4_show_meta($module) {
    return (isset($module->props) && isset($module->props['meta']) && $module->props['meta'] === 'on');
}

// ===== Divi 5 Implementation =====
function d5_block_type_metadata_settings($settings, $metadata = null) {
    $module_name       = $settings['name'] ?? '';
    $module_attributes = $settings['attributes'] ?? false;
    if ($module_name !== DIVI5_MODULE_SLUG) {
        return $settings;
    }
    if (!$module_attributes) {
        return $settings;
    }
    // Register the custom attribute for showing tags in Post Title (Divi 5 front-end)
    $settings['attributes'][ DIVI5_SETTING_SLUG ] = get_divi5_attribute_definition();
    return $settings;
}

function d5_render_filter($block_content, $parsed_block, $block) {
    // Check setting values
    $show_tags = $parsed_block['attrs'][DIVI5_SETTING_SLUG]['desktop']['value'] ?? 'off';
    if ($show_tags !== 'on') {
        return $block_content;
    }

    if (!d5_is_meta_enabled($parsed_block, $block_content)) {
        return $block_content;
    }

    $html = ensure_meta_container_exists($block_content);
    $html = preg_replace_callback('/(<p class="[^"]*et_pb_title_meta_container[^"]*">)(.*?)(<\/p>)/', __NAMESPACE__ . '\\add_tags_to_meta', $html);

    // Add per-instance CSS for separators
    $order_class = extract_order_class($html);
    if ($order_class) {
        $style = '<style>.' . esc_attr($order_class) . ' .dbdb_posttitle_tags a:not(:last-child):after{content:",";}</style>';
        $html .= $style;
    }

    return $html;
}

function d5_conversion_outline($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;
}

// ===== Shared Helpers =====
function get_divi5_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'showTagsToggle' => [
                        'groupSlug'   => 'contentElements',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => 'Show Post Tags',
                        'description' => 'Here you can choose whether or not display the Tags in Post Meta.',
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'content',
                        ],
                        'render'   => true,
                        'priority' => 36,
                        'component' => [
                            'type' => 'field',
                            'name' => 'divi/toggle',
                        ],
                        // Ensure default value exists for migrator / builder visibility
                        'defaultAttr' => [ 'desktop' => [ 'value' => 'off' ] ],
                    ],
                ],
            ],
        ],
    ];
}

function ensure_meta_container_exists($html) {
    $meta_container_regex = '/(<p class="[^"]*et_pb_title_meta_container[^"]*">)(.*?)(<\/p>)/';
    if (!preg_match($meta_container_regex, $html)) {
        $html = preg_replace(
            '/(<div class="et_pb_title_container">)(.*?)(<\/div>)/s',
            '\\1\\2<p class="et_pb_title_meta_container"></p>\\3',
            $html
        );
    }
    return $html;
}

function add_tags_to_meta($match) {
    if (!is_array($match) || !isset($match[1], $match[2], $match[3])) {
        return isset($match[0]) ? $match[0] : '';
    }

    $post_type = get_post_type();
    $taxonomy  = ($post_type === 'project') ? 'project_tag' : 'post_tag';

    $tags = get_the_term_list(get_the_id(), $taxonomy, '', ' ', '');
    if ($tags && !is_wp_error($tags)) {
        return $match[1] . $match[2] . '<span class="dbdb_posttitle_tags_separator"> | </span><span class="dbdb_posttitle_tags">' . $tags . '</span>' . $match[3];
    }

    return $match[0];
}

function d5_is_meta_enabled($parsed_block, $html) {
    $val = $parsed_block['attrs']['meta']['advanced']['showMeta']['desktop']['value'] ?? null;
    if ($val === 'on') {
        return true;
    }
    if ($val === 'off') {
        return false;
    }
    // Fallback to presence of meta container in output
    return (bool) preg_match('/<p class="[^"]*et_pb_title_meta_container[^"]*">/', $html);
}

function extract_order_class($html) {
    if (!is_string($html) || $html === '') {
        return '';
    }
    if (!preg_match('/<div[^>]+class="([^"]*\bet_pb_post_title\b[^"]*)"[^>]*>/', $html, $m)) {
        return '';
    }
    $classes = preg_split('/\s+/', $m[1]);
    if (!is_array($classes)) {
        return '';
    }
    foreach ($classes as $c) {
        if (strpos($c, 'et_pb_post_title_') === 0) {
            return $c;
        }
    }
    return '';
}

// ===== Divi 5 VB Mapping (JS injection) =====
function enqueue_builder_mapping_script() {
        // Only in Divi 5 Visual Builder
        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 . '-' . 'post-title-tags');
        \dbdb_enqueue_inline_script_if_dependencies_available($handle, get_inline_mapping_js(), array('lodash', array('divi-vendor-wp-hooks', 'wp-hooks')));
}

function get_inline_mapping_js() {
        $defs = json_encode([ DIVI5_SETTING_SLUG => get_divi5_attribute_definition() ]);
        $divi5_slug = json_encode(DIVI5_MODULE_SLUG);
        return <<<JS
(function(){
    var hooks = (window.vendor && window.vendor.wp && window.vendor.wp.hooks) ? window.vendor.wp.hooks : null;
    if(!hooks) return;
    hooks.addFilter('divi.moduleLibrary.moduleMapping', 'divi', function(modules){
        var path = [{$divi5_slug}, 'metadata', 'attributes'];
        var lodash = window.lodash || window._;
        if(!lodash) return modules;
        var set = lodash.set, get = lodash.get, has = lodash.has;
        var defs = {$defs};
        var target = get(modules, path) ? get(modules, path) : set(modules, path, {});
        if (has(modules, path)) {
            Object.keys(defs).forEach(function(key){ target[key] = defs[key]; });
        }
        return modules;
    });
})();
JS;
}

// Created at 1762913490.

