<?php

namespace Essential_Addons_Elementor\Classes;

if (!defined('ABSPATH')) {
    exit;
} // Exit if accessed directly

use Elementor\Plugin;
use Essential_Addons_Elementor\Traits\Admin;
use Essential_Addons_Elementor\Traits\Core;
use Essential_Addons_Elementor\Traits\Elements;
use Essential_Addons_Elementor\Traits\Enqueue;
use Essential_Addons_Elementor\Traits\Helper;
use Essential_Addons_Elementor\Traits\Library;
use Essential_Addons_Elementor\Traits\Login_Registration;
use Essential_Addons_Elementor\Traits\Woo_Product_Comparable;
use Essential_Addons_Elementor\Traits\Controls;
use Essential_Addons_Elementor\Traits\Facebook_Feed;
use Essential_Addons_Elementor\Classes\Asset_Builder;
use Essential_Addons_Elementor\Traits\Ajax_Handler;
use Essential_Addons_Elementor\Pro\Classes\License\LicenseManager;

class Bootstrap
{
    use Library;
    use Core;
    use Helper;
    use Enqueue;
    use Admin;
    use Elements;
    use Login_Registration;
    use Woo_Product_Comparable;
    use Controls;
    use Facebook_Feed;
    use Ajax_Handler;

    // instance container
    private static $instance = null;

    // request unique id container
    protected $uid = null;

    // registered elements container
    protected $registered_elements;

    // registered extensions container
    protected $registered_extensions;

    // identify whether pro is enabled
    protected $pro_enabled;

    // localize objects
    public $localize_objects = [];

    // request data container
    protected $request_requires_update;

    // loaded templates in a request
    protected $loaded_templates = [];

    // loaded elements in a request
    protected $loaded_elements = [];

    // used for internal css
    protected $css_strings;

    // used for internal js
    protected $js_strings;

    // used to store custom js
    protected $custom_js_strings;

    // modules
    protected $installer;


    const EAEL_PROMOTION_FLAG = 15;
    const EAEL_ADMIN_MENU_FLAG = 15;
    /**
     * Singleton instance
     *
     * @since 3.0.0
     */
    public static function instance()
    {
        if (self::$instance == null) {
            self::$instance = new self;
        }

        return self::$instance;
    }

    /**
     * Constructor of plugin class
     *
     * @since 3.0.0
     */
    private function __construct()
    {
        // init modules
        $this->installer = new WPDeveloper_Plugin_Installer();

        // before init hook
        do_action('eael/before_init');

        // search for pro version
        $this->pro_enabled = apply_filters('eael/pro_enabled', false);

        // elements classmap
        $this->registered_elements = apply_filters('eael/registered_elements', $GLOBALS['eael_config']['elements']);

        // extensions classmap
        $this->registered_extensions = apply_filters('eael/registered_extensions', $GLOBALS['eael_config']['extensions']);

	    // start plugin tracking
	    if ( ! $this->pro_enabled ) {
            add_action( 'init', [ $this, 'start_plugin_tracking' ] );
	    }

        // register extensions
        $this->register_extensions();

        // register hooks
        $this->register_hooks();

	    if ( $this->is_activate_elementor() ) {
		    new Asset_Builder( $this->registered_elements, $this->registered_extensions );
	    }

    }

