<?php
/**
 * Elementor Service Provider File
 *
 * @category   Service Provider
 * @package    CodexShaper_Framework
 * @author     CodexShaper <info@codexshaper.com>
 * @license    https://www.gnu.org/licenses/gpl-2.0.html
 * @link       https://codexshaper.com
 * @since      1.0.0
 */

namespace CodexShaper\Framework\Providers;

use CodexShaper\Framework\Foundation\ServiceProvider;
use CodexShaper\Framework\Foundation\Traits\Hook;
use CodexShaper\Framework\Providers\Elementor\ModuleServiceProvider;

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

/**
 * Elementor Service Provider Class
 *
 * @category   Class
 * @package    CodexShaper_Framework
 * @author     CodexShaper <info@codexshaper.com>
 * @license    https://www.gnu.org/licenses/gpl-2.0.html
 * @link       https://codexshaper.com
 * @since      1.0.0
 */
class ElementorServiceProvider extends ServiceProvider {
	use Hook;

	/**
	 * The provider class names.
	 *
	 * @var string[]
	 */
	public $providers = array();

	/**
	 * Minimum Elementor Version
	 *
	 * @since 1.0.0
	 * @var string Minimum Elementor version required to run the bucket.
	 */
	const MINIMUM_ELEMENTOR_VERSION = '3.21.0';

	/**
	 * Minimum PHP Version
	 *
	 * @since 1.0.0
	 * @var string Minimum PHP version required to run the bucket.
	 */
	const MINIMUM_PHP_VERSION = '7.4';

	/**
	 * Module Manager
	 *
	 * @since 1.0.0
	 * @access private
	 * @var \CodexShaper\Framework\Manager\ElementorModuleManager module manager.
	 */
	private $module_manager;

	/**
	 * Constructor
	 *
	 * Perform some compatibility checks to make sure basic requirements are meet.
	 * If all compatibility checks pass, initialize the functionality.
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function register() {

		$this->providers = apply_filters( 'csmf_elementor_providers', $this->providers );

		if ( $this->is_compatible() ) {
			$this->providers = array_merge(
				$this->providers,
				array(
					ModuleServiceProvider::class,
				)
			);
			add_action( 'elementor/init', array( $this, 'init' ) );

			add_action('elementor/editor/before_enqueue_scripts', [$this, 'editor_scripts']);

			// Styles.
			add_action( 'elementor/frontend/before_enqueue_styles', array( $this, 'register_frontend_styles' ) );
			add_action( 'elementor/frontend/after_enqueue_styles', array( $this, 'enqueue_styles' ) );

			// Scripts.
			add_action( 'elementor/frontend/before_register_scripts', array( $this, 'register_frontend_scripts' ) );
			add_action( 'elementor/frontend/after_enqueue_scripts', array( $this, 'enqueue_frontend_scripts' ) );

		}
		// Admin enqueue.
		add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) );
	}

	/**
	 * Initialize
	 *
	 * Load the buckets functionality only after Elementor is initialized.
	 *
	 * Fired by `elementor/init` action hook.
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function init() {
		// Register Widget Categories.
		add_action( 'elementor/elements/categories_registered', array( $this, 'add_widget_categories' ) );
	}

	public function editor_scripts() {
        // Register Select2 if not already registered by Elementor
        if (!wp_script_is('select2', 'registered')) {
            wp_register_script(
                'select2',
                CSMF_URL . 'assets/js/select2.min.js',
                ['jquery'],
                '4.1.0',
                true
            );

            wp_register_style(
                'select2',
                CSMF_URL . 'assets/css/select2.min.css',
                [],
                '4.1.0'
            );
        }

		wp_enqueue_style( 
			'csmf--editor',
			CSMF_URL . 'assets/css/editor' . CSMF_MIN_EXTENSION . '.css',
			[],
			filemtime(CSMF_PATH . 'assets/css/editor' . CSMF_MIN_EXTENSION . '.css'),
		);
    }

	/**
	 * Register frontend styles
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function register_frontend_styles() {
		wp_register_style(
			'csmf-eb-swiper',
			csmf_plugin_base_url() . 'widgets/elementor/assets/vendor/swiper/bundle.min.css',
			array(),
			'11.1.4',
			'all'
		);
	}

	/**
	 * Enqueue styles
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function enqueue_styles() {
		wp_enqueue_style(
			'csmf-eb-frontend',
			csmf_plugin_base_url() . 'widgets/elementor/assets/css/eb-frontend.css',
			array(),
			CSMF_APP_VERSION,
			'all'
		);
	}

	/**
	 * Register frontend scripts
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function register_frontend_scripts() {
		wp_register_script(
			'csmf-eb-swiper',
			csmf_plugin_base_url() . 'widgets/elementor/assets/vendor/swiper/bundle.min.js',
			array( 'jquery' ),
			'11.1.4',
			true
		);
	}

	/**
	 * Enqueue frontend scripts
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function enqueue_frontend_scripts() {
	}

	/**
	 * Enqueue admin scripts
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function admin_enqueue() {
		wp_register_style(
			'csmf-eb-admin-css',
			csmf_plugin_base_url() . 'widgets/elementor/assets/css/eb-admin.css',
			array(),
			CSMF_APP_VERSION,
			'all',
		);

		wp_register_style(
			'csmf-eb-google-fonts',
			add_query_arg( 'family', rawurlencode( 'Rethink+Sans:ital,wght@0,400..800;1,400..800&display=swap' ), '//fonts.googleapis.com/css' ),
			array(),
			CSMF_APP_VERSION,
			'all',
		);

		wp_enqueue_style( 'csmf-eb-admin-css' );
		wp_enqueue_style( 'csmf-eb-google-fonts' );
	}

	/**
	 * Register elementor categories
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param \Elementor\Elements_Manager $elements_manager elements manager object.
	 *
	 * @return void
	 */
	public function add_widget_categories( $elements_manager ) {

		$categories = array(
			'csmf--widget' => array(
				'title' => esc_html__( 'CodexShaper Framework', 'codexshaper-framework' ),
				'icon'  => 'fa fa-plug',
			),
		);

		// See the original solution here https://github.com/elementor/elementor/issues/7445#issuecomment-692123467.
		$old_categories = $elements_manager->get_categories();
		$categories     = array_merge( $categories, $old_categories );

		$set_categories = function ( $categories ) {
			$this->categories = $categories;
		};

		$set_categories->call( $elements_manager, $categories );
	}

