<?php 
    // prevent direct file access
	if( !defined( 'ABSPATH' ) ) exit;
    
    class Pixe_Editor{

        // is current page editor
        private static $is_editor = false;
        public static function is_editor(){
            return self::$is_editor;
        }

        // return instance for use
        private static $instance;
        public static function get_instance(){
            return self::$instance;
        }

        // variables
        public $type;
        public $id;
        public $part;
        public $revision;
        public $is_preview = false;

        function __construct(){
            self::$instance = $this;
            add_action('init', array(&$this, 'initialize'));
        }

        function initialize(){

            // check if it's an editor request
            // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Nonce not required: request performs read-only query.
            if( current_user_can('edit_posts') ){
                if( isset($_REQUEST['pixe_editor']) && isset($_REQUEST['pixe_id']) ){
                    $allowed_type = array('post', 'template', 'template_part');
                    
                    if( in_array($_REQUEST['pixe_editor'], $allowed_type) ){
                        $this->id = absint(wp_unslash($_REQUEST['pixe_id']));
                        $this->type = sanitize_text_field(wp_unslash($_REQUEST['pixe_editor']));
                        $this->part = empty($_REQUEST['pixe_part'])? '': sanitize_text_field(wp_unslash($_REQUEST['pixe_part']));
                        $this->revision = empty($_REQUEST['pixe_revision'])? '': absint(wp_unslash($_REQUEST['pixe_revision']));
                    }

                    // check if editing
                    if( !empty($this->type) && !empty($this->id) ){
                        if( $this->type == 'post' ){
                            if( Pixe_Builder::can_use_builder($this->id) && current_user_can('edit_post', $this->id) ){
                                self::$is_editor = true;
                            }
                        }else{
                            if( current_user_can('manage_options') ){
                                self::$is_editor = true;
                            }
                        }
                    }
                }
            }
            
            // for front end content display
            if( !self::is_editor() ){
                $this->is_preview = empty($_GET['pixe_preview'])? false: true;
                add_filter('the_content', array(&$this, 'the_content_display'), 30);

            // for back end editor
            }else{

                // load necessary scripts
                add_filter('show_admin_bar', '__return_false');
                add_filter('body_class', 'Pixe_Editor::body_class');
                add_action('wp_enqueue_scripts', array(&$this, 'load_editor_scripts'));

                // for posts
                if( $this->type == 'post' ){
                    add_filter('the_content', array(&$this, 'the_content_editor'), 30);
                }

                // filter for plugin support
                add_filter('woocommerce_checkout_redirect_empty_cart', '__return_false'); // woocommerce checkout
            }
            // phpcs:enable WordPress.Security.NonceVerification.Recommended

            // save editor action
            add_action('wp_ajax_pixe_save_post_editor', 'pixe_save_post_editor');
            add_action('wp_ajax_pixe_save_template_editor', 'pixe_save_template_editor');

            // search page builder
            add_filter('posts_join', array(&$this, 'search_posts_join'), 10, 2);
            add_filter('posts_where', array(&$this, 'search_posts_where'), 10, 2);
            add_filter('posts_groupby', array(&$this, 'search_posts_groupby'), 10, 2);
        }

        // editor preview url
        public static function get_editor_url($id, $type, $part = '', $thumbnail = false){

            // arguments
            $args = array(
                'pixe_editor' => $type,
                'pixe_id' => $id
            );
            if( !empty($part) ){
                $args['pixe_part'] = $part;
            }
            if( $thumbnail ){
                $args['pixe_preview_thumbnail'] = 1;
            }

            // url
            if( $type == 'post' ){
                $url = get_permalink($id);
            }else{
                $url = home_url('/');
            }

            return add_query_arg($args, $url);
        }
        public static function body_class($classes){
            $classes[] = 'pixe-editor-body';

            if( isset($_REQUEST['pixe_preview_thumbnail']) ){ // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Nonce not required: request performs read-only query.
                $classes[] = 'pixe-preview';
                $classes[] = 'pixe-preview-thumbnail';
            }

            $editor = self::get_instance();
            if( $editor->type == 'template_part' ){
                $classes[] = 'pixe-template-' . $editor->part;
            }else if( $editor->type == 'template' ){
                $classes[] = 'pixe-template-editor';
            }

            pixe_register_tmce();

            return $classes;
        }

        // load editor script for front end editing
        function load_editor_scripts(){
            pixe_enqueue_admin_styles(array('utility', 'editor'));
            if( $this->type == 'template_part' ){
                pixe_enqueue_admin_scripts(array('jquery', 'wp-media', 'wp-editor', 'utility', 'editor', 'html2canvas'));
            }else{
                pixe_enqueue_admin_scripts(array('jquery', 'wp-media', 'wp-editor', 'utility', 'editor'));
            }

            wp_localize_script('pixe-i18n', 'pixeData', $this->get_editor_script_data());

            // woocommerce support
            wp_deregister_script('wc-checkout');
            wp_deregister_script('wc-cart');
            wp_deregister_script('wc-cart-fragments');
        }
        function get_editor_script_data(){
            global $pixe_site;

            // update status
            // initial : disable
            // edit : enable
            // update failed : enable
            // success : disable
            // loading
            $ret = array(
                'site' => $pixe_site,
                'type' => $this->type,
                'part' => $this->part,
                'id' => $this->id,
                'siteTitle' => get_bloginfo('name'),
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'adminUrl' => admin_url('admin.php'),
                'aiConnectorUrl' => admin_url('options-connectors.php'),
                'nonce' => wp_create_nonce('pixe-editor'),
                'previewUrl' => add_query_arg(array('pixe_preview' => 'true'), get_permalink($this->id)),
                'syncedBlockUrl' => Pixe_Builder::get_template_edit_url('PIXE_TEMPLATE_ID', 'template_part', 'synced_block'),
                'imgDir' => PIXE_URL . '/admin/img/',
                'updateStatus' => 'disable',
                'wcSupport' => get_theme_support('pixe-woocommerce'),
                'ai' => pixe_get_builder_ai_data(),
                'stockImage' => pixe_get_builder_stock_image_data(),
            );

            // right click settings
            $general_settings = get_option('pixe_general', array());
            if( !empty($general_settings['context-menu']) && $general_settings['context-menu'] == 'no' ){
                $ret['disableContextMenu'] = true;
            }

            // post editor
            if( $this->type == 'post' ){

                // post title
                $ret['postTitle'] = get_the_title($this->id);

                // autosave
                $enable_autosave = (pixe_get_settings('enable-autosave') != 'no'); 
                if( !$enable_autosave ){
                    $ret['autosave'] = 'off';
                }

                // for displaying revision data
                if( !empty($this->revision) ){
                    $result = pixe_get_revision_data($this->revision, $this->id);
                    if( !empty($result->post_content) ){
                        $ret['mainContent'] = json_decode($result->post_content, true);
                    }
                    if( !empty($result->settings) ){
                        $ret['editorSettings'] = json_decode($result->settings, true);
                    }

                    $ret['revision'] = 1;
                    $ret['updateStatus'] = 'edited';

                // for displaying normal editor area
                }else{
                    $main_content = pixe_get_builder_data($this->id, $enable_autosave);
                    if( !empty($main_content) ){
                        $ret['mainContent'] = $main_content;
                    }

                    $editor_settings = pixe_get_builder_settings($this->id, $enable_autosave);
                    if( !empty($editor_settings) ){
                        $ret['editorSettings'] = $editor_settings;
                    }
                }
            
            // template editor
            }else{

                $ret['autosave'] = 'off';

                // main template content
                $result = pixe_get_template($this->id);
                if( !empty($result->content) ){
                    $ret['mainContent'] = json_decode($result->content, true);
                }
                if( !empty($result->title) ){
                    $ret['postTitle'] = $result->title;
                }

                // template settings
                $result = pixe_get_template($this->id);
                if( !empty($result->settings) ){
                    $ret['editorSettings'] = json_decode($result->settings, true);
                }

            }

            // elements
            $elements = Pixe_Builder::get_elements();

            $ret['elements'] = array();
            foreach( $elements as $element ){
                $slug = $element::get_name();

                $ret['elements'][$slug] = array(
                    'title' => $element::get_title(),
                    'isPro' => $element::is_pro()
                );
                
                if( !empty($element::get_dependencies()) ){
                    $ret['elements'][$slug]['deps'] = $element::get_dependencies();
                }
            }

            // preset
            $ret['colorPreset'] = pixe_get_colors();
            $ret['typoPreset'] = pixe_get_typo();
            $ret['controlPreset'] = pixe_get_controls();
            $ret['adminIconPreset'] = pixe_admin_icon_preset();
            $ret['buttonPreset'] = pixe_get_button_preset();
            $ret['variablePreset'] = pixe_get_variables();

            // plugins
            $ret['recaptchaSettingsUrl'] = admin_url('admin.php?page=pixe_plugin_settings_integration');
            $ret['mailchimpSettingsUrl'] = admin_url('admin.php?page=pixe_plugin_settings_integration&type=mailchimp'); 
            $ret['mailchimpApi'] = get_option('pixe_mailchimp_api', array());
            $ret['activeCampaignApi'] = get_option('pixe_active_campaign_api', array());
            
            $ret = apply_filters('pixe_editor_script_data', $ret);

            return $ret;
        }

        // add the_content with custom editing area
        function the_content_editor($content){
            if( !empty($content) ){
                $content = '<div class="pixe-the-content" >' . $content . '</div>';
            }
            return $content .'<div class="pixe-editor pixe-box-sizing" id="pixe-editor" data-area="main" ></div>';
        }

        // add custom page builder data to content area
        function the_content_display($content){
            global $pixe_builder_loop;

            // prevent content display loop
            if( is_admin() || !empty($pixe_builder_loop) ) return $content;

            // only display page builder inside main query content
            if( is_main_query() ){ 
                if( !empty($content) ){
                    $content = '<div class="pixe-the-content" >' . $content . '</div>';
                }

                return $content . pixe_get_post_content(get_the_ID(), $this->is_preview);

            }

            return $content;
        }

        // search
        function search_posts_join($join, $query){
            global $wpdb;
            
            $keywords = $query->get('s');
            if( !empty($keywords) && strpos($join, $wpdb->postmeta) === false ){
                $join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id ";
            }

            return $join;
        }
        function search_posts_where($where, $query) {
            global $wpdb;
            
            // Search post_meta
            $keywords = $query->get('s');
            if( !empty($keywords) ){

                // for alias
                if( strpos($where, 'sq1.meta_value') !== false ){
                    $where = preg_replace(
                        "/\(\s*{$wpdb->posts}\.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
                        "({$wpdb->posts}.post_title LIKE $1) OR (sq1.meta_key = 'pixe-builder-main' AND sq1.meta_value LIKE $1)",
                        $where
                    );

                // normal query results
                }else{
                    $where = preg_replace(
                        "/\(\s*{$wpdb->posts}\.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
                        "({$wpdb->posts}.post_title LIKE $1) OR ({$wpdb->postmeta}.meta_key = 'pixe-builder-main' AND {$wpdb->postmeta}.meta_value LIKE $1)",
                        $where
                    );
                }
            }

            return $where;
        }
        function search_posts_groupby($groupby, $query){
            global $wpdb;

            // Ensures no duplicate results
            $keywords = $query->get('s');
            if( !empty($keywords) ){
                return "{$wpdb->posts}.ID";
            }

            return $groupby;
        }
    }

    new Pixe_Editor();
