<?php

namespace Limb_Chatbot\Includes\Admin\Pages\Live_Agent;

use Limb_Chatbot\Includes\Admin\Admin;
use Limb_Chatbot\Includes\Frontend\Page_Context;
use Limb_Chatbot\Includes\Integrations\Integrations;
use Limb_Chatbot\Includes\Services\User_Roles;

/**
 * Class Page
 *
 * Handles the Settings submenu page for the Limb Chatbot plugin.
 * Responsible for rendering the settings page, enqueuing assets, and rendering a live chatbot preview.
 *
 * @package Limb_Chatbot\Includes\Admin\Pages\Setting
 * @since 1.0.0
 */
class Page {
    /**
     * Screen options
     *
     * @var array[]
     */
    public static $screen_options_officials = array(
        'lbaic_items_per_page'                  => array(
            'option'  => 'lbaic_admin_settings_items_per_page',
            'default' => 10,
        ),
    );

    /**
     * Menu slug for the settings page.
     *
     * @since 1.0.0
     * @var string
     */
    public static string $menu_slug = 'lbaic-dashboard&menu=live-agent';

    /**
     * Adds the "Settings" submenu page under the main "Limb" admin menu.
     * Also hooks required scripts and styles for the settings page.
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function add_submenu_page() {
        $settings = add_submenu_page(
            Admin::$menu_slug,
            __( 'Live Agent', 'limb-chatbot' ),
	        __( 'Live Agent', 'wordpress-seo' ) . ' <span class="lbaic-badge-premium"></span>',
            'manage_options',
            static::$menu_slug,
            array(
                $this,
                'render'
            ),
            8
        );
        add_action( 'admin_print_scripts-' . $settings, array( $this, 'scripts' ) );
        add_action( 'admin_print_styles-' . $settings, array( $this, 'styles' ) );
        add_action( 'load-' . $settings, array( $this, 'add_screen_options' ) );
        add_action( 'load-' . $settings, array( $this, 'remove_notices' ) );
        // Hook early to catch screen options save
        add_action( 'admin_init', array( $this, 'save_checkbox_screen_options' ), 5 );

        // Disable wp emojis cdn and scripts to not have conflicts
        remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
        add_filter( 'emoji_svg_url', '__return_false' ); // Critical to block emoji CDN
    }

    /**
     * Renders the settings page content by including the settings template.
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function render() {
        include Limb_Chatbot()->get_plugin_dir_path() . 'templates/admin/lbaic-page-settings.php';
    }

    /**
     * Enqueues JavaScript assets required for the settings page.
     * Registers and localizes `lbaic-page-settings.js`.
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function scripts(): void {
        $limb_chatbot    = Limb_Chatbot();
        $plugin_dir_url  = $limb_chatbot->get_plugin_dir_url();
        $plugin_dir_path = $limb_chatbot->get_plugin_dir_path();
        $plugin_version  = $limb_chatbot->get_version();

        wp_enqueue_media();

        // Enqueue settings page (skeleton) js
        if ( ! wp_script_is( 'lbaic-page-settings-script', 'registered' ) ) {
            $settings_script_asset = include( $plugin_dir_path . 'dist/admin/lbaic-page-settings.asset.php' );
            wp_register_script( 'lbaic-page-settings-script', $plugin_dir_url . 'dist/admin/lbaic-page-settings.js', $settings_script_asset['dependencies'], $settings_script_asset['version'], true );
        }
        if ( ! wp_script_is( 'lbaic-page-settings-script', 'enqueued' ) ) {
            $post_types = get_post_types(
                    [ 'public' => true ],
                    'objects'
            );
            // Exclude unwanted ones
            $exclude = [ 'attachment', 'revision', 'nav_menu_item' ];
            foreach ( $exclude as $unset ) {
                unset( $post_types[ $unset ] );
            }
            // Format as 'post_type_name' => 'Label' (plural)
            $formatted = [];
            foreach ( $post_types as $name => $obj ) {
                $formatted[] = [
                        'name' => $obj->labels->name,
                        'slug' => $name
                ];
            }
            wp_enqueue_script( 'lbaic-page-settings-script' );
            // Get screen options data to localize
            $screen_options = array();
            $user_id        = get_current_user_id();
            foreach ( self::$screen_options_officials as $key => $args ) {
                $meta_value = get_user_meta( $user_id, $args['option'], true );
                // Handle checkbox (boolean) types
                if ( isset( $args['type'] ) && $args['type'] === 'checkbox' ) {
                    $screen_options[ $key ] = ( $meta_value === '1' || $meta_value === true || $meta_value === 'true' ) ? true : ( $meta_value !== '' ? (bool) $meta_value : $args['default'] );
                } else {
                    // Handle integer types (like per_page)
                    $screen_options[ $key ] = (int) ( $meta_value ?: $args['default'] );
                }
            }
	        $localize_data = array(
		        'rest'                 => array(
			        'url'   => get_rest_url( null, 'limb/chatbot/v1/' ),
			        'nonce' => wp_create_nonce( 'wp_rest' )
		        ),
		        'plugin'               => array(
			        'url'     => $plugin_dir_url,
			        'version' => $plugin_version,
		        ),
		        'screen_options'       => $screen_options,
		        'wp_objects'           => array( 'post_types' => $formatted ),
		        'user_roles'           => User_Roles::instance()->get_items(),
		        'integrations'         => array_keys( Integrations::instance()->get_integrations() ),
		        'page_context'         => Page_Context::instance()->get_context()
	        );
            // Localize the script
	        wp_localize_script( 'lbaic-page-settings-script', 'LimbChatbot', $localize_data);
        }
        add_action( 'admin_footer', array( $this, 'add_screen_options_script' ) );
        // Chatbot playground script
        $hooks_script_asset = include( $plugin_dir_path . 'dist/public/lbaic-chatbot.asset.php' );
        // Script
        $script_handle = 'lbaic-chatbot-playground-script';
        wp_register_script(
                $script_handle,
                $plugin_dir_url . 'dist/public/lbaic-chatbot.js',
                $hooks_script_asset['dependencies'],
                $plugin_version
        );
        wp_enqueue_script( $script_handle );
        // Chatbot playground styles
        $style_handle = 'lbaic-chatbot-playground-style';
        if ( ! wp_style_is( $style_handle, 'registered' ) ) {
            wp_register_style( $style_handle, $plugin_dir_url . 'dist/public/lbaic-chatbot.css', array(), $plugin_version );
        }
        if ( ! wp_style_is( $style_handle, 'enqueued' ) ) {
            wp_enqueue_style( $style_handle );
        }
    }

    /**
     * Enqueues CSS assets required for the settings page.
     * Loads both JS-generated and CSS-based styles for the settings UI and chatbot preview.
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function styles(): void {
        $limb_chatbot    = Limb_Chatbot();
        $plugin_dir_url  = $limb_chatbot->get_plugin_dir_url();
        $version         = $limb_chatbot->get_version();
        if ( ! wp_style_is( 'lbaic-page-settings-style', 'registered' ) ) {
            wp_register_style( 'lbaic-page-settings-style', $plugin_dir_url . 'dist/admin/lbaic-page-settings.css', array(), $version );
        }
        wp_enqueue_style( 'lbaic-page-settings-style' );
    }

    /**
     * Set screen options support
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function add_screen_options(): void {
    }

    /**
     * Remove the header notices
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function remove_notices(): void {
        remove_all_actions( 'admin_notices' );
        remove_all_actions( 'all_admin_notices' );
    }

    /**
     * Save screen options
     *
     * @param mixed $status Current status
     * @param string $option Option name
     * @param mixed $value Option value
     *
     * @return int|bool|mixed
     * @since 1.0.0
     *
     */
    public function set_screen_options( $status, $option, $value ) {
        foreach ( self::$screen_options_officials as $key => $args ) {
            if ( isset( $args['option'] ) && $args['option'] === $option ) {
                $user_id = get_current_user_id();

                // Handle checkbox (boolean) types
                if ( isset( $args['type'] ) && $args['type'] === 'checkbox' ) {
                    // Save as '1' for true, '' for false
                    $bool_value = ( $value === '1' || $value === 1 || $value === true || $value === 'true' ) ? '1' : '';
                    update_user_meta( $user_id, $option, $bool_value );

                    return $bool_value;
                }

                // Handle integer types (like items_per_page)
                $int_value = (int) $value;
                update_user_meta( $user_id, $option, $int_value );

                return $int_value;
            }
        }

        // When any screen option is saved, also process all our custom screen options
        // This ensures all options are saved even if they don't go through the standard mechanism
        $this->process_all_screen_options_on_save();

        return $status;
    }