    protected function register_hooks() {
        // Core
        add_action('init', [$this, 'i18n']);
        // TODO::RM
        add_filter('eael/active_plugins', [$this, 'is_plugin_active'], 10, 1);

        add_filter('eael/is_plugin_active', [$this, 'is_plugin_active'], 10, 1);
        add_action('elementor/editor/after_save', array($this, 'save_global_values'), 10, 2);
        add_action('trashed_post', array($this, 'save_global_values_trashed_post'), 10, 1);

        // Enqueue
        add_action('eael/before_enqueue_styles', [$this, 'before_enqueue_styles']);
        add_action('elementor/editor/before_enqueue_scripts', [$this, 'editor_enqueue_scripts']);
        add_action('elementor/frontend/before_register_scripts', [$this, 'frontend_enqueue_scripts']);

        // Generator

	    $this->init_ajax_hooks();

        // Ajax
        add_action('wp_ajax_facebook_feed_load_more', [$this, 'facebook_feed_render_items']);
        add_action('wp_ajax_nopriv_facebook_feed_load_more', [$this, 'facebook_feed_render_items']);

        // Compare table
	    add_action( 'wp_ajax_nopriv_eael_product_grid', [$this, 'get_compare_table']);
	    add_action( 'wp_ajax_eael_product_grid', [$this, 'get_compare_table']);

	    add_action( 'wp_ajax_eael_clear_widget_cache_data', [ $this, 'eael_clear_widget_cache_data' ] );

	    if ( defined( 'ELEMENTOR_VERSION' ) ) {
		    if ( version_compare( ELEMENTOR_VERSION, '3.5.0', '>=' ) ) {
			    add_action( 'elementor/controls/register', array( $this, 'register_controls' ) );
			    add_action('elementor/widgets/register', array($this, 'register_elements'));
		    } else {
			    add_action( 'elementor/controls/controls_registered', array( $this, 'register_controls' ) );
			    add_action('elementor/widgets/widgets_registered', array($this, 'register_elements'));
		    }
	    }

        // Elements
        add_action('elementor/elements/categories_registered', array($this, 'register_widget_categories'));
        add_filter('elementor/editor/localize_settings', [$this, 'promote_pro_elements']);
        add_action('wp_footer', [$this, 'render_global_html']);
        add_action('wp_footer', [$this, 'render_advanced_accordion_global_faq']);

        // Controls
        add_action('eael/controls/query', [$this, 'query'], 10, 1);
        add_action('eael/controls/betterdocs/query', [$this, 'betterdocs_query'], 10, 1);
        add_action('eael/controls/layout', [$this, 'layout'], 10, 1);
        add_action('eael/controls/terms_style', [$this, 'terms_style'], 10, 1);
        add_action('eael/controls/read_more_button_style', [$this, 'read_more_button_style'], 10, 1);
        add_action('eael/controls/load_more_button_style', [$this, 'load_more_button_style'], 10, 1);
        add_action('eael/controls/custom_positioning', [$this, 'custom_positioning'], 10, 5);
	    add_action('eael/controls/nothing_found_style', [$this, 'nothing_found_style'], 10, 1);

        add_filter('eael/controls/event-calendar/source', [$this, 'event_calendar_source']);
        add_action('eael/controls/advanced-data-table/source', [$this, 'advanced_data_table_source']);

        // Login | Register
        add_action('init', [$this, 'login_or_register_user']);
        add_filter('wp_new_user_notification_email', array($this, 'new_user_notification_email'), 10, 3);
        add_filter('wp_new_user_notification_email_admin', array($this, 'new_user_notification_email_admin'), 10, 3);
        add_action( 'login_init', [$this, 'eael_redirect_to_reset_password'] );

        if( 'on' === get_option( 'eael_custom_profile_fields' ) ){
            add_action( 'show_user_profile', [ $this, 'eael_extra_user_profile_fields' ] );
            add_action( 'edit_user_profile', [ $this, 'eael_extra_user_profile_fields' ] );

            add_action( 'personal_options_update', [ $this, 'eael_save_extra_user_profile_fields' ] );
            add_action( 'edit_user_profile_update', [ $this, 'eael_save_extra_user_profile_fields' ] );
        }

        //rank math support
        add_filter('rank_math/researches/toc_plugins', [$this, 'toc_rank_math_support']);

//        if(defined('WPML_TM_VERSION')){
//	        add_filter( 'elementor/documents/get/post_id',[$this, 'eael_wpml_template_translation']);
//        }

        //templately plugin support
        if( !class_exists('Templately\Plugin') && !get_option('eael_templately_promo_hide') ) {
            add_action( 'elementor/editor/before_enqueue_scripts', [$this, 'templately_promo_enqueue_scripts'] );
            add_action( 'eael/before_enqueue_styles', [$this, 'templately_promo_enqueue_style'] );
            add_action( 'elementor/editor/footer', [ $this, 'print_template_views' ] );
            add_action( 'wp_ajax_templately_promo_status', array($this, 'templately_promo_status'));
        }

	    if( class_exists( 'woocommerce' ) ) {
		    // quick view
		    add_action( 'eael_woo_single_product_image', 'woocommerce_show_product_images', 20 );
		    add_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_title', 5 );
		    add_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_rating', 10 );
		    add_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_price', 15 );
		    add_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
		    add_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_add_to_cart', 25 );
		    add_action( 'eael_woo_single_product_summary', 'woocommerce_template_single_meta', 30 );

		    add_filter( 'eael_product_wrapper_class', [ $this, 'eael_product_wrapper_class' ], 10, 3 );

            add_action('wp_ajax_eael_checkout_cart_qty_update', [$this, 'eael_checkout_cart_qty_update'] );
    		add_action('wp_ajax_nopriv_eael_checkout_cart_qty_update', [$this, 'eael_checkout_cart_qty_update'] );

		    add_action( 'wp_loaded', [ $this, 'eael_woo_cart_empty_action' ], 20 );
		    add_filter( 'woocommerce_checkout_fields', [ $this, 'eael_customize_woo_checkout_fields' ] );

		    add_action( 'eael_woo_before_product_loop', function ( $layout ) {
			    if ( $layout === 'eael-product-default' ) {
				    return;
			    }

			    remove_action( 'woocommerce_before_shop_loop_item', 'woocommerce_template_loop_product_link_open' );
			    remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_product_link_close' );
			    remove_action( 'woocommerce_after_shop_loop_item', 'astra_woo_woocommerce_shop_product_content' );
			    remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );
		    } );

            add_action( 'eael_woo_after_product_loop', function ( $layout ) {
			    if ( $layout === 'eael-product-default' ) {
				    return;
			    }

			    add_action( 'woocommerce_before_shop_loop_item', 'woocommerce_template_loop_product_link_open' );
			    add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_product_link_close' );
                //Get current active theme
                $theme = wp_get_theme();
                $theme = $theme->parent() ? $theme->parent() : $theme;
                //Astra Theme
                if( function_exists( 'astra_woo_woocommerce_shop_product_content' ) ){
                    add_action( 'woocommerce_after_shop_loop_item', 'astra_woo_woocommerce_shop_product_content' );
                } else {
                    add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );
                }
                //Theme Support
                $theme_to_check = ['OceanWP', 'Blocksy', 'Travel Ocean'];
                if( in_array( $theme->name, $theme_to_check, true ) ) {
                    remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );
                }
		    } );

		    add_filter( 'wcml_multi_currency_ajax_actions', function ( $ajax_actions ) {
			    $ajax_actions[] = 'load_more';

			    return $ajax_actions;
		    } );
	    }

        // Admin
	    if ( is_admin() ) {
            // Admin
            if (!$this->pro_enabled) {
                add_action( 'admin_init', [ $this, 'admin_notice' ] );
            } else {
                new WPDeveloper_Core_Installer( basename( EAEL_PLUGIN_BASENAME, '.php' ) );
            }

		    add_action( 'admin_menu', array( $this, 'admin_menu' ) );
		    add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
		    add_action( 'admin_enqueue_scripts', array( $this, 'admin_dequeue_scripts' ), 100 );

            // Core
            add_filter('plugin_action_links_' . EAEL_PLUGIN_BASENAME, array($this, 'insert_plugin_links'));
            add_filter('plugin_row_meta', array($this, 'insert_plugin_row_meta'), 10, 2);

            // removed activation redirection temporarily
            // add_action('admin_init', array($this, 'redirect_on_activation'));

	        if ( ! did_action( 'elementor/loaded' ) ) {
		        add_action( 'admin_notices', array( $this, 'elementor_not_loaded' ) );
		        add_action( 'eael_admin_notices', array( $this, 'elementor_not_loaded' ) );
	        }

	        add_action( 'in_admin_header', [ $this, 'remove_admin_notice' ], 99 );

	        //handle typeform auth token
	        add_action('admin_init', [$this, 'typeform_auth_handle']);


	        // On Editor - Register WooCommerce frontend hooks before the Editor init.
	        // Priority = 5, in order to allow plugins remove/add their wc hooks on init.
	        if ( ! empty( $_REQUEST['action'] ) && 'elementor' === $_REQUEST['action'] ) {
		        add_action( 'init', [ $this, 'register_wc_hooks' ], 5 );
	        }

			// update admin menu notice flag once visit EA settings page
	        add_action( 'eael_admin_page_setting', [ $this, 'eael_show_admin_menu_notice' ] );

		    if ( ! current_user_can( 'administrator' ) ) {
			    add_filter( 'elementor/document/save/data', function ( $data ) {
				    if ( isset( $data['settings']['eael_custom_js'] ) ) {
					    $data['settings']['eael_custom_js'] = get_post_meta( get_the_ID(), '_eael_custom_js', true );
				    }

				    if ( empty( $data['elements'] ) ) {
					    return $data;
				    }

				    $data['elements'] = Plugin::$instance->db->iterate_data( $data['elements'], function ( $element ) {
					    if ( isset( $element['widgetType'] ) && $element['widgetType'] === 'eael-login-register' ) {
						    if ( ! empty( $element['settings']['register_user_role'] ) ) {
							    $element['settings']['register_user_role'] = '';
						    }
					    }

					    if ( isset( $element['widgetType'] ) && $element['widgetType'] === 'eicon-woocommerce' ) {
						    if ( ! empty( $element['settings']['eael_product_grid_products_status'] ) ) {
							    $element['settings']['eael_product_grid_products_status'] = [ 'publish' ];
						    }
					    }

                        if ( ! current_user_can( 'install_plugins' ) && isset( $element['widgetType'] ) && $element['widgetType'] === 'eaicon-advanced-data-table' ) {
						    if ( ! empty( $element['settings']['ea_adv_data_table_source'] ) ) {
							    $element['settings']['ea_adv_data_table_source'] = 'static';
						    }
					    }

					    return $element;
				    } );

				    return $data;
			    } );
		    }
        } else {
	        add_action( 'wp', [ $this, 'eael_post_view_count' ] );
        }

	    // beehive theme compatibility
	    add_filter( 'beehive_scripts', array( $this, 'beehive_theme_swiper_slider_compatibility' ), 999 );


	    // init plugin updater with version check
	    if ( defined( 'EAEL_PRO_PLUGIN_VERSION' ) && version_compare( EAEL_PRO_PLUGIN_VERSION, '6.2.2', '>=' ) && version_compare( EAEL_PRO_PLUGIN_VERSION, '6.2.3', '<=' ) ) {
		    add_action( 'init', [ $this, 'eael_init_plugin_updater' ], 99 );
	    }
    }

    /**
     * Initialize plugin updater
     *
     * @since 6.1.14
     */
	function eael_init_plugin_updater() {
		if ( is_admin() ) {
			$license_manager = LicenseManager::get_instance( [] );
			$license_manager->plugin_updater();
		}
	}
}
