<?php
// Divi YouTube Limit Related Videos (to same channel) Feature with Divi 4 and Divi 5 Support + Conversion
namespace DiviBooster\DiviBooster\Modules\Video\YoutubeLimitRelated;

const DIVI5_MODULE_SLUG = 'divi/video';
const DIVI4_MODULE_SLUG = 'et_pb_video';
const DIVI5_SETTING_SLUG = 'diviboosterYoutubeLimitRelated';
const DIVI4_SETTING_SLUG = 'db_limit_youtube_related_videos_to_same_channel';

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());
}
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_script');

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);

add_filter('divi_booster_inline_scripts', function($scripts) {
    $scripts[] = get_inline_js();
    return $scripts;
});

function get_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'youtubeLimitRelatedToggle' => [
                        'groupSlug'   => 'contentVideo',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => 'Limit YouTube Related Videos to Same Channel',
                        'description' => 'Show only related videos from the same channel at the end of YouTube videos.',
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'content',
                        ],
                        'render'   => true,
                        'priority' => 20,
                        'component' => [
                            'type' => 'field',
                            'name' => 'divi/toggle',
                        ],
                    ],
                ],
            ],
        ],
    ];
}

// Adds rel=0 param to YouTube iframes on output if feature is enabled.
function add_youtube_rel_zero($content, $rel_enabled) {
    if ($rel_enabled !== 'on') return $content;
    return preg_replace_callback(
        '/<iframe([^>]+)src="([^"]+)"([^>]*)>/i',
        function($m) {
            $src = $m[2];
            if (strpos($src, 'youtube.com') !== false || strpos($src, 'youtu.be') !== false) {
                $delimiter = (strpos($src, '?') === false) ? '?' : '&';
                // Remove existing rel param
                $src = preg_replace('/([\?&])rel=\d+/', '', $src);
                // Always add rel=0 at end
                $src .= $delimiter . 'rel=0';
                // Avoid duplicate delimiters
                $src = preg_replace('/([\?&]){2,}/', '$1', $src);
                // Clean up any "?&" to just "?"
                $src = str_replace('?&', '?', $src);
            }
            return '<iframe' . $m[1] . 'src="' . $src . '"' . $m[3] . '>';
        },
        $content,
        1
    );
}

// Divi 5 front-end block render filter
add_filter('render_block_' . DIVI5_MODULE_SLUG, function($block_content, $parsed_block, $block) {
    $rel_value = $parsed_block['attrs'][DIVI5_SETTING_SLUG]['desktop']['value'] ?? 'off';
    return add_youtube_rel_zero($block_content, $rel_value);
}, 10, 3);

// Divi 4 classic builder field registration
add_filter('et_pb_all_fields_unprocessed_' . DIVI4_MODULE_SLUG, function($fields) {
    $def = get_attribute_definition();
    $toggle = $def['settings']['innerContent']['items']['youtubeLimitRelatedToggle'];
    $fields[DIVI4_SETTING_SLUG] = [
        'label'           => $toggle['label'],
        'description'     => $toggle['description'],
        'type'            => 'yes_no_button',
        'option_category' => 'configuration',
        'options'         => [
            'on'  => esc_html__('On', 'et_builder'),
            'off' => esc_html__('Off', 'et_builder'),
        ],
        'tab_slug'        => 'general',
        'toggle_slug'     => 'main_content',
        'default'         => 'off',
        'priority'        => $toggle['priority'],
    ];
    return $fields;
});

// Divi 4 front-end output filter
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;
    }
    $rel_value = $module->props[DIVI4_SETTING_SLUG] ?? 'off';
    return add_youtube_rel_zero($output, $rel_value);
}, 10, 3);

