<?php

namespace DiviBooster\GalleryBooster\GridImageScaling;

// === Constants ===
const DIVI4_MODULE_SLUG = 'et_pb_gallery';
const DIVI5_MODULE_SLUG = 'divi/gallery';
const DIVI4_SETTING_SLUG = 'db_image_object_fit';
const DIVI5_SETTING_SLUG = 'diviboosterImageObjectFit';

// === Divi 4: Register Image Scaling 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__('Image Scaling', 'et_builder'),
        'type'             => 'select',
        'options'          => array(
            'initial' => esc_html__('Fill', 'et_builder'),
            'cover'   => esc_html__('Cover', 'et_builder'),
            'contain' => esc_html__('Fit', 'et_builder'),
            'none'    => esc_html__('Actual Size', 'et_builder'),
        ),
        'default'         => 'initial',
        'option_category' => 'layout',
        'description'     => esc_html__('Choose how the image fills its bounding box.', 'et_builder'),
        'tab_slug'        => 'advanced',
        'toggle_slug'     => 'layout',
        'show_if'         => array('fullwidth' => 'off'),
    );
    return $fields;
}

// === Divi 5 Attribute Registration (JS in VB) ===
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_d5_builder_js');
function enqueue_d5_builder_js() {
    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_d5_inline_js());
}
function get_d5_inline_js() {
    $attr  = wp_json_encode(get_d5_attribute_definition());
    $d4slug = wp_json_encode(DIVI4_MODULE_SLUG);
    $d5key = wp_json_encode(DIVI5_SETTING_SLUG);
    $d4key = wp_json_encode(DIVI4_SETTING_SLUG);
    return <<<JS
(function(){
  const hooks = window.vendor?.wp?.hooks; if (!hooks) return;
  // Register attribute
  hooks.addFilter('divi.moduleLibrary.moduleAttributes.divi.gallery', 'divi', (attributes) => {
    attributes[{$d5key}] = {$attr};
    return attributes;
  });
  // Conversion mapping D4 -> D5
  hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (outline, name) => {
    if (name !== {$d4slug}) return outline;
    if (!outline.module) outline.module = {};
    outline.module[{$d4key}] = {$d5key} + '.*';
    return outline;
  });
})();
JS;
}

// === Divi 5 Attribute Registration (PHP fallback) ===
add_filter('divi_module_library_register_module_attrs', __NAMESPACE__ . '\\register_d5_attribute', 10, 2);
function register_d5_attribute($module_attrs, $filter_args) {
    if (($filter_args['name'] ?? '') !== DIVI5_MODULE_SLUG) {
        return $module_attrs;
    }
    $module_attrs[DIVI5_SETTING_SLUG] = get_d5_attribute_definition();
    return $module_attrs;
}

function get_d5_attribute_definition() {
    return [
        'type'     => 'object',
        'settings' => [
            'innerContent' => [
                'groupType' => 'group-items',
                'items'     => [
                    'imageScaling' => [
                        'groupSlug'   => 'designLayout',
                        'attrName'    => DIVI5_SETTING_SLUG,
                        'label'       => __('Image Scaling', 'et_builder'),
                        'description' => __('Choose how the image fills its bounding box.', 'et_builder'),
                        'features'    => [
                            'hover'      => false,
                            'sticky'     => false,
                            'responsive' => false,
                            'preset'     => 'advanced',
                        ],
                        'showIf' => [
                            'fullwidth' => [ 'desktop' => [ 'value' => 'off' ] ]
                        ],
                        'options'     => [
                            'initial' => [ 'label' => __('Fill', 'et_builder') ],
                            'cover'   => [ 'label' => __('Cover', 'et_builder') ],
                            'contain' => [ 'label' => __('Fit', 'et_builder') ],
                            'none'    => [ 'label' => __('Actual Size', 'et_builder') ],
                        ],
                        'defaultAttr' => [ 'desktop' => [ 'value' => 'initial' ] ],
                        'render'      => true,
                        'priority'    => 99,
                        'component'   => [
                            'type' => 'field',
                            'name' => 'divi/select',
                        ],
                    ],
                ],
            ],
        ],
    ];
}