	/**
	 * Check compatibility
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return bool
	 */
	public function is_compatible() {

		// Check if Elementor installed and activated.
		if ( ! did_action( 'elementor/loaded' ) ) {
			add_action( 'admin_notices', array( $this, 'admin_notice_missing_elementor_activation' ) );
			return false;
		}

		// Check for required Elementor version.
		if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) {
			add_action( 'admin_notices', array( $this, 'admin_notice_minimum_elementor_version' ) );
			return false;
		}

		// Check for required PHP version.
		if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) {
			add_action( 'admin_notices', array( $this, 'admin_notice_minimum_php_version' ) );
			return false;
		}

		return true;
	}

	/**
	 * Check element active or not. If not active display activation button.
	 * If not installed then diaplay installation button.
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function admin_notice_missing_elementor_activation() {

		$btn['text'] = esc_html__( 'Install Elementor', 'codexshaper-framework' );
		$btn['url']  = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=elementor' ), 'install-plugin_elementor' );

		if ( file_exists( WP_PLUGIN_DIR . '/elementor/elementor.php' ) ) {
			$btn['text'] = esc_html__( 'Activate Elementor', 'codexshaper-framework' );
			$btn['url']  = wp_nonce_url( 'plugins.php?action=activate&plugin=elementor/elementor.php&plugin_status=all&paged=1', 'activate-plugin_elementor/elementor.php' );
		}

		printf(
			'<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>',
			sprintf(
				/* translators: 1: Plugin name 2: Elementor  */
				esc_html__( '"%1$s" uses "%2$s" to build widgets. For "%2$s" to work, you need "%2$s" plugin to be installed and activated. Click here to %3$s', 'codexshaper-framework' ),
				'<strong>' . esc_html__( 'CodexShaper Framework', 'codexshaper-framework' ) . '</strong>',
				'<strong>' . esc_html__( 'Elementor', 'codexshaper-framework' ) . '</strong>',
				'<a href="' . esc_url( $btn['url'] ) . '" class="button button-primary">' . esc_html( $btn['text'] ) . '</a>'
			)
		);
	}

	/**
	 * Check minimum elementor version
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function admin_notice_minimum_elementor_version() {

		printf(
			'<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>',
			sprintf(
				/* translators: 1: Plugin name 2: Required Elementor version */
				esc_html__( '"%1$s" requires Elementor Version %2$s or greater.', 'codexshaper-framework' ),
				'<strong>' . esc_html__( 'CodexShaper Framework', 'codexshaper-framework' ) . '</strong>',
				esc_html( self::MINIMUM_ELEMENTOR_VERSION )
			)
		);
	}

	/**
	 * Check PHP Version
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function admin_notice_minimum_php_version() {

		printf(
			'<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>',
			sprintf(
				/* translators: 1: Plugin name 2: PHP Version 3: Required PHP version */
				esc_html__( '"%1$s" requires PHP Version %2$s or greater.', 'codexshaper-framework' ),
				'<strong>' . esc_html__( 'CodexShaper Framework', 'codexshaper-framework' ) . '</strong>',
				esc_html( self::MINIMUM_PHP_VERSION )
			)
		);
	}

	/**
	 * Get asset url
	 *
	 * @since 1.0.0
	 * @access public
	 * @static
	 *
	 * @param string $path an asset path.
	 *
	 * @return string
	 */
	public static function asset_url( $path = '' ) {
		return csmf_plugin_base_url() . 'widgets/elementor/assets/' . $path;
	}
}
