<?php

namespace Hecate\Controls\Components;

use Hecate\Defaults;
use Hecate\Lodash;
use Hecate\Components\ComponentBase;

/**
 * Class is used internally in hecate to store configuration for controls added in sections and panels. This is not the
 * used for registring controls into WordPress. The class used to register the control type in WordPress can be found in
 * the Hecate\Customizer\Controls namespace
 */
class BaseControl {


	/**
	 * @var string .The setting that will be used
	 */
	public $settingId;


	/**
	 * @var string. The control type(input, checkbox, etc...)
	 */
	public $type;

	/**
	 * @var string. The label of the control
	 */
	public $label = 'Generic control';


	/**
	 * @var string. The id of the section that contains this control.
	 */
	public $section;

	/**
	 * @var string. The default value of the setting.
	 */
	public $default = null;

	/**
	 * @var int . Used for order of the component. It will be ignored in most cases because we will use the order inside
	 *  the tabs/accordions all of the controls should have the same priority and we will use the order in which we load elements.
	 */
	public $priority = 10;

	//
	/**
	 * @var callable|null. Callback used to determine if the control should be visible
	 */
	public $activeCallback;


	/**
	 * @var callable. This function is called on partial refresh when the setting change to recompute the component
	 */
	public $renderCallback;


	/**
	 * @var ComponentBase
	 */
	public $component;

	public $selector;


	/**
	 * @param string[] $data Various parameters needed by the control
	 * @param ComponentBase $component The component that holds the control
	 */
	public function __construct( array $data, ComponentBase $component ) {

		$defaultData = array(
			'settingId'       => null,
			'type'            => null,
			'section'         => null,
			'active_callback' => null,
		);
		$mergedData  = Lodash::merge( $defaultData, $data );

		//extract the variables
		extract( $mergedData );

		$path       = $mergedData['settingId'];
		$this->path = $path;

		$settingId       = $component->settingPath( $settingId );
		$this->settingId = $settingId;

		if ( ! $section ) {
			$section = $component->getSectionId();
		}
		$this->section = $section;

		if ( ! $active_callback ) {
			$this->activeCallback = $active_callback;
		}

		if ( ! ! $type ) {
			$this->type = $type;
		}

		$this->selector       = $component->getPartialRefreshSelector();
		$this->renderCallback = array( $component, 'getPartialRefreshContent' );
		$this->component      = $component;

	}

	/**
	 * TODO Overwrite me in children classes to add extra options
	 * @return string[]
	 */
	public function getExtraWordpressControlSettings() {
		return array();
	}

	/**
	 * Returns the parameters needed when for inserting the WordPress controller. The key word is that this is for the controller
	 * @return string[]
	 */
	public function getWordpressControlSettings() {
		$extraSettings = $this->getExtraWordpressControlSettings();

		$settings = array(
			'type'     => $this->type,
			'label'    => $this->label,
			'section'  => $this->section,
			'priority' => $this->priority,
		);

		if ( ! ! $this->activeCallback ) {
			$settings['active_callback'] = $this->activeCallback;
		}
		return Lodash::merge( $settings, $extraSettings );
	}

	public function sanitize( $value, $control, $default = '' ) {
		return '';
	}

	/**
	 *  Parameters needed when for registering a WordPress setting used by the controllers
	 */
	public function getWordpressSettingParams() {
        $self = $this;
        $santizeCallback = function($value, $control ) use($self) {
            return $self->sanitize($value, $control);
        };
		return  array(
			'type'                 => 'theme_mod',
			'sanitize_callback'    => $santizeCallback,
			'transport'            => 'postMessage',
            //'transport'            => 'refresh',
			'default'              => $this->default,
		);
	}

	public static function getWordpressPartialParams( $controls ) {
		$partialRefreshData = array();
		foreach ( $controls as $control ) {

			$componentId = $control->component->getComponentId();
			if ( ! isset( $partialRefreshData[ $componentId ] ) ) {

				$partialRefreshData[ $componentId ] = array(
					'selector'        => $control->selector,
					'render_callback' => $control->renderCallback,
					'settings'        => array( $control->settingId ),
                    'container_inclusive' => true,
				);
			} else {
				$data                               = $partialRefreshData[ $componentId ];
				$data['settings'][]                 = $control->settingId;
				$partialRefreshData[ $componentId ] = $data;

			}
		}

		return $partialRefreshData;
	}

}