    /**
     * Process all custom screen options when any screen option is saved
     * This is called from set_screen_options filter to ensure all options are saved
     *
     * @return void
     * @since 1.0.0
     *
     */
    private function process_all_screen_options_on_save() {
        // Only process if this is a screen options save request
        if ( ! isset( $_POST['screenoptionnonce'] ) ) {
            return;
        }

        $user_id = get_current_user_id();
        if ( ! $user_id ) {
            return;
        }

        // Handle each screen option
        foreach ( self::$screen_options_officials as $key => $args ) {
            $option_name = $args['option'];
            $value       = null;

            // Check wp_screen_options format first (if JavaScript converted it)
            if ( isset( $_POST['wp_screen_options'] ) &&
                 is_array( $_POST['wp_screen_options'] ) &&
                 isset( $_POST['wp_screen_options']['option'] ) &&
                 $_POST['wp_screen_options']['option'] === $option_name &&
                 isset( $_POST['wp_screen_options']['value'] ) ) {
                $value = $_POST['wp_screen_options']['value'];
            } else {
                // Check direct POST fields - WordPress uses the key as input name
                $post_keys = array(
                        $key, // WordPress uses the key as the input name
                        $option_name, // Direct option name (fallback)
                        'lbaic_checkbox_' . $key, // With prefix for checkboxes (fallback)
                );

                foreach ( $post_keys as $post_key ) {
                    if ( isset( $_POST[ $post_key ] ) ) {
                        $value = $_POST[ $post_key ];
                        break;
                    }
                }
            }

            // Only save if we found a value
            if ( $value !== null ) {
                // Handle checkbox (boolean) types
                if ( isset( $args['type'] ) && $args['type'] === 'checkbox' ) {
                    $value = ( $value === '1' || $value === 1 || $value === true || $value === 'true' ) ? '1' : '';
                } else {
                    // Handle integer types (like items_per_page)
                    $value = (int) $value;
                    // Ensure minimum value of 1
                    if ( $value < 1 ) {
                        $value = $args['default'];
                    }
                }

                update_user_meta( $user_id, $option_name, $value );
            }
        }
    }

