<?php

namespace DiviBooster\GalleryBooster\LightboxArrowStyles;

// === Constants ===
const DIVI4_MODULE_SLUG      = 'et_pb_gallery';
const DIVI5_MODULE_SLUG      = 'divi/gallery';
const DIVI4_ADV_FONTS_SLUG   = 'dbdb_lightbox_arrows';
const DIVI5_ATTR_SLUG        = 'diviboosterLightboxArrows';

// === Hook Registration ===
if (function_exists('add_filter')) {
    // Divi 4: Advanced fonts group
    \add_filter('et_pb_gallery_advanced_fields', __NAMESPACE__ . '\\add_advanced_fields', 10, 3);

    // Divi 4: Output processing (opacity fix + enqueue body-class script)
    \add_filter('et_module_shortcode_output', __NAMESPACE__ . '\\divi4_output', 10, 3);

    // Divi 5: Output processing (per-instance CSS + opacity fix + enqueue body-class script)
    \add_filter('render_block_' . DIVI5_MODULE_SLUG, __NAMESPACE__ . '\\divi5_output', 10, 3);

    // Divi 5: PHP conversion outline registration (fonts mapping)
    \add_filter('divi.moduleLibrary.conversion.moduleConversionOutline', __NAMESPACE__ . '\\register_divi5_conversion_outline', 10, 2);

    // Divi 5: Register attribute in block metadata (front-end)
    \add_filter('block_type_metadata_settings', function($settings) {
        $module_name       = $settings['name'] ?? '';
        $module_attributes = $settings['attributes'] ?? false;
        if ($module_name !== DIVI5_MODULE_SLUG) {
            return $settings;
        }
        if (!$module_attributes) {
            return $settings;
        }
        $settings['attributes'][DIVI5_ATTR_SLUG] = get_divi5_attribute_definition();
        return $settings;
    });

    // Divi 5: Front-end styles via Style::add
    add_filter('divi_module_wrapper_render', function($module_wrapper, $args) {
        $module_name     = $args['name'] ?? '';
        $module_elements = $args['elements'] ?? null;
        if ($module_name !== DIVI5_MODULE_SLUG || !$module_elements) {
            return $module_wrapper;
        }
        if (is_callable('\\ET\\Builder\\FrontEnd\\Module\\Style::add')) {
            \ET\Builder\FrontEnd\Module\Style::add([
                'id'            => $args['id'] ?? '',
                'name'          => $module_name,
                'orderIndex'    => $args['orderIndex'] ?? 0,
                'storeInstance' => $args['storeInstance'] ?? 0,
                'styles'        => [
                    $module_elements->style(['attrName' => DIVI5_ATTR_SLUG])
                ],
            ]);
        }
        return $module_wrapper;
    }, 10, 2);
}

if (function_exists('add_action')) {
    // Divi 5: VB-only JS for attribute + group + conversion mapping
    \add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_divi5_vb_js');
}

// === Divi 4 Advanced Fonts Group ===
function add_advanced_fields($fields, $slug, $main_css_element) {
    if (!is_array($fields)) {
        return $fields;
    }
    if (!isset($fields['fonts']) || !is_array($fields['fonts'])) {
        $fields['fonts'] = array();
    }

    // Derive order class placeholder (e.g. %%order_class%%)
    $order_class = preg_replace('/\.[^\.]+$/', '', (string) $main_css_element);

    // Keep existing implementation and selectors
    $fields['fonts'][DIVI4_ADV_FONTS_SLUG] = array(
        'label'            => esc_html__('Lightbox Arrows', 'divi-booster'),
        'css'              => array(
            'main'         => "{$order_class}_dbdb_lightbox_open .mfp-gallery .mfp-arrow:after",
            'hover'        => "{$order_class}_dbdb_lightbox_open .mfp-gallery .mfp-arrow:hover:after",
            'text_shadow'  => "{$order_class}_dbdb_lightbox_open .mfp-gallery .mfp-arrow:after",
            'important'    => array('text_shadow'),
        ),
        'hide_text_align'   => true,
        'hide_font'         => true,
        'hide_line_height'  => true,
        'hide_letter_spacing' => true,
        'font_size'         => array(
            'default' => '48px',
        ),
    );

    return $fields;
}

// === Divi 4 Output Processing ===
function divi4_output($output, $render_slug, $module) {
    if (!is_string($output) || $render_slug !== DIVI4_MODULE_SLUG || !isset($module->props) || !is_array($module->props)) {
        return $output;
    }

    // Opacity fix when custom arrows color is set
    $props = $module->props;
    if (!empty($props['dbdb_lightbox_arrows_text_color'])) {
        if (class_exists('ET_Builder_Element') && is_callable(array('ET_Builder_Element', 'set_style'))) {
            \ET_Builder_Element::set_style(
                $render_slug,
                array(
                    'selector'    => '%%order_class%%_dbdb_lightbox_open .mfp-gallery .mfp-arrow',
                    'declaration' => 'opacity: 1 !important;'
                )
            );
        }
    }

    // Ensure body-class JS is present once
    if (!has_action('wp_footer', __NAMESPACE__ . '\\output_body_class_script_once')) {
        \add_action('wp_footer', __NAMESPACE__ . '\\output_body_class_script_once');
    }

    return $output;
}

