<?php
/**
 * Read More/Less element.
 *
 * @package BricksExtras
 */

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

/**
 * Read More/Less element class.
 */
class X_Read_More_Less extends \Bricks\Element {

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';
	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xreadmoreless';
	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-layout-cta-center';
	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '';
	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xReadMoreLess' );
	/**
	 * Element is nestable.
	 *
	 * @var bool
	 */
	public $nestable = true;
	/**
	 * Script localized flag.
	 *
	 * @var bool
	 */
	private static $script_localized = false;


	/**
	 * Get element label.
	 */
	public function get_label() {
		return esc_html__( 'Read More / Less', 'bricksextras' );
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( 'read', 'more', 'less' );
	}

	/**
	 * Set control groups.
	 */
	public function set_control_groups() {

		$this->control_groups['content'] = array(
			'title' => esc_html__( 'Content', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['button'] = array(
			'title' => esc_html__( 'Button', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['icon'] = array(
			'title' => esc_html__( 'Icon', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['fadeGradient'] = array(
			'title' => esc_html__( 'Gradient', 'bricks' ),
			'tab'   => 'content',
		);
	}

	/**
	 * Set element controls.
	 */
	public function set_controls() {

		$this->controls['builderVisibility'] = array(
			'tab'    => 'content',
			'inline' => true,
			'small'  => true,
			'label'  => esc_html__( 'Preview', 'bricks' ),
			'type'   => 'checkbox',
		);

		$this->controls['collapsedHeight'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Height', 'bricks' ) . ' (' . esc_html__( 'Collapsed', 'bricks' ) . ')',
			'type'        => 'number',
			'css'         => array(
				array(
					'selector' => '.x-read-more_content',
					'property' => 'max-height',
				),
				'',
			),
			'placeholder' => '200px',
			'units'       => 'px',
		);

		$this->controls['speed'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Animation speed in ms', 'bricks' ),
			'type'        => 'number',
			'units'       => false,
			'inline'      => true,
			'small'       => true,
			'placeholder' => '300',
		);

		$this->controls['heightMargin'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Height margin', 'bricksextras' ) . ' (px)',
			'type'        => 'number',
			'units'       => false,
			'inline'      => true,
			'small'       => true,
			'placeholder' => '20',
		);

		$this->controls['readMoreContent'] = array(
			'tab'         => 'content',
			'group'       => 'content',
			'label'       => esc_html__( 'Content', 'bricks' ),
			'type'        => 'select',
			'options'     => array(
				'wysiwyg'  => esc_html__( 'Text editor', 'bricks' ),
				'nestable' => esc_html__( 'Add elements', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Text editor', 'bricks' ),
			'clearable'   => false,
			'default'     => 'wysiwyg',
		);

		$this->controls['readMoreWysiwyg'] = array(
			'tab'           => 'content',
			'group'         => 'content',
			'label'         => esc_html__( 'Text editor', 'bricks' ),
			'type'          => 'editor',
			'inlineEditing' => array(
				'selector' => '.text-editor',
				'toolbar'  => true,
			),
			'default'       => "<p>Edit me, chia DIY typewriter schlitz single-origin coffee subway tile. Next level before they sold out vice truffaut, edison bulb mixtape drinking vinegar hexagon chia tattooed sustainable single-origin coffee biodiesel chambray fashion axe. Etsy trust fund authentic hammock 3 wolf moon sartorial bespoke umami tattooed. Cardigan pabst keffiyeh try-hard cold-pressed four loko food truck sustainable tote bag occupy before they sold out mixtape. Ramps tote bag freegan DIY palo santo YOLO pabst you probably haven't heard of them shabby chic. Aesthetic trust fund ugh, tousled readymade health goth tacos slow-carb tonx. Vinyl gluten-free readymade poke +1 normcore.</p>",
			'required'      => array( 'readMoreContent', '!=', 'nestable' ),
		);

		/* read more button */

		$button = '.x-read-more_link';

		$this->controls['moreText'] = array(
			'tab'     => 'content',
			'group'   => 'button',
			'label'   => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'More', 'bricksextras' ) . ')',
			'inline'  => true,
			'type'    => 'text',
			'default' => 'Read more',
		);

		$this->controls['lessText'] = array(
			'tab'     => 'content',
			'group'   => 'button',
			'label'   => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Less', 'bricksextras' ) . ')',
			'inline'  => true,
			'type'    => 'text',
			'default' => 'Read Less',
		);

		$this->controls['ariaLabels'] = array(
			'type'  => 'separator',
			'label' => 'Aria-label',
			'group' => 'button',
		);

		$this->controls['moreAria'] = array(
			'tab'     => 'content',
			'group'   => 'button',
			'label'   => esc_html__( 'More', 'bricksextras' ),
			'inline'  => true,
			'type'    => 'text',
			'default' => 'Read more',
		);

			$this->controls['lessAria'] = array(
				'tab'     => 'content',
				'group'   => 'button',
				'label'   => esc_html__( 'Less', 'bricksextras' ),
				'inline'  => true,
				'type'    => 'text',
				'default' => 'Read Less',
			);

			$this->controls['buttonDuration'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Duration', 'bricks' ) . ' (ms)',
				'type'        => 'number',
				'group'       => 'button',
				'unit'        => 'ms',
				'inline'      => true,
				'small'       => true,
				'placeholder' => '300',
				'css'         => array(
					array(
						'property' => 'animation-duration',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonTypography'] = array(
				'tab'   => 'content',
				'group' => 'button',
				'type'  => 'typography',
				'label' => esc_html__( 'Typography', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'font',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonStyle_start'] = array(
				'tab'   => 'content',
				'group' => 'button',
				'type'  => 'separator',
			);

			$this->controls['buttonBackgroundColor'] = array(
				'tab'   => 'content',
				'group' => 'button',
				'type'  => 'color',
				'label' => esc_html__( 'Background', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'background-color',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonBorder'] = array(
				'tab'   => 'content',
				'group' => 'button',
				'type'  => 'border',
				'label' => esc_html__( 'Border', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'border',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonBoxShadow'] = array(
				'tab'   => 'content',
				'group' => 'button',
				'label' => esc_html__( 'Box shadow', 'bricks' ),
				'type'  => 'box-shadow',
				'css'   => array(
					array(
						'property' => 'box-shadow',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonPosition'] = array(
				'tab'     => 'content',
				'group'   => 'button',
				'label'   => esc_html__( 'Position', 'bricks' ),
				'type'    => 'select',
				'inline'  => true,
				'info'    => 'Absolute will reduce CLS if above fold',
				'options' => array(
					'static'   => 'static',
					'absolute' => 'absolute',
				),
				'css'     => array(
					array(
						'property' => 'position',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonBottom'] = array(
				'tab'         => 'content',
				'group'       => 'button',
				'label'       => esc_html__( 'Bottom', 'bricks' ),
				'type'        => 'number',
				'units'       => true,
				'inline'      => true,
				'required'    => array( 'buttonPosition', '=', 'absolute' ),
				'placeholder' => '0',
				'css'         => array(
					array(
						'property' => 'bottom',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonStyle_end'] = array(
				'tab'   => 'content',
				'group' => 'button',
				'type'  => 'separator',
			);

			$this->controls['buttonPadding'] = array(
				'tab'         => 'content',
				'group'       => 'button',
				'label'       => esc_html__( 'Padding', 'bricks' ),
				'type'        => 'spacing',
				'css'         => array(
					array(
						'property' => 'padding',
						'selector' => $button,
					),
				),
				'placeholder' => array(
					'top'    => '10px',
					'right'  => '10px',
					'bottom' => '10px',
					'left'   => '10px',
				),
			);

			$this->controls['buttonMargin'] = array(
				'tab'      => 'content',
				'group'    => 'button',
				'label'    => esc_html__( 'Margin', 'bricks' ),
				'type'     => 'spacing',
				'required' => array( 'buttonPosition', '!=', 'absolute' ),
				'css'      => array(
					array(
						'property' => 'margin',
						'selector' => $button,
					),
				),
			);

			$this->controls['buttonAlign'] = array(
				'tab'          => 'content',
				'label'        => esc_html__( 'Align', 'bricks' ),
				'type'         => 'align-items',
				'group'        => 'button',
				'css'          => array(
					array(
						'property' => 'align-self',
						'selector' => $button,
					),
					array(
						'required' => 'stretch',
						'property' => 'width',
						'value'    => '100%',
						'selector' => $button,
					),
				),
				'isHorizontal' => false,
				'exclude'      => array(
					'space-between',
					'space-around',
					'space-evenly',
				),
			);

			$this->controls['buttonWidth'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Button width', 'bricks' ),
				'type'   => 'number',
				'inline' => true,
				'group'  => 'button',
				'css'    => array(
					array(
						'selector' => $button,
						'property' => 'width',
					),
				),
				'units'  => true,
			);

			/* icon */

			$this->controls['maybeIcon'] = array(
				'tab'    => 'content',
				'inline' => true,
				'group'  => 'icon',
				'small'  => true,
				'label'  => esc_html__( 'Icon', 'bricks' ),
				'type'   => 'checkbox',
			);

			$this->controls['icon'] = array(
				'tab'     => 'content',
				'group'   => 'icon',
				'label'   => esc_html__( 'Icon', 'bricks' ),
				'type'    => 'icon',
				'css'     => array(
					array(
						'selector' => '.x-read-more_link-icon svg',
					),
				),
				'default' => array(
					'library' => 'ionicons',
					'icon'    => 'ion-ios-arrow-down',
				),
			);

			$this->controls['iconSize'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Icon size', 'bricks' ),
				'type'   => 'number',
				'group'  => 'icon',
				'units'  => array(
					'px' => array(
						'min'  => 1,
						'max'  => 30,
						'step' => 1,
					),
					'em' => array(
						'min'  => 1,
						'max'  => 20,
						'step' => 0.1,
					),
				),
				'inline' => true,
				'css'    => array(
					array(
						'property' => 'font-size',
						'selector' => '.x-read-more_link-icon',
					),
				),
			);

			$this->controls['iconRotate'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Rotation', 'bricks' ) . ' (' . esc_html__( 'Expanded', 'bricks' ) . ')',
				'type'        => 'number',
				'group'       => 'icon',
				'unit'        => 'deg',
				'inline'      => true,
				'small'       => true,
				'placeholder' => '180',
				'css'         => array(
					array(
						'property' => '--x-read-more-rotate',
						'selector' => '.x-read-more_link-icon',
					),
				),
			);

			$this->controls['iconMargin'] = array(
				'tab'   => 'content',
				'group' => 'icon',
				'label' => esc_html__( 'Icon margin', 'bricks' ),
				'type'  => 'spacing',
				'css'   => array(
					array(
						'property' => 'margin',
						'selector' => '.x-read-more_link-icon',
					),
				),
			);

			/* fade gradient */

			$this->controls['maybeGradient'] = array(
				'tab'         => 'content',
				'inline'      => true,
				'group'       => 'fadeGradient',
				'placeholder' => esc_html__( 'Enable', 'bricks' ),
				'label'       => esc_html__( 'Enable', 'bricks' ),
				'type'        => 'select',
				'options'     => array(
					'true'  => esc_html__( 'Enable', 'bricks' ),
					'false' => esc_html__( 'Disable', 'bricks' ),
				),
			);

			$this->controls['fadeSeparator'] = array(
				'tab'   => 'content',
				'type'  => 'separator',
				'group' => 'fadeGradient',
				'label' => esc_html__( 'Fade', 'bricks' ),
			);

			$this->controls['gradientPercentageStart'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Start', 'bricks' ) . ' (%)',
				'type'        => 'number',
				'group'       => 'fadeGradient',
				'css'         => array(
					array(
						'property' => '--x-mask-start',
						'selector' => '.x-read-more_content',
					),
				),
				'placeholder' => '40',
				'unit'        => '%',
				'required'    => array( 'maybeGradient', '!=', 'false' ),
			);

			$this->controls['gradientPercentageEnd'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'End', 'bricks' ) . ' (%)',
				'type'        => 'number',
				'group'       => 'fadeGradient',
				'css'         => array(
					array(
						'property' => '--x-mask-end',
						'selector' => '.x-read-more_content',
					),
				),
				'placeholder' => '90',
				'unit'        => '%',
				'required'    => array( 'maybeGradient', '!=', 'false' ),
			);
	}


	/**
	 * Enqueue scripts.
	 */
	public function enqueue_scripts() {

		if ( bricks_is_builder_main() ) {
			return;
		}

		wp_enqueue_script( 'x-read-more-less', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'readmoreless' ) . '.js', array( 'bricks-scripts' ), \BricksExtras\Plugin::VERSION, true );

		if ( ! self::$script_localized ) {

			wp_localize_script(
				'x-read-more-less',
				'xReadMore',
				array(
					'Instances' => array(),
				)
			);

			self::$script_localized = true;

		}

		if ( ! \BricksExtras\Helpers::element_css_added( $this->name ) ) {
			wp_enqueue_style( 'x-read-more-less', BRICKSEXTRAS_URL . 'components/assets/css/readmoreless.css', array(), \BricksExtras\Plugin::VERSION );
		}
	}

	/**
	 * Render element output.
	 */
	public function render() {

		$icon = empty( $this->settings['icon'] ) ? false : self::render_icon( $this->settings['icon'] );

		$maybe_gradient = isset( $this->settings['maybeGradient'] ) ? ( 'true' === $this->settings['maybeGradient'] ) : true;

		$read_more_content = isset( $this->settings['readMoreContent'] ) ? $this->settings['readMoreContent'] : 'wysiwyg';

		if ( $maybe_gradient ) {
			$this->set_attribute( '_root', 'class', 'x-read-more_fade' );
			$this->set_attribute( '_root', 'data-x-fade', '' );
		}

		$this->set_attribute( 'x-read-more_content', 'class', 'x-read-more_content' );

		$config = array();

		if ( isset( $this->settings['heightMargin'] ) ) {
			$config += array( 'heightMargin' => $this->settings['heightMargin'] );
		}

		if ( isset( $this->settings['speed'] ) ) {
			$config += array( 'speed' => $this->settings['speed'] );
		}

		if ( isset( $this->settings['moreText'] ) ) {
			$config += array( 'moreText' => wp_kses_post( bricks_render_dynamic_data( $this->settings['moreText'] ) ) );
		}

		if ( isset( $this->settings['lessText'] ) ) {
			$config += array( 'lessText' => wp_kses_post( bricks_render_dynamic_data( $this->settings['lessText'] ) ) );
		}

		if ( isset( $this->settings['moreAria'] ) ) {
			$config += array( 'moreAria' => bricks_render_dynamic_data( $this->settings['moreAria'] ) );
		}

		if ( isset( $this->settings['lessAria'] ) ) {
			$config += array( 'lessAria' => bricks_render_dynamic_data( $this->settings['lessAria'] ) );
		}

		// Generate and set a unique identifier for this instance.
		$indentifier = \BricksExtras\Helpers::set_identifier_attribute( $this );

		$this->set_attribute( '_root', 'data-x-readmore', wp_json_encode( $config ) );
		$this->set_attribute( 'x-read-more_icon', 'class', 'x-read-more_icon' );

		$output = '';

		$output .= "<div {$this->render_attributes( '_root' )}>";
		$output .= "<div {$this->render_attributes( 'x-read-more_content' )}>";

		if ( 'wysiwyg' === $read_more_content ) {

			$content = $this->settings['readMoreWysiwyg'];
			$content = $this->render_dynamic_data( $content );
			$content = \Bricks\Helpers::parse_editor_content( $content );
			$output .= $content;

		} elseif ( method_exists( '\Bricks\Frontend', 'render_children' ) ) {
				$output .= \Bricks\Frontend::render_children( $this );
		}

		$output .= '</div>';
		$output .= '</div>';

		if ( $icon ) {
			$output .= "<div style='display: none;' {$this->render_attributes( 'x-read-more_icon' )}> " . $icon . '  </div>';
		}

		echo $output;
	}

	/**
	 * Render builder template.
	 */
	public static function render_builder() {
		?>

		<script type="text/x-template" id="tmpl-bricks-element-xreadmoreless">

			<component 
				:class="{ 'x-read-more_fade' : 'false' !== settings.maybeGradient }"
			>

				<contenteditable
					tag="div"
					v-if="'nestable' !== settings.readMoreContent"
					class="x-read-more_content"
					:class="{ 'x-read-more_builder-expand' : settings.builderVisibility }"
					:name="name"
					controlKey="readMoreWysiwyg"
					toolbar="true"
					:settings="settings"
				/>

				<div 
					v-else
					class="x-read-more_content"
					:class="{ 'x-read-more_builder-expand' : settings.builderVisibility }"
				> 
					<bricks-element-children
						:element="element"
					/>
				</div>

				<button 
					aria-label="Open" 
					class="x-read-more_link"
				>
					<contenteditable
						tag="span"
						class="x-read-more_link-text"
						:name="name"
						controlKey="moreText"
						toolbar="style"
						:settings="settings"
					/>
					<span 
						v-if="settings.maybeIcon"
						class="x-read-more_link-icon"
					>
						<icon-svg 
							:iconSettings="settings.icon"
						/>
					</span>
				</button>
				
			</component>
			
		</script>

		<?php
	}
}