<?php
/**
 * Zenvy Customizer Builder
 *
 * @package Zenvy
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! function_exists( 'zenvy_sanitize_field_recursive' ) ) {

	/**
	 * Recursively sanitize a field value.
	 *
	 * @param mixed $value Value to sanitize.
	 * @return mixed
	 */
	function zenvy_sanitize_field_recursive( $value ) {
		if ( ! is_array( $value ) ) {
			$value = wp_kses_post( $value );
		} elseif ( is_array( $value ) ) {
			foreach ( $value as $k => $v ) {
				$value[ $k ] = zenvy_sanitize_field_recursive( $v );
			}
		}
		return $value;
	}
}

if ( ! function_exists( 'zenvy_sanitize_field' ) ) {

	/**
	 * Sanitize a customizer field input.
	 *
	 * @param mixed $input Raw input value to sanitize.
	 * @return string
	 */
	function zenvy_sanitize_field( $input ) {
		$input = wp_unslash( $input );
		if ( ! is_array( $input ) ) {
			$input = json_decode( urldecode_deep( $input ), true );
		}
		$output = zenvy_sanitize_field_recursive( $input );
		$output = wp_json_encode( $output );
		return $output;
	}
}

/**
 * Add Builder to WP Customize.
 *
 * Class Zenvy_Customizer_Builder
 */
class Zenvy_Customizer_Builder {

	/**
	 * Main Instance
	 *
	 * Insures that only one instance of Zenvy_Customizer_Builder exists in memory at any one
	 * time. Also prevents needing to define globals all over the place.
	 *
	 * @return object
	 */
	public static function instance() {

		// Store the instance locally to avoid private static replication.
		static $instance = null;

		// Only run these methods if they haven't been ran previously.
		if ( null === $instance ) {
			$instance = new self();
		}

		// Always return the instance.
		return $instance;
	}

	/**
	 * Run functionality with hooks.
	 *
	 * @return void
	 */
	public function run() {

		if ( ! is_admin() ) {
			return;
		}

		add_action( 'customize_controls_enqueue_scripts', [ $this, 'enqueue' ] );
		add_action( 'customize_controls_print_footer_scripts', [ $this, 'builder_template' ] );
	}

	/**
	 * Get all builders registered.
	 *
	 * Insures that every builder is registered by zenvy_builders filter.
	 *
	 * @return array
	 */
	public function get_builders() {
		$builders = [];
		$builders = apply_filters( 'zenvy_builders', $builders );
		return $builders;
	}

	/**
	 * Callback functions for customize_controls_enqueue_scripts.
	 * Enqueue script and style for builder.
	 *
	 * @return void
	 */
	public function enqueue() {

		// Enqueue customizer styles.
		wp_enqueue_style(
			'zenvy-customizer-builder',
			ZENVY_THEME_URI . 'assets/build/css/customize-builder.css',
			[],
			ZENVY_THEME_VERSION,
			'all'
		);
		wp_style_add_data( 'zenvy-customizer-builder', 'rtl', 'replace' );

		wp_enqueue_script(
			'zenvy-customizer-builder',
			ZENVY_THEME_URI . 'assets/build/js/customize-builder.js',
			[
				'customize-controls',
				'jquery-ui-droppable',
			],
			ZENVY_THEME_VERSION,
			true
		);

		wp_localize_script(
			'zenvy-customizer-builder',
			'Zenvy_Customizer_Builder',
			[
				'footer_moved_widgets_text' => '',
				'builders'                  => $this->get_builders(),
				'desktop_label'             => esc_html__( 'Desktop', 'zenvy' ),
				'mobile_tablet_label'       => esc_html__( 'Mobile/Tablet', 'zenvy' ),
			]
		);
	}

	/**
	 * Callback functions for customize_controls_print_footer_scripts.
	 * Add Builder Template.
	 *
	 * @access public
	 *
	 * @return void
	 */
	public function builder_template() {

		require ZENVY_THEME_DIR . 'inc/customizer/builder/header/views/builder-template.php';
	}
}

if ( ! function_exists( 'zenvy_customizer_builder' ) ) {

	/**
	 * Create instance for Zenvy_Customizer_Builder.
	 *
	 * @return object
	 */
	function zenvy_customizer_builder() {

		return Zenvy_Customizer_Builder::instance();
	}

	zenvy_customizer_builder()->run();
}
