<?php

namespace Hecate\Customizer;

use Hecate\Components\ComponentsRepository;
use Hecate\Controls\Components\BaseControl;
use Hecate\Lodash;

class DynamicComponentsTemplate {
	private static $instance            = null;
	protected $dynamicComponentsNames   = array();
	protected $templatesByComponentType = array();
	protected $componentIdPlaceholder   = 'hecateTemplateId444';

	protected function __construct() {
		$this->dynamicComponentsNames = ComponentsRepository::getInstance()->getComponentsTypes();
		$this->generateTemplates();
		add_filter(
			'customize_dynamic_setting_args',
			array( $this, 'addDynamicSettings' ),
			10,
			2
		);
		add_filter( 'customize_dynamic_partial_args', array( $this, 'addDynamicPartials' ), 10, 2 );

	}

	public function addDynamicSettings( $settingArgs, $settingId = '' ) {
		if ( ! $settingArgs ) {

			$settingArgs = array(
				'sanitize_callback' => '',
			);
		}
		return $settingArgs;
	}

	public function addDynamicPartials( $partialArgs, $partialId ) {

		if ( ! $partialArgs ) {

			/**
			 * Dynamic components have this structure for settings and partials
			 * settingId = componentId.controlId and the componentId have this following structure:
			 * componentId = componentType__randomString
			 * We can split the string to determine relevant information like component id and componentType
			 */
			$pieces        = explode( '__', $partialId );
			$componentType = $pieces[0];

			if ( count( $pieces ) < 2 ) {
				return $partialArgs;
			}

			$pieces      = explode( '.', $partialId );
			$componentId = $pieces[0];
			if ( count( $pieces ) < 2 ) {
				return $partialArgs;
			}

			$component = ComponentsRepository::getComponent( $componentId, $componentType );
			if ( ! $component ) {
				return $partialArgs;
			}
			global $wp_customize;
			$controls                        = $component->getControls();
			$partialRefreshDataByComponentId = BaseControl::getWordpressPartialParams( $controls );
			$partialRefreshData              = Lodash::get( $partialRefreshDataByComponentId, $componentId );

			//register dynamic settings because when dynamic partials are created it checks for the setting
			CustomizerManager::getInstance()->registerControlsAndSettings( $wp_customize, $controls );
			return $partialRefreshData;

		}
		return $partialArgs;
	}


	private function generateTemplates() {
		$templatesByComponentType = array();
		foreach ( $this->dynamicComponentsNames as $componentsName ) {
			$componentClass = ComponentsRepository::getInstance()->getComponentClassByType( $componentsName );
			if ( ! $componentClass ) {
				continue;
			}
			$componentConstructorData = array(
				'componentId' => $this->componentIdPlaceholder,
			);
			$component                = new $componentClass( $componentConstructorData );
			$sections                 = $component->getSections();
			$controls                 = $component->getControls();

			$componentParts    = $component->componentParts;
			$componentDefaults = $component->componentDefaults;

			$sectionsParameters = $sections;
			$controlsParameters = array();
			$settingsParameters = array();
			$partialParameters  = $this->getPartialParameters( $controls, $this->componentIdPlaceholder );

			foreach ( $controls as $control ) {
				$controlsParameters[ $control->settingId ] = $this->getControlParameters( $control );
				$settingsParameters[ $control->settingId ] = $this->getSettingParameters( $control );
			}

			$templatesByComponentType[ $componentsName ] = array(
				'sections'       => $sectionsParameters,
				'controls'       => $controlsParameters,
				'settings'       => $settingsParameters,
				'partials'       => $partialParameters,
				'componentParts' => $componentParts,
				'defaults'       => $componentDefaults,
			);
		}

		$this->templatesByComponentType = $templatesByComponentType;

	}

	protected function getControlParameters( $control ) {
		return $control->getWordpressControlSettings();
	}

	protected function getSettingParameters( $control ) {
		$extraOptions = array(
			'setting'        => $control->settingId,
			'dynamicContent' => true,
		);
		return  array_merge( $control->getWordpressSettingParams(), $extraOptions );
	}

	protected function getPartialParameters( $controls, $componentId ) {
		$parameters = BaseControl::getWordpressPartialParams( $controls );
		return Lodash::get( $parameters, $componentId, array() );
	}

	public function exportToJs() {
		$data = array(
			'componentIdPlaceholder'   => $this->componentIdPlaceholder,
			'templatesByComponentType' => $this->templatesByComponentType,
		);

		return $data;
	}

	public static function init() {
		return self::getInstance();
	}

	public static function getInstance() {
		if ( ! self::$instance ) {
			self::$instance = new static();
		}

		return self::$instance;
	}
}
