<?php
/**
 * Counters element.
 *
 * One or more animated numbers that count up when scrolled into view. The user
 * adds as many counters as they like, each with its own data, via a repeater.
 *
 * @package CraftAddonsForWPBakery
 */

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

/**
 * Class CAFW_Element_Counter
 */
class CAFW_Element_Counter extends CAFW_Element_Base {

	/**
	 * {@inheritDoc}
	 */
	public function get_shortcode_tag() {
		return 'cafw_counter';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_label() {
		return esc_html__( 'Counter', 'craft-addons-for-wpbakery' );
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_description() {
		return esc_html__( 'Numbers that count up on scroll.', 'craft-addons-for-wpbakery' );
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_admin_icon() {
		return 'dashicons-chart-bar';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_editor_icon() {
		return 'cafw-vc-icon cafw-vc-icon-counter';
	}

	/**
	 * {@inheritDoc}
	 */
	protected function get_defaults() {
		return array(
			'items'              => $this->default_items(),
			'speed'              => '2',
			'gap'                => '8',
			'number_font'        => '',
			'number_google_font' => '',
			'title_font'         => '',
			'title_google_font'  => '',
		);
	}

	/**
	 * Default repeater content (two sample counters).
	 *
	 * @return string
	 */
	private function default_items() {
		$items = array(
			array(
				'number' => '500',
				'suffix' => '+',
				'title'  => esc_html__( 'Happy Clients', 'craft-addons-for-wpbakery' ),
				'color'  => '#111827',
				'bg'     => '#ece8ff',
				'radius' => '16',
			),
			array(
				'number' => '12',
				'suffix' => 'k',
				'title'  => esc_html__( 'Downloads', 'craft-addons-for-wpbakery' ),
				'color'  => '#502bf8',
				'bg'     => '#ece8ff',
				'radius' => '16',
			),
		);

		return rawurlencode( wp_json_encode( $items ) );
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_params() {
		return array_merge( array(
			array(
				'type'        => 'param_group',
				'heading'     => esc_html__( 'Counters', 'craft-addons-for-wpbakery' ),
				'param_name'  => 'items',
				'value'       => $this->default_items(),
				'params'      => array(
					array(
						'type'        => 'iconpicker',
						'heading'     => esc_html__( 'Icon', 'craft-addons-for-wpbakery' ),
						'param_name'  => 'icon',
						'settings'    => array(
							'emptyIcon'    => true,
							'type'         => 'fontawesome',
							'iconsPerPage' => 200,
						),
						'description' => esc_html__( 'Optional - shown above the number.', 'craft-addons-for-wpbakery' ),
					),
					array(
						'type'             => 'colorpicker',
						'heading'          => esc_html__( 'Icon color', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'icon_color',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'textfield',
						'heading'          => esc_html__( 'Icon size (px)', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'icon_size',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'colorpicker',
						'heading'          => esc_html__( 'Background color', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'bg',
						'description'      => esc_html__( 'Background of the whole counter.', 'craft-addons-for-wpbakery' ),
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'textfield',
						'heading'          => esc_html__( 'Border radius (px)', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'radius',
						'description'      => esc_html__( 'Rounds the counter corners.', 'craft-addons-for-wpbakery' ),
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'textfield',
						'heading'          => esc_html__( 'Starting number', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'start',
						'value'            => '0',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'textfield',
						'heading'          => esc_html__( 'Ending number', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'number',
						'admin_label'      => true,
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'textfield',
						'heading'          => esc_html__( 'Prefix', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'prefix',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'textfield',
						'heading'          => esc_html__( 'Suffix', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'suffix',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'       => 'textfield',
						'heading'    => esc_html__( 'Title', 'craft-addons-for-wpbakery' ),
						'param_name' => 'title',
					),
					array(
						'type'             => 'colorpicker',
						'heading'          => esc_html__( 'Number color', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'color',
						'value'            => '#111827',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
					array(
						'type'             => 'colorpicker',
						'heading'          => esc_html__( 'Title color', 'craft-addons-for-wpbakery' ),
						'param_name'       => 'title_color',
						'edit_field_class' => 'vc_col-sm-6 vc_column',
					),
				),
			),
			array(
				'type'             => 'textfield',
				'heading'          => esc_html__( 'Counter speed (seconds)', 'craft-addons-for-wpbakery' ),
				'param_name'       => 'speed',
				'value'            => '2',
				'description'      => esc_html__( 'How long the numbers take to count up.', 'craft-addons-for-wpbakery' ),
				'edit_field_class' => 'vc_col-sm-6 vc_column',
			),
			array(
				'type'             => 'textfield',
				'heading'          => esc_html__( 'Gap (px)', 'craft-addons-for-wpbakery' ),
				'param_name'       => 'gap',
				'value'            => '8',
				'description'      => esc_html__( 'Even spacing between the icon, number and title.', 'craft-addons-for-wpbakery' ),
				'edit_field_class' => 'vc_col-sm-6 vc_column',
			),
		),
			$this->typography_params( 'number', esc_html__( 'Number', 'craft-addons-for-wpbakery' ), array( 'color' => false ) ),
			$this->typography_params( 'title', esc_html__( 'Title', 'craft-addons-for-wpbakery' ), array( 'color' => false, 'sep' => true ) )
		);
	}

	/**
	 * Parse the repeater value into an array of counter items.
	 *
	 * @param string $raw Raw param_group value.
	 * @return array[]
	 */
	private function parse_items( $raw ) {
		if ( function_exists( 'vc_param_group_parse_atts' ) ) {
			$items = vc_param_group_parse_atts( $raw );
			return is_array( $items ) ? $items : array();
		}

		$decoded = json_decode( rawurldecode( (string) $raw ), true );
		return is_array( $decoded ) ? $decoded : array();
	}

	/**
	 * {@inheritDoc}
	 */
	public function render( $atts, $content, $el_id ) {
		$items = $this->parse_items( $atts['items'] );

		if ( empty( $items ) ) {
			return '';
		}

		wp_enqueue_script( 'cafw-counter' );

		$has_icon = false;
		foreach ( $items as $maybe_item ) {
			if ( ! empty( $maybe_item['icon'] ) ) {
				$has_icon = true;
				break;
			}
		}
		if ( $has_icon && function_exists( 'vc_icon_element_fonts_enqueue' ) ) {
			vc_icon_element_fonts_enqueue( 'fontawesome' );
		}

		// One animation duration for the whole element (entered in seconds).
		$speed    = (float) ( isset( $atts['speed'] ) ? $atts['speed'] : 2 );
		$duration = $speed > 0 ? (int) round( $speed * 1000 ) : 2000;

		// Even vertical spacing between the icon, number and title (px).
		$gap = ( isset( $atts['gap'] ) && '' !== $atts['gap'] ) ? absint( $atts['gap'] ) : 8;

		$number_type = $this->part_typography( $atts, 'number' );
		$title_type  = $this->part_typography( $atts, 'title' );

		ob_start();
		echo $this->open_root( $atts, $el_id, 'cafw-counters' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- open_root escapes internally.

		foreach ( $items as $item ) {
			$item     = wp_parse_args(
				$item,
				array(
					'icon'        => '',
					'icon_color'  => '',
					'icon_size'   => '',
					'bg'          => '',
					'radius'      => '',
					'start'       => '0',
					'number'      => '0',
					'prefix'      => '',
					'suffix'      => '',
					'title'       => '',
					'color'       => '',
					'title_color' => '',
				)
			);
			$number   = preg_replace( '/[^0-9.]/', '', (string) $item['number'] );
			$number   = '' === $number ? '0' : $number;
			$start    = preg_replace( '/[^0-9.]/', '', (string) $item['start'] );
			$start    = '' === $start ? '0' : $start;
			$color    = sanitize_hex_color( $item['color'] );
			$nstyles  = $number_type['styles'];
			if ( $color ) {
				$nstyles['color'] = $color;
			}
			$nstyle   = $this->style_attr( $nstyles );
			$tcolor   = sanitize_hex_color( $item['title_color'] );
			$tstyles  = $title_type['styles'];
			if ( $tcolor ) {
				$tstyles['color'] = $tcolor;
			}
			$icon_styles = array();
			$ic          = sanitize_hex_color( $item['icon_color'] );
			if ( $ic ) {
				$icon_styles['color'] = $ic;
			}
			$isize = absint( $item['icon_size'] );
			if ( $isize ) {
				$icon_styles['font-size'] = $isize . 'px';
			}
			$icon_box_style = $this->style_attr( $icon_styles );

			// Even spacing between icon / number / title; background + radius
			// (and padding when used) style the whole counter card.
			$counter_styles = array( 'gap' => $gap . 'px' );
			$cbg            = sanitize_hex_color( $item['bg'] );
			if ( $cbg ) {
				$counter_styles['background-color'] = $cbg;
			}
			$has_radius = '' !== trim( (string) $item['radius'] );
			if ( $has_radius ) {
				$counter_styles['border-radius'] = absint( $item['radius'] ) . 'px';
			}
			if ( $cbg || $has_radius ) {
				$counter_styles['padding'] = '1.25rem';
			}
			$counter_style = $this->style_attr( $counter_styles );
			?>
			<div class="cafw-counter"<?php echo $counter_style; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>>
				<?php if ( '' !== $item['icon'] ) : ?>
					<div class="cafw-counter__icon"<?php echo $icon_box_style; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>><span class="<?php echo esc_attr( $item['icon'] ); ?>"></span></div>
				<?php endif; ?>
				<div class="cafw-counter__number"<?php echo $nstyle; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>>
					<?php if ( '' !== $item['prefix'] ) : ?>
						<span class="cafw-counter__prefix"><?php echo esc_html( $item['prefix'] ); ?></span>
					<?php endif; ?>
					<span
						class="cafw-counter__value"
						data-target="<?php echo esc_attr( $number ); ?>"
						data-start="<?php echo esc_attr( $start ); ?>"
						data-duration="<?php echo esc_attr( (string) $duration ); ?>"
					><?php echo esc_html( $start ); ?></span>
					<?php if ( '' !== $item['suffix'] ) : ?>
						<span class="cafw-counter__suffix"><?php echo esc_html( $item['suffix'] ); ?></span>
					<?php endif; ?>
				</div>
				<?php if ( '' !== $item['title'] ) : ?>
					<div class="cafw-counter__title"<?php echo $this->style_attr( $tstyles ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>><?php echo esc_html( $item['title'] ); ?></div>
				<?php endif; ?>
			</div>
			<?php
		}

		echo '</div>';
		return ob_get_clean();
	}
}
