<?php

namespace PowerpackElements\Base;

use Elementor\Controls_Manager;

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

/**
 * Extension
 *
 * Class to easify extend Elementor controls and functionality
 *
 * @since 0.1.0
 */
class Extension_Base {

	/**
	 * Is Common Extension
	 *
	 * Defines if the current extension is common for all element types or not
	 *
	 * @since 1.8.0
	 * @access private
	 *
	 * @var bool
	 */
	protected $is_common = false;

	/**
	 * Depended scripts.
	 *
	 * Holds all the extension depended scripts to enqueue.
	 *
	 * @since 1.8.0
	 * @access private
	 *
	 * @var array
	 */
	private $depended_scripts = [];

	/**
	 * Depended styles.
	 *
	 * Holds all the extension depended styles to enqueue.
	 *
	 * @since 1.8.0
	 * @access private
	 *
	 * @var array
	 */
	private $depended_styles = [];

	/**
	 * Constructor
	 *
	 * @since 0.1.0
	 * @access public
	 */
	final public function __construct() {

		// Enqueue scripts
		add_action( 'elementor/frontend/after_enqueue_scripts', [ $this, 'enqueue_scripts' ] );

		// Enqueue styles
		add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'enqueue_styles' ] );

		// Elementor hooks

		if ( $this->is_common ) {
			// Add the advanced section required to display controls
			$this->add_common_sections_actions();
		}

		$this->add_actions();
	}

	/**
	 * Add script depends.
	 *
	 * Register new script to enqueue by the handler.
	 *
	 * @since 1.8.0
	 * @access public
	 *
	 * @param string $handler Depend script handler.
	 */
	public function add_script_depends( $handler ) {
		$this->depended_scripts[] = $handler;
	}

	/**
	 * Add style depends.
	 *
	 * Register new style to enqueue by the handler.
	 *
	 * @since 1.8.0
	 * @access public
	 *
	 * @param string $handler Depend style handler.
	 */
	public function add_style_depends( $handler ) {
		$this->depended_styles[] = $handler;
	}

	/**
	 * Get script dependencies.
	 *
	 * Retrieve the list of script dependencies the extension requires.
	 *
	 * @since 1.8.0
	 * @access public
	 *
	 * @return array Widget scripts dependencies.
	 */
	public function get_script_depends() {
		return $this->depended_scripts;
	}

	/**
	 * Enqueue scripts.
	 *
	 * Registers all the scripts defined as extension dependencies and enqueues
	 * them. Use `get_script_depends()` method to add custom script dependencies.
	 *
	 * @since 1.8.0
	 * @access public
	 */
	final public function enqueue_scripts() {
		foreach ( $this->get_script_depends() as $script ) {
			wp_enqueue_script( $script );
		}
	}

	/**
	 * Retrieve style dependencies.
	 *
	 * Get the list of style dependencies the extension requires.
	 *
	 * @since 1.8.0
	 * @access public
	 *
	 * @return array Widget styles dependencies.
	 */
	public function get_style_depends() {
		return $this->depended_styles;
	}

	/**
	 * Retrieve extension description.
	 *
	 * @since 1.8.0
	 * @access public
	 *
	 * @return string Widget description.
	 */
	public static function get_description() {}

	/**
	 * Enqueue styles.
	 *
	 * Registers all the styles defined as extension dependencies and enqueues
	 * them. Use `get_style_depends()` method to add custom style dependencies.
	 *
	 * @since 1.8.0
	 * @access public
	 */
	final public function enqueue_styles() {
		foreach ( $this->get_style_depends() as $style ) {
			wp_enqueue_style( $style );
		}
	}

	/**
	 * Add extension section
	 *
	 * Registers a dedicated controls section for the extension on the given element.
	 *
	 * @since 3.0.0
	 *
	 * @access protected
	 *
	 * @param \Elementor\Controls_Stack $element      The element the section is added to.
	 * @param string                    $section_name Unique name of the section.
	 * @param string                    $label        Section title. Must be escaped by the caller.
	 * @param string                    $tab          Optional. Panel tab the section belongs to.
	 * @return bool False if the section already exists on the element.
	 */
	final protected function add_extension_section( $element, $section_name, $label, $tab = Controls_Manager::TAB_ADVANCED ) {

		// Check if this section exists
		$section_exists = \Elementor\Plugin::instance()->controls_manager->get_control_from_stack( $element->get_unique_name(), $section_name );

		if ( ! is_wp_error( $section_exists ) ) {
			// We can't and should try to add this section to the stack
			return false;
		}

		$element->start_controls_section(
			$section_name,
			[
				'tab'   => $tab,
				'label' => self::get_section_title( $label ),
			]
		);

		$element->end_controls_section();

		return true;
	}

	/**
	 * Get section title
	 *
	 * Prefixes an extension section title with the mark this site draws: the
	 * site's own logo, ours, the name it renamed us to, or nothing at all. The
	 * order is the order of how directly each answers "put a mark here", so an
	 * uploaded logo wins over a name, and Hide Logo wins over everything.
	 *
	 * @since 3.0.0
	 *
	 * @access public
	 *
	 * @param string $label Section title. Must be escaped by the caller.
	 * @return string
	 */
	public static function get_section_title( $label ) {

		$settings = \PowerpackElements\Classes\PP_Admin_Settings::get_settings();

		/*
		 * Hiding leaves the extension's own name standing on its own, the same
		 * as it does in the template library. Checked before the rename, so a
		 * site that hid the mark and set a name is not handed the name here as
		 * a consolation mark it never asked for.
		 */
		if ( 'on' === $settings['hide_logo'] ) {
			return $label;
		}

		$custom = \PowerpackElements\Classes\PP_Admin_Settings::get_custom_logo();

		if ( '' !== $custom ) {
			return sprintf(
				'<img class="pp-panel-heading-logo" src="%s" alt="" aria-hidden="true" />',
				esc_url( $custom )
			) . $label;
		}

		$admin_label = \PowerpackElements\Classes\PP_Admin_Settings::get_admin_label();

		if ( 'PowerPack' !== $admin_label ) {
			return esc_html( $admin_label ) . ' ' . $label;
		}

		return '<i class="ppicon-powerpack-small pp-panel-heading-logo" aria-hidden="true"></i>' . $label;
	}

	/**
	 * Add common sections
	 *
	 * @since 1.8.0
	 *
	 * @access protected
	 */
	protected function add_common_sections_actions() {}

	/**
	 * Add Actions
	 *
	 * @since 0.1.0
	 *
	 * @access private
	 */
	protected function add_actions() {}

	/**
	 * Removes controls in bulk
	 *
	 * @since 0.1.0
	 *
	 * @access private
	 */
	protected function remove_controls( $element, $controls = null ) {
		if ( empty( $controls ) ) {
			return;
		}

		if ( is_array( $controls ) ) {
			$control_id = $controls;

			foreach ( $controls as $control_id ) {
				$element->remove_control( $control_id );
			}
		} else {
			$element->remove_control( $controls );
		}
	}

	/**
	 * Method for setting extension dependancy on Elementor Pro plugin
	 *
	 * When returning false it doesn't allow the extension to be registered
	 *
	 * @access public
	 * @since 1.8.0
	 * @return bool
	 */
	public static function requires_elementor_pro() {
		return false;
	}

	/**
	 * Is enabled by default
	 *
	 * Return wether or not the extension should be disabled by default,
	 * prior to user actually saving a value in the admin page
	 *
	 * @access public
	 * @since 2.0.0
	 * @return bool
	 */
	public static function is_default_disabled() {
		return false;
	}

}
