<?php

    // prevent direct file access
	if( !defined( 'ABSPATH' ) ) exit;

    add_action('widgets_init', 'pixe_register_custom_widget_areas');

    if( is_admin() ){
        add_action('admin_init', 'pixe_save_custom_widget_area');
        add_action('wp_ajax_pixe_remove_widget_area', 'pixe_remove_custom_widget_area');
        add_action('admin_print_styles-widgets.php', 'pixe_widget_area_form_styles');
        add_action('admin_print_scripts-widgets.php', 'pixe_widget_area_form_scripts');
    }
    
    // Get widget areas created from the Widgets admin screen.
    function pixe_get_custom_widget_areas(){
        $widget_areas = get_option('pixe_custom_widget_areas', array());

        if( !is_array($widget_areas) ){
            return array();
        }

        return $widget_areas;
    }

    // Register saved custom widget areas with WordPress.
    function pixe_register_custom_widget_areas(){
        $widget_areas = pixe_get_custom_widget_areas();

        if( empty($widget_areas) ){
            return;
        }

        foreach( $widget_areas as $widget_area ){
            if( empty($widget_area['id']) || empty($widget_area['name']) ){
                continue;
            }

            register_sidebar(array(
                'name'          => $widget_area['name'],
                'id'            => $widget_area['id'],
                'description'   => esc_html__('A custom widget area.', 'pixebuilder'),
                'before_widget' => '<div class="widget %2$s">',
                'after_widget'  => '</div>',
                'before_title'  => '<h3 class="widget-title">',
                'after_title'   => '</h3>',
            ));
        }
    }

    // Handle the POST request for adding a new widget area.
    function pixe_save_custom_widget_area(){
        if( empty($_POST['pixe_add_widget_area']) ){
            return;
        }

        if( !current_user_can('edit_theme_options') ){
            wp_die(esc_html__('Sorry, you are not allowed to create widget areas.', 'pixebuilder'));
        }

        check_admin_referer('pixe_add_widget_area', 'pixe_add_widget_area_nonce');

        $widget_name = empty($_POST['pixe_widget_area_name'])? '': sanitize_text_field(wp_unslash($_POST['pixe_widget_area_name']));

        if( empty($widget_name) ){
            wp_safe_redirect(add_query_arg('pixe_widget_area_error', 'empty', admin_url('widgets.php')));
            exit;
        }

        // retrive current widgets to update
        $widget_areas = pixe_get_custom_widget_areas();
        $widget_id = 'pixe_widget_area_' . time();
        $widget_areas[$widget_id] = array(
            'id'   => $widget_id,
            'name' => $widget_name,
        );
        update_option('pixe_custom_widget_areas', $widget_areas);

        wp_safe_redirect(admin_url('widgets.php'));
        exit;
    }

    // Handle the AJAX request for removing a custom widget area.
    function pixe_remove_custom_widget_area(){
        if( !current_user_can('edit_theme_options') ){
            wp_send_json_error(array(
                'message' => esc_html__('Sorry, you are not allowed to remove widget areas.', 'pixebuilder')
            ), 403);
        }

        check_ajax_referer('pixe_remove_widget_area', 'nonce');

        $widget_id = empty($_POST['widget_id'])? '': sanitize_key(wp_unslash($_POST['widget_id']));

        if( empty($widget_id) ){
            wp_send_json_error(array(
                'message' => esc_html__('Missing widget area.', 'pixebuilder')
            ), 400);
        }

        $widget_areas = pixe_get_custom_widget_areas();

        if( empty($widget_areas[$widget_id]) ){
            wp_send_json_error(array(
                'message' => esc_html__('Widget area not found.', 'pixebuilder')
            ), 404);
        }

        unset($widget_areas[$widget_id]);
        update_option('pixe_custom_widget_areas', $widget_areas);

        $sidebars_widgets = get_option('sidebars_widgets', array());
        if( is_array($sidebars_widgets) && isset($sidebars_widgets[$widget_id]) ){
            unset($sidebars_widgets[$widget_id]);
            update_option('sidebars_widgets', $sidebars_widgets);
        }

        wp_send_json_success(array(
            'widget_id' => $widget_id
        ));
    }

    // Build the widget-area creation form markup.
    function pixe_get_widget_area_form_markup(){
        ob_start();
        ?>
        <div id="pixe-widget-area-form" class="pixe-widget-area-form" style="display:none;">
            <?php if( !empty($_GET['pixe_widget_area_error']) ){ ?>
                <div class="notice notice-error inline"><p><?php esc_html_e('Please enter a widget name.', 'pixebuilder'); ?></p></div>
            <?php } ?>
            <form method="post" action="<?php echo esc_url(admin_url('widgets.php')); ?>">
                <?php wp_nonce_field('pixe_add_widget_area', 'pixe_add_widget_area_nonce'); ?>
                <input type="hidden" name="pixe_add_widget_area" value="1" />
                <label for="pixe-widget-area-name"><?php esc_html_e('New Widget Area', 'pixebuilder'); ?></label>
                <input type="text" id="pixe-widget-area-name" name="pixe_widget_area_name" placeholder="<?php esc_attr_e('Widget name...', 'pixebuilder'); ?>" />
                <button type="submit" class="button button-primary"><?php esc_html_e('Add Widget', 'pixebuilder'); ?></button>
            </form>
        </div>
        <?php
        return ob_get_clean();
    }

    // Print styles for the widget-area creation form.
    function pixe_widget_area_form_styles(){
        if( !current_user_can('edit_theme_options') ){
            return;
        }
        ?>
<style>
    
    .pixe-widget-area-form{ max-width: 700px;  margin: 0px auto 20px; padding: 16px; background: #fff; border: 1px solid #e1e1e1; }
    .pixe-widget-area-form:first-child{ margin-top: 28px; }
    .pixe-widget-area-form .notice{ margin: 0 0 11px; }
    .pixe-widget-area-form form{ display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
    .pixe-widget-area-form label{ font-size: 14px; font-weight: 600; margin-right: 5px; }
    .pixe-widget-area-form input[type="text"]{ flex-grow: 1; height: 48px; --pixe--color--placeholder: #9ea4b9; background: #f7f7f7; border: 1px solid #E6E7E9; }
    .pixe-widget-area-form input[type="text"]:focus{ outline: none; box-shadow: none; }
    .pixe-widget-area-form button{ height: 48px; }
    .pixe-widget-area-form button.button:focus{ outline: none; box-shadow: none; }

    .pixe-widget-area-form ::placeholder{ color: var(--pixe--color--placeholder); }
    .pixe-widget-area-form ::-webkit-input-placeholder{ color: var(--pixe--color--placeholder); }
    .pixe-widget-area-form ::-moz-placeholder{ color: var(--pixe--color--placeholder); }
    .pixe-widget-area-form :-ms-input-placeholder{  color: var(--pixe--color--placeholder); }
    .pixe-widget-area-form :-moz-placeholder{ color: var(--pixe--color--placeholder); }
    .components-panel__body-toggle .pixe-remove-widget-area{ position: absolute; right: 46px; top: 50%; transform: translateY(-50%); }
    .components-panel__body-toggle .pixe-remove-widget-area:hover{ color: #c72929; }
    .components-panel__body-toggle .pixe-remove-widget-area[aria-disabled="true"]{ opacity: .5; pointer-events: none; }
    .pixe-widget-confirmation{ position: fixed; top: 50%; left: 50%; width: 460px; z-index: 12000; max-width: calc(100% - 20px); overflow: hidden; background: #fff; border-radius: 16px; box-shadow: 0 15px 40px rgba(0, 0, 0, .18); transform: translate(-50%, -50%); }
    .pixe-widget-confirmation .pixe-head{ font-size: 16px; font-weight: 600; text-align: center; padding: 20px 25px; border-bottom: 1px solid #ececec; background: #fbfcfe; color: #303238; }
    .pixe-widget-confirmation .pixe-head .dashicons{ display: inline-block; vertical-align: middle; width: 22px; height: 22px; margin: -2px 10px 0 0; color: #c72929; font-size: 22px; }
    .pixe-widget-confirmation .pixe-content{ width: 400px; max-width: 100%; margin: 0 auto; font-size: 14px; padding: 40px 20px 25px; line-height: 1.4; color: #575b6a; box-sizing: border-box; }
    .pixe-widget-confirmation .pixe-button-wrap{ display: flex; justify-content: center; gap: 10px; padding-bottom: 45px; }
    .pixe-widget-confirmation .pixe-button-wrap input[type="button"]{ min-width: 105px; height: 44px; border: 0; border-radius: 12px; cursor: pointer; }
    .pixe-widget-confirmation .pixe-button-wrap input.pixe-submit{ background: #c72929; color: #fff; }
    .pixe-widget-confirmation .pixe-button-wrap input.pixe-cancel{ color: #697386; background: #eef2f7; }
    .pixe-widget-confirmation-overlay{ position: fixed; inset: 0; z-index: 11999; background: rgba(0, 0, 0, .25); }
</style>
        <?php
    }

    // Print scripts that place the form after the block editor writing flow.
    function pixe_widget_area_form_scripts(){
        if( !current_user_can('edit_theme_options') ){
            return;
        }

        $form = pixe_get_widget_area_form_markup();
        $widget_areas = array_values(pixe_get_custom_widget_areas());
        ?>
<script>
    (function(){
        var formHtml = <?php echo wp_json_encode($form); ?>;
        var widgetAreas = <?php echo wp_json_encode($widget_areas); ?>;
        var removeNonce = <?php echo wp_json_encode(wp_create_nonce('pixe_remove_widget_area')); ?>;

        // insert widget form at the bottom
        function insertWidgetAreaForm(){
            var writingFlow = document.querySelector('.block-editor-writing-flow');

            if( !writingFlow || document.getElementById('pixe-widget-area-form') ){
                return;
            }

            writingFlow.insertAdjacentHTML('afterend', formHtml);
            document.getElementById('pixe-widget-area-form').style.display = '';
        }

        function escapeHtml(text){
            var div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        // Copied confirmation behavior from $.pixeConfirmationBox for the native Widgets screen.
        function pixeWidgetConfirmationBox(settings){
            var confirmBox = document.createElement('div');
            confirmBox.className = 'pixe-widget-confirmation';
            confirmBox.innerHTML = '<div class="pixe-head"><span class="dashicons dashicons-trash" aria-hidden="true"></span>' + settings.title + '</div>' +
                '<div class="pixe-content">' + settings.message + '</div>' +
                '<div class="pixe-button-wrap">' +
                    '<input class="pixe-submit" type="button" value="' + settings.confirmText + '">' +
                    '<input class="pixe-cancel" type="button" value="' + settings.cancelText + '">' +
                '</div>';

            function close(){
                confirmBox.remove();
                overlay.remove();
                document.removeEventListener('keydown', keydown);
            }

            function keydown(event){
                if( event.key === 'Enter' ){
                    confirmBox.querySelector('.pixe-submit').click();
                }else if( event.key === 'Escape' ){
                    confirmBox.querySelector('.pixe-cancel').click();
                }
            }

            var overlay = document.createElement('div');
            overlay.className = 'pixe-widget-confirmation-overlay';
            document.body.appendChild(overlay);
            document.body.appendChild(confirmBox);

            confirmBox.addEventListener('click', function(event){
                if( event.target.classList.contains('pixe-submit') ){
                    settings.onSuccess(confirmBox);
                    close();
                }else if( event.target.classList.contains('pixe-cancel') ){
                    close();
                }
            });

            setTimeout(function(){
                document.addEventListener('keydown', keydown);
            }, 50);

            return confirmBox;
        }

        function confirmRemoveWidgetArea(widgetArea, removeIcon){
            pixeWidgetConfirmationBox({
                title: 'Remove Widget Area',
                confirmText: 'Remove',
                cancelText: 'Cancel',
                message: 'Are you sure you want to remove "' + escapeHtml(widgetArea.name) + '"?',
                onSuccess: function(){
                    removeWidgetArea(widgetArea, removeIcon);
                }
            });
        }

        function removeWidgetArea(widgetArea, removeIcon){
            if( removeIcon.getAttribute('aria-disabled') === 'true' ){
                return;
            }

            var formData = new FormData();
            formData.append('action', 'pixe_remove_widget_area');
            formData.append('nonce', removeNonce);
            formData.append('widget_id', widgetArea.id);

            removeIcon.setAttribute('aria-disabled', 'true');

            fetch(ajaxurl, {
                method: 'POST',
                credentials: 'same-origin',
                body: formData
            }).then(function(response){
                return response.json();
            }).then(function(response){
                if( !response || !response.success ){
                    throw new Error(response && response.data && response.data.message? response.data.message: 'Unable to remove widget area.');
                }

                window.location.reload();
            }).catch(function(error){
                removeIcon.setAttribute('aria-disabled', 'false');
                window.alert(error.message);
            });
        }

        function addWidgetAreaRemoveButtons(){
            if( !widgetAreas || !widgetAreas.length ){
                return;
            }

            document.querySelectorAll('button.components-panel__body-toggle').forEach(function(toggle){
                var widgetAreaId = '';
                var panelBody = toggle.closest('.components-panel__body');
                var widgetAreaWrap = panelBody? panelBody.querySelector('[data-widget-area-id]'): null;

                if( widgetAreaWrap ){
                    widgetAreaId = widgetAreaWrap.getAttribute('data-widget-area-id');
                }

                widgetAreas.forEach(function(widgetArea){
                    if( toggle.querySelector('.pixe-remove-widget-area') || widgetAreaId !== widgetArea.id ){
                        return;
                    }

                    var removeIcon = document.createElement('span');
                    removeIcon.className = 'pixe-remove-widget-area';
                    removeIcon.setAttribute('role', 'button');
                    removeIcon.setAttribute('tabindex', '0');
                    removeIcon.setAttribute('aria-label', 'Remove ' + widgetArea.name);
                    removeIcon.innerHTML = '<span class="dashicons dashicons-trash" aria-hidden="true"></span>';

                    removeIcon.addEventListener('click', function(event){
                        event.preventDefault();
                        event.stopPropagation();
                        confirmRemoveWidgetArea(widgetArea, removeIcon);
                    });

                    removeIcon.addEventListener('keydown', function(event){
                        if( event.key !== 'Enter' && event.key !== ' ' ){
                            return;
                        }

                        event.preventDefault();
                        event.stopPropagation();
                        confirmRemoveWidgetArea(widgetArea, removeIcon);
                    });

                    toggle.appendChild(removeIcon);
                });
            });
        }

        function watchWidgetAreaForm(){
            insertWidgetAreaForm();
            addWidgetAreaRemoveButtons();

            if( !document.body ){
                return;
            }

            var observer = new MutationObserver(function(){
                insertWidgetAreaForm();
                addWidgetAreaRemoveButtons();
            });
            observer.observe(document.body, { childList: true, subtree: true });
        }

        if( document.readyState === 'loading' ){
            document.addEventListener('DOMContentLoaded', watchWidgetAreaForm);
        }else{
            watchWidgetAreaForm();
        }
    })();
</script>
        <?php
    }
    