// === Divi 5 Output Processing ===
function divi5_output($block_content, $parsed_block, $block) {
    $order_class = extract_order_class_from_html($block_content);
    if ($order_class === '') {
        return $block_content;
    }

    $attrs = isset($parsed_block['attrs']) && is_array($parsed_block['attrs']) ? $parsed_block['attrs'] : array();

    // Opacity fix when custom arrows color is set
    if (divi5_attr_has_custom_color($attrs)) {
        $css = '.' . $order_class . '_dbdb_lightbox_open .mfp-gallery .mfp-arrow{opacity:1!important;}';
        $block_content .= '<style>' . $css . '</style>';
    }

    // Ensure body-class JS is present once
    if (!has_action('wp_footer', __NAMESPACE__ . '\\output_body_class_script_once')) {
        \add_action('wp_footer', __NAMESPACE__ . '\\output_body_class_script_once');
    }

    return $block_content;
}

// === Divi 5: Conversion Outline Registration (PHP fallback) ===
function register_divi5_conversion_outline($conversion_outline, $module_name) {
    if ($module_name !== DIVI5_MODULE_SLUG) {
        return $conversion_outline;
    }
    if (!isset($conversion_outline['advanced']) || !is_array($conversion_outline['advanced'])) {
        $conversion_outline['advanced'] = array();
    }
    if (!isset($conversion_outline['advanced']['fonts']) || !is_array($conversion_outline['advanced']['fonts'])) {
        $conversion_outline['advanced']['fonts'] = array();
    }
    // Map Divi 4 advanced fonts group -> Divi 5 attribute font path
    $conversion_outline['advanced']['fonts'][DIVI4_ADV_FONTS_SLUG] = DIVI5_ATTR_SLUG . '.decoration.font';
    return $conversion_outline;
}

// === Divi 5: VB-only JS (attribute + group + conversion mapping) ===
function enqueue_divi5_vb_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_ATTR_SLUG);
    \wp_register_script($handle, '', array('lodash', 'divi-vendor-wp-hooks'), null, true);
    \wp_enqueue_script($handle);
    \wp_add_inline_script($handle, get_divi5_inline_js());
}

function get_divi5_inline_js() {
    $attr_def = wp_json_encode(get_divi5_attribute_definition());
    $d4fonts  = wp_json_encode(DIVI4_ADV_FONTS_SLUG);
    $d5attr   = wp_json_encode(DIVI5_ATTR_SLUG);
    $d4slug   = wp_json_encode(DIVI4_MODULE_SLUG);
    return <<<JS
// Register custom attribute on Gallery module
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleAttributes.divi.gallery', 'divi', (attributes) => {
    attributes[{$d5attr}] = {$attr_def};
    // Visibility: only when lightbox likely in use (layout not slider and lightbox not disabled)
    try {
        const item = attributes[{$d5attr}]?.settings?.decoration?.font?.item;
        if (item) {
            item.visible = function({ attrs }) {
                const layout = attrs?.module?.advanced?.fullwidth?.desktop?.value;
                const lb = attrs?.diviboosterShowInLightbox?.desktop?.value ?? attrs?.diviboosterShowInLightbox?.value;
                const layoutOk = layout !== 'on';
                const lightboxOk = (typeof lb === 'undefined') ? true : lb !== 'off';
                return layoutOk && lightboxOk;
            };
        }
    } catch (e) {}
    return attributes;
});

// Create Design > Lightbox group (Lightbox Arrows)
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.moduleSettings.groups.divi.gallery', 'divi', (groups) => {
  if (!groups.designLightboxArrows) {
    groups.designLightboxArrows = {
      groupName: 'designLightboxArrows',
      panel: 'design',
      priority: 30,
      multiElements: true,
      component: {
        name: 'divi/composite',
        props: {
          groupLabel: 'Lightbox Arrows',
          visible: ({ attrs }) => {
            const layout = attrs?.module?.advanced?.fullwidth?.desktop?.value;
            const lb = attrs?.diviboosterShowInLightbox?.desktop?.value ?? attrs?.diviboosterShowInLightbox?.value;
            const layoutOk = layout !== 'on';
            const lightboxOk = (typeof lb === 'undefined') ? true : lb !== 'off';
            return layoutOk && lightboxOk;
          }
        }
      }
    };
  }
  return groups;
});

// Conversion outline mapping (Divi 4 advanced fonts -> Divi 5 attribute font path)
window.vendor.wp.hooks.addFilter('divi.moduleLibrary.conversion.moduleConversionOutline', 'divi', (outline, name) => {
  if (name !== {$d4slug}) return outline;
  if (!outline.advanced) outline.advanced = {};
  if (!outline.advanced.fonts) outline.advanced.fonts = {};
  outline.advanced.fonts[{$d4fonts}] = {$d5attr} + '.decoration.font';
  return outline;
});