// === Divi 5: PHP conversion outline fallback ===
add_filter('divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\\register_d5_conversion', 10, 2);
function register_d5_conversion($conversion_outline, $module_name) {
    if ($module_name !== DIVI5_MODULE_SLUG) {
        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 is_grid_layout($props) {
    // Divi 4
    if (isset($props['fullwidth'])) {
        return ($props['fullwidth'] === 'off');
    }
    // Divi 5
    if (isset($props['module']['advanced']['fullwidth']['desktop']['value'])) {
        return ($props['module']['advanced']['fullwidth']['desktop']['value'] === 'off');
    }
    if (isset($props['module']['advanced']['fullwidth']['value'])) {
        return ($props['module']['advanced']['fullwidth']['value'] === 'off');
    }
    return true; // default to grid when unknown
}

function get_image_scaling_value($props) {
    $allowed = array('initial', 'cover', 'contain', 'none'); // No change needed, keys remain the same
    // Divi 4
    if (isset($props[DIVI4_SETTING_SLUG]) && in_array($props[DIVI4_SETTING_SLUG], $allowed, true)) {
        return $props[DIVI4_SETTING_SLUG];
    }
    // Divi 5 (desktop value)
    if (isset($props[DIVI5_SETTING_SLUG]['desktop']['value']) && in_array($props[DIVI5_SETTING_SLUG]['desktop']['value'], $allowed, true)) {
        return $props[DIVI5_SETTING_SLUG]['desktop']['value'];
    }
    // Divi 5 fallback
    if (isset($props[DIVI5_SETTING_SLUG]['value']) && in_array($props[DIVI5_SETTING_SLUG]['value'], $allowed, true)) {
        return $props[DIVI5_SETTING_SLUG]['value'];
    }
    return '';
}

function extract_order_class_from_html($html) {
    if (!is_string($html) || $html === '') return '';
    if (!preg_match('/<div[^>]*class=\"([^\"]*\bet_pb_gallery\b[^\"]*)\"/i', $html, $m)) {
        return '';
    }
    $classes = preg_split('/\s+/', $m[1], -1, PREG_SPLIT_NO_EMPTY);
    foreach ($classes as $c) {
        if (preg_match('/^et_pb_gallery_\d+(?:_[^\s]+)?$/', $c)) {
            return $c;
        }
    }
    if (preg_match('/et_pb_gallery_\d+(?:_[^\s]+)?/', $m[1], $m2)) {
        return $m2[0];
    }
    return '';
}

function build_object_fit_css($order_class, $value) {
    if ($order_class === '' || $value === '') return '';
    $galleryItem = '.' . $order_class . ' .et_pb_gallery_item.et_pb_grid_item';
    $css = $galleryItem . ' .et_pb_gallery_image img { object-fit: ' . esc_attr($value) . ' !important; }';
    return $css;
}

function build_uncrop_script($order_class) {
    if ($order_class === '') return '';
    $galleryItem = '.' . $order_class . ' .et_pb_gallery_item.et_pb_grid_item';
    $selector = esc_js($galleryItem);
    return '<script>jQuery(function($){var items=$("' . $selector . '");items.each(function(){var href=$(this).find("a").attr("href");if(href){$(this).find("a > img").attr("src",href).attr("srcset","").attr("sizes","");}});});</script>';
}

// === Divi 4 Output Filter ===
add_filter('et_module_shortcode_output', __NAMESPACE__ . '\\apply_scaling_divi4', 10, 3);
function apply_scaling_divi4($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }
    $props = $module->props;
    if (!is_grid_layout($props)) {
        return $output;
    }
    
    $value = get_image_scaling_value($props);

    if ($value === '') {
        return $output;
    }
    $order_class = extract_order_class_from_html($output);
    if ($order_class === '') {
        return $output;
    }
    $css = build_object_fit_css($order_class, $value);
    if ($css !== '') {
        $output .= '<style>' . $css . '</style>';
    }
    if ($value !== 'initial') {
        $output .= build_uncrop_script($order_class);
    }
    return $output;
}

// === Divi 5 Output Filter ===
add_filter('render_block_' . DIVI5_MODULE_SLUG, __NAMESPACE__ . '\\apply_scaling_divi5', 10, 3);
function apply_scaling_divi5($block_content, $parsed_block, $block) {
    if (!is_string($block_content)) {
        return $block_content;
    }
    $attrs = isset($parsed_block['attrs']) && is_array($parsed_block['attrs']) ? $parsed_block['attrs'] : array();
    if (!is_grid_layout($attrs)) {
        return $block_content;
    }
    $value = get_image_scaling_value($attrs);
    if ($value === '') {
        return $block_content;
    }
    $order_class = extract_order_class_from_html($block_content);
    if ($order_class === '') {
        return $block_content;
    }
    $css = build_object_fit_css($order_class, $value);
    if ($css !== '') {
        $block_content .= '<style>' . $css . '</style>';
    }
    if ($value !== 'initial') {
        $block_content .= build_uncrop_script($order_class);
    }
    return $block_content;
}

// Created at 1759333088.