    /**
     * Handle saving of all custom screen options
     * This is needed because unchecked checkboxes don't appear in POST data
     * and to ensure all our custom options are saved
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function save_checkbox_screen_options() {
        // Check if this is a screen options save request
        // WordPress screen options form uses 'screenoptionnonce' field
        if ( ! isset( $_POST['screenoptionnonce'] ) ) {
            return;
        }

        // Verify nonce
        if ( ! wp_verify_nonce( $_POST['screenoptionnonce'], 'screen-options-nonce' ) ) {
            return;
        }

        // Process all custom screen options immediately
        $this->process_all_screen_options_on_save();
    }

    /**
     * Adds JavaScript to handle saving checkbox screen options
     *
     * @return void
     * @since 1.0.0
     *
     */
    public function add_screen_options_script() {
        $screen = get_current_screen();
        if ( ! $screen || strpos( $screen->id, 'lbaic-dashboard' ) === false ) {
            return;
        }
        ?>
        <script type="text/javascript">
            (function ($) {
                $(document).ready(function () {
                    // Handle screen options form submission
                    // WordPress processes screen options via wp_screen_options[option] and wp_screen_options[value]
                    // We need to convert our checkbox to this format
                    var form = $('#adv-settings');
                    if (form.length) {
                        // Function to save all custom screen options via WordPress screen options mechanism
                        function saveAllScreenOptions() {
                            <?php foreach ( self::$screen_options_officials as $key => $args ) : ?>
                            <?php $option_name = $args['option']; ?>
                            <?php if ( isset( $args['type'] ) && $args['type'] === 'checkbox' ) : ?>
                            // Handle checkbox options
                            var checkbox_<?php echo esc_js( $key ); ?> = $('input[data-option-name="<?php echo esc_js( $option_name ); ?>"]');
                            if (checkbox_<?php echo esc_js( $key ); ?>.length) {
                                var isChecked = checkbox_<?php echo esc_js( $key ); ?>[0].checked;
                                var checkboxValue = isChecked ? '1' : '0';

                                // Remove any existing wp_screen_options for this option
                                form.find('input[name="wp_screen_options[option]"][value="<?php echo esc_js( $option_name ); ?>"]').next('input[name="wp_screen_options[value]"]').remove();
                                form.find('input[name="wp_screen_options[option]"][value="<?php echo esc_js( $option_name ); ?>"]').remove();

                                // Add in WordPress screen options format
                                form.append('<input type="hidden" name="wp_screen_options[option]" value="<?php echo esc_js( $option_name ); ?>" />');
                                form.append('<input type="hidden" name="wp_screen_options[value]" value="' + checkboxValue + '" />');
                            }
                            <?php else : ?>
                            // Handle other options (like items_per_page)
                            // WordPress uses the key as the input name, and the option name for saving
                            var optionInput_<?php echo esc_js( $key ); ?> = form.find('input[name="<?php echo esc_js( $key ); ?>"]');
                            if (optionInput_<?php echo esc_js( $key ); ?>.length) {
                                var optionValue = optionInput_<?php echo esc_js( $key ); ?>.val();

                                // Remove any existing wp_screen_options for this option
                                form.find('input[name="wp_screen_options[option]"][value="<?php echo esc_js( $option_name ); ?>"]').next('input[name="wp_screen_options[value]"]').remove();
                                form.find('input[name="wp_screen_options[option]"][value="<?php echo esc_js( $option_name ); ?>"]').remove();

                                // Add in WordPress screen options format (using option name, not key)
                                form.append('<input type="hidden" name="wp_screen_options[option]" value="<?php echo esc_js( $option_name ); ?>" />');
                                form.append('<input type="hidden" name="wp_screen_options[value]" value="' + optionValue + '" />');
                            }
                            <?php endif; ?>
                            <?php endforeach; ?>
                        }

                        // Save all custom screen options BEFORE form is submitted
                        form.on('submit', function (e) {
                            saveAllScreenOptions();
                        });

                        // Handle when Apply button is clicked - this is the main way WordPress saves screen options
                        $(document).on('click', '#screen-options-apply, #screen-options-save', function (e) {
                            // Save all custom screen options immediately
                            saveAllScreenOptions();
                        });

                    }
                });
            })(jQuery);
        </script>
        <?php
    }
}