// Ensure builder prints attribute styles (additional StyleContainer)
window.vendor.wp.hooks.addFilter('divi.module.wrapper.render', 'divi', (moduleWrapper, param) => {
  const { name: moduleName, elements: moduleElements, state: moduleState } = param;
  if ('divi/gallery' !== moduleName || !moduleElements) return moduleWrapper;
  const { StyleContainer } = window.divi.module;
  const { isEdited } = moduleWrapper.props;
  const extra = window.vendor.wp.element.createElement(
    StyleContainer,
    { key: 'dbdb-lightbox-arrows-styles', mode: 'builder', state: isEdited ? moduleState : '', noStyleTag: false },
    moduleElements.style({ attrName: {$d5attr} })
  );
  return window.vendor.wp.element.cloneElement(moduleWrapper, {}, moduleWrapper.props.children, [extra]);
});
JS;
}

// === Divi 5: Attribute Definition ===
function get_divi5_attribute_definition() {
    return [
        'type'     => 'object',
        'selector' => '{{selector}}_dbdb_lightbox_open .mfp-gallery .mfp-arrow:after',
        'settings' => [
            'decoration' => [
                'font' => [
                    'groupType' => 'group-item',
                    'item'      => [
                        'groupSlug' => 'designLightboxArrows',
                        'render'    => true,
                        'component' => [
                            'type'  => 'group',
                            'name'  => 'divi/font',
                            'props' => [
                                'grouped'        => false,
                                'fieldLabel'     => __('Lightbox Arrows', 'divi-gallery-booster'),
                                'defaultGroupAttr' => [
                                    'font' => [
                                        'desktop' => [
                                            'value' => [
                                                'size' => '48px'
                                            ]
                                        ]
                                    ]
                                ],
                                'fields' => [
                                    'lineHeight' => [ 'render' => false ],
                                    'textAlign'  => [ 'render' => false ],
                                    'family'     => [ 'render' => false ],
                                    'weight'     => [ 'render' => false ],
                                    'style'      => [ 'render' => false ],
                                    'letterSpacing' => [ 'render' => false ],
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ],
        'styleProps' => [
            'font' => [
                'important' => [
                    'font' => [
                        'desktop' => [
                            'value' => [
                                'color' => true,
                                'size'  => true
                            ]
                        ]
                    ]
                ],
                'propertySelectors' => [
                    'textShadow' => [
                        'desktop' => [
                            'value' => [
                                'text-shadow' => '{{selector}}_dbdb_lightbox_open .mfp-gallery .mfp-arrow:after'
                            ]
                        ]
                    ]
                ]
            ]
        ],
    ];
}

// === One-time Body Class Toggle Script ===
function output_body_class_script_once() {
    static $done = false;
    if ($done) return;
    $done = true;
    ?>
    <script>
    jQuery(document).ready(function($) {
        function clearDbdbLbOpen() {
            $('body').removeClass(function(index, className) {
                return (className.match(/(^|\s)et_pb_gallery_\d+(?:_[^\s]+)?_dbdb_lightbox_open/g) || []).join(' ');
            });
        }
        $(document).on('click', '.et_pb_gallery .et_pb_gallery_image a', function(){
            clearDbdbLbOpen();
            var $gallery = $(this).closest('.et_pb_gallery');
            if (!$gallery.length) return;
            var classes = ($gallery.attr('class') || '');
            var match = classes.match(/et_pb_gallery_\d+(?:_[^\s]+)?/);
            if (!match) return;
            var orderClass = match[0];
            $('body').addClass(orderClass + '_dbdb_lightbox_open');
        });
        $(document).on('click', '.mfp-close, .mfp-bg', function(){ clearDbdbLbOpen(); });
        $(document).on('keyup', function(e){ if (e.key === 'Escape') { clearDbdbLbOpen(); } });
    });
    </script>
    <?php
}

// === Helpers ===
function extract_order_class_from_html($html) {
    if (!is_string($html) || $html === '') return '';
    // Find the first gallery wrapper and its classes
    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 divi5_attr_has_custom_color($attrs) {
    if (!is_array($attrs)) return false;
    if (!isset($attrs[DIVI5_ATTR_SLUG]) || !is_array($attrs[DIVI5_ATTR_SLUG])) return false;
    // Check for color in structured font path
    $p = $attrs[DIVI5_ATTR_SLUG];
    $color = $p['decoration']['font']['font']['desktop']['value']['color'] ??
             $p['decoration']['font']['font']['value']['color'] ??
             $p['decoration']['font']['desktop']['value']['color'] ??
             $p['decoration']['font']['value']['color'] ?? '';
    return (is_string($color) && $color !== '');
}

// Created at 1759214247.
