<?php
/**
 * Widget Name: Testimonial
 * Description: An animated testimonial carousel with selectable visual styles, a
 *              repeater of reviews ( quote, avatar, name, role, star rating ), slide
 *              or fade animation, autoplay with pause-on-hover, looping, navigation
 *              arrows and dots. Only the selected style CSS file is loaded on the
 *              frontend.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.3.0
 */

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

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Repeater;
use Elementor\Group_Control_Typography;
use Elementor\Group_Control_Box_Shadow;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Background;
use Elementor\Utils;

/**
 * Class Captwiki_Testimonial
 *
 * @since 1.3.0
 */
class Captwiki_Testimonial extends Widget_Base {

	/**
	 * Get widget name.
	 *
	 * @since 1.3.0
	 * @return string
	 */
	public function get_name(): string {
		return 'captwiki-testimonial';
	}

	/**
	 * Get widget title.
	 *
	 * @since 1.3.0
	 * @return string
	 */
	public function get_title(): string {
		return esc_html__( 'Testimonial', 'captain-widgets-kit' );
	}

	/**
	 * Get widget icon.
	 *
	 * @since 1.3.0
	 * @return string
	 */
	public function get_icon(): string {
		return 'eicon-testimonial-carousel captwiki-el-logo';
	}

	/**
	 * Get widget categories.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	public function get_categories(): array {
		return array( 'captwiki-essential' );
	}

	/**
	 * Get widget keywords.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'testimonial', 'review', 'carousel', 'slider', 'quote', 'feedback', 'captain-widgets-kit' );
	}

	/**
	 * Common stylesheet dependency.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	public function get_style_depends(): array {
		return array( 'captwiki_testimonial' );
	}

	/**
	 * Frontend script dependency.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	public function get_script_depends(): array {
		return array( 'captwiki-testimonial' );
	}

	/**
	 * Disable Elementor's default inner wrapper.
	 *
	 * @since 1.3.0
	 * @return bool
	 */
	public function has_widget_inner_wrapper(): bool {
		return ! \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
	}

	/**
	 * Selectable visual styles.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Classic Card', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Centered Quote', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Bubble', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Minimal', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Filled Accent', 'captain-widgets-kit' ),
		);
	}

	/**
	 * Register widget controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	protected function register_controls(): void {
		$this->register_content_controls();
		$this->register_settings_controls();

		$this->register_general_style_controls();
		$this->register_content_style_controls();
		$this->register_person_style_controls();
		$this->register_rating_style_controls();
		$this->register_arrows_style_controls();
		$this->register_dots_style_controls();
	}

	/**
	 * Content tab — testimonials repeater.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_content_controls(): void {

		$this->start_controls_section(
			'section_testimonials',
			array(
				'label' => esc_html__( 'Testimonials', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'widget_style',
			array(
				'label'   => esc_html__( 'Style', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'style-1',
				'options' => $this->captwiki_style_options(),
			)
		);

		$repeater = new Repeater();

		$repeater->add_control(
			'content',
			array(
				'label'       => esc_html__( 'Testimonial', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXTAREA,
				'rows'        => 5,
				'default'     => esc_html__( 'This product completely changed the way our team works. Setup was effortless and the support has been outstanding every step of the way.', 'captain-widgets-kit' ),
				'dynamic'     => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'name',
			array(
				'label'   => esc_html__( 'Name', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::TEXT,
				'default' => esc_html__( 'Jane Cooper', 'captain-widgets-kit' ),
				'dynamic' => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'role',
			array(
				'label'   => esc_html__( 'Role / Company', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::TEXT,
				'default' => esc_html__( 'Marketing Director, Acme', 'captain-widgets-kit' ),
				'dynamic' => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'image',
			array(
				'label'   => esc_html__( 'Avatar', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::MEDIA,
				'default' => array( 'url' => Utils::get_placeholder_image_src() ),
				'dynamic' => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'rating',
			array(
				'label'   => esc_html__( 'Rating', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => '5',
				'options' => array(
					'0' => esc_html__( 'No rating', 'captain-widgets-kit' ),
					'1' => '1',
					'2' => '2',
					'3' => '3',
					'4' => '4',
					'5' => '5',
				),
			)
		);

		$this->add_control(
			'testimonials',
			array(
				'label'       => esc_html__( 'Items', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $repeater->get_controls(),
				'default'     => array(
					array(
						'name' => esc_html__( 'Jane Cooper', 'captain-widgets-kit' ),
						'role' => esc_html__( 'Marketing Director, Acme', 'captain-widgets-kit' ),
					),
					array(
						'content' => esc_html__( 'Honestly the best investment we made this year. Our conversion rate jumped within the first month of using it.', 'captain-widgets-kit' ),
						'name'    => esc_html__( 'Marcus Lee', 'captain-widgets-kit' ),
						'role'    => esc_html__( 'Founder, Brightlabs', 'captain-widgets-kit' ),
					),
					array(
						'content' => esc_html__( 'Clean, fast and incredibly flexible. It fit right into our workflow and the whole team loves it.', 'captain-widgets-kit' ),
						'name'    => esc_html__( 'Priya Nair', 'captain-widgets-kit' ),
						'role'    => esc_html__( 'Product Lead, Northwind', 'captain-widgets-kit' ),
					),
				),
				'title_field' => '{{{ name }}}',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — carousel settings.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_settings_controls(): void {

		$this->start_controls_section(
			'section_settings',
			array(
				'label' => esc_html__( 'Settings', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'animation',
			array(
				'label'   => esc_html__( 'Animation', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'slide',
				'options' => array(
					'slide' => esc_html__( 'Slide', 'captain-widgets-kit' ),
					'fade'  => esc_html__( 'Fade', 'captain-widgets-kit' ),
				),
			)
		);

		$this->add_control(
			'autoplay',
			array(
				'label'        => esc_html__( 'Autoplay', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'autoplay_speed',
			array(
				'label'     => esc_html__( 'Autoplay Speed ( ms )', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::NUMBER,
				'min'       => 1000,
				'max'       => 15000,
				'step'      => 250,
				'default'   => 4000,
				'condition' => array( 'autoplay' => 'yes' ),
			)
		);

		$this->add_control(
			'pause_on_hover',
			array(
				'label'        => esc_html__( 'Pause on Hover', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'No', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
				'condition'    => array( 'autoplay' => 'yes' ),
			)
		);

		$this->add_control(
			'loop',
			array(
				'label'        => esc_html__( 'Infinite Loop', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'No', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'show_arrows',
			array(
				'label'        => esc_html__( 'Show Arrows', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Hide', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'show_dots',
			array(
				'label'        => esc_html__( 'Show Dots', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Hide', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'show_rating',
			array(
				'label'        => esc_html__( 'Show Rating', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Hide', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'show_avatar',
			array(
				'label'        => esc_html__( 'Show Avatar', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Hide', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * General (wrapper) style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_general_style_controls(): void {

		$this->start_controls_section(
			'section_general_style',
			array(
				'label' => esc_html__( 'General', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_responsive_control(
			'max_width',
			array(
				'label'      => esc_html__( 'Max Width', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array(
					'px' => array( 'min' => 280, 'max' => 1000 ),
					'%'  => array( 'min' => 30, 'max' => 100 ),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial' => 'max-width: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'accent_color',
			array(
				'label'       => esc_html__( 'Accent Color', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::COLOR,
				'default'     => '',
				'selectors'   => array(
					'{{WRAPPER}} .captwiki-testimonial' => '--captwiki-ts-accent: {{VALUE}};',
				),
				'description' => esc_html__( 'Drives arrows, dots and style accents.', 'captain-widgets-kit' ),
			)
		);

		$this->add_group_control(
			Group_Control_Background::get_type(),
			array(
				'name'     => 'card_background',
				'label'    => esc_html__( 'Slide Background', 'captain-widgets-kit' ),
				'types'    => array( 'classic', 'gradient' ),
				'selector' => '{{WRAPPER}} .captwiki-testimonial__slide',
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'card_border',
				'label'    => esc_html__( 'Slide Border', 'captain-widgets-kit' ),
				'selector' => '{{WRAPPER}} .captwiki-testimonial__slide',
			)
		);

		$this->add_responsive_control(
			'card_radius',
			array(
				'label'      => esc_html__( 'Slide Radius', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__slide' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Box_Shadow::get_type(),
			array(
				'name'     => 'card_shadow',
				'label'    => esc_html__( 'Slide Shadow', 'captain-widgets-kit' ),
				'selector' => '{{WRAPPER}} .captwiki-testimonial__slide',
			)
		);

		$this->add_responsive_control(
			'card_padding',
			array(
				'label'      => esc_html__( 'Slide Padding', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', 'rem' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__slide' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'wrapper_margin',
			array(
				'label'      => esc_html__( 'Margin', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', 'rem' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Quote content style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_content_style_controls(): void {

		$this->start_controls_section(
			'section_content_style',
			array(
				'label' => esc_html__( 'Content', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'content_color',
			array(
				'label'     => esc_html__( 'Text Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__content' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'content_typography',
				'selector' => '{{WRAPPER}} .captwiki-testimonial__content',
			)
		);

		$this->add_responsive_control(
			'content_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 80 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__content' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Person ( avatar / name / role ) style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_person_style_controls(): void {

		$this->start_controls_section(
			'section_person_style',
			array(
				'label' => esc_html__( 'Person', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_responsive_control(
			'avatar_size',
			array(
				'label'      => esc_html__( 'Avatar Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 32, 'max' => 160 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__avatar' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
				),
				'condition'  => array( 'show_avatar' => 'yes' ),
			)
		);

		$this->add_control(
			'avatar_radius',
			array(
				'label'      => esc_html__( 'Avatar Radius', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 100 ) ),
				'default'    => array( 'unit' => '%', 'size' => 50 ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__avatar' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
				'condition'  => array( 'show_avatar' => 'yes' ),
			)
		);

		$this->add_control(
			'name_heading',
			array(
				'label'     => esc_html__( 'Name', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		$this->add_control(
			'name_color',
			array(
				'label'     => esc_html__( 'Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__name' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'name_typography',
				'selector' => '{{WRAPPER}} .captwiki-testimonial__name',
			)
		);

		$this->add_control(
			'role_heading',
			array(
				'label'     => esc_html__( 'Role', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		$this->add_control(
			'role_color',
			array(
				'label'     => esc_html__( 'Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__role' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'role_typography',
				'selector' => '{{WRAPPER}} .captwiki-testimonial__role',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Rating style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_rating_style_controls(): void {

		$this->start_controls_section(
			'section_rating_style',
			array(
				'label'     => esc_html__( 'Rating', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_rating' => 'yes' ),
			)
		);

		$this->add_control(
			'star_color',
			array(
				'label'     => esc_html__( 'Star Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__star.is-filled' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'star_empty_color',
			array(
				'label'     => esc_html__( 'Empty Star Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__star' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'star_size',
			array(
				'label'      => esc_html__( 'Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array( 'px' => array( 'min' => 10, 'max' => 48 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__rating' => 'font-size: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'rating_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 60 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__rating' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Arrows style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_arrows_style_controls(): void {

		$this->start_controls_section(
			'section_arrows_style',
			array(
				'label'     => esc_html__( 'Arrows', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_arrows' => 'yes' ),
			)
		);

		$this->add_control(
			'arrow_color',
			array(
				'label'     => esc_html__( 'Icon Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__arrow' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'arrow_bg',
			array(
				'label'     => esc_html__( 'Background', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__arrow' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'arrow_color_hover',
			array(
				'label'     => esc_html__( 'Icon Color ( Hover )', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__arrow:hover' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'arrow_bg_hover',
			array(
				'label'     => esc_html__( 'Background ( Hover )', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__arrow:hover' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'arrow_size',
			array(
				'label'      => esc_html__( 'Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 24, 'max' => 80 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__arrow' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Dots style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_dots_style_controls(): void {

		$this->start_controls_section(
			'section_dots_style',
			array(
				'label'     => esc_html__( 'Dots', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_dots' => 'yes' ),
			)
		);

		$this->add_control(
			'dot_color',
			array(
				'label'     => esc_html__( 'Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__dot' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'dot_active_color',
			array(
				'label'     => esc_html__( 'Active Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-testimonial__dot.is-active' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'dot_size',
			array(
				'label'      => esc_html__( 'Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 4, 'max' => 24 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-testimonial__dot' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Render the star rating row.
	 *
	 * @since 1.3.0
	 * @param int $rating Rating value 0–5.
	 * @return void
	 */
	private function captwiki_render_rating( int $rating ): void {
		$rating = max( 0, min( 5, $rating ) );

		if ( 0 === $rating ) {
			return;
		}

		/* translators: %d: rating value out of 5. */
		$label = sprintf( esc_attr__( 'Rated %d out of 5', 'captain-widgets-kit' ), $rating );

		echo '<div class="captwiki-testimonial__rating" role="img" aria-label="' . esc_attr( $label ) . '">';

		for ( $i = 1; $i <= 5; $i++ ) {
			$filled = $i <= $rating ? ' is-filled' : '';
			echo '<span class="captwiki-testimonial__star' . esc_attr( $filled ) . '" aria-hidden="true">&#9733;</span>';
		}

		echo '</div>';
	}

	/**
	 * Render a single testimonial slide.
	 *
	 * @since 1.3.0
	 * @param array $item     Repeater item.
	 * @param array $settings Widget settings.
	 * @param int   $index    Slide index.
	 * @return void
	 */
	private function captwiki_render_slide( array $item, array $settings, int $index ): void {
		$content = isset( $item['content'] ) ? trim( (string) $item['content'] ) : '';
		$name    = isset( $item['name'] ) ? trim( (string) $item['name'] ) : '';
		$role    = isset( $item['role'] ) ? trim( (string) $item['role'] ) : '';
		$img     = ! empty( $item['image']['url'] ) ? $item['image']['url'] : '';
		$rating  = isset( $item['rating'] ) ? (int) $item['rating'] : 0;

		$active = 0 === $index ? ' is-active' : '';

		echo '<div class="captwiki-testimonial__slide' . esc_attr( $active ) . '" role="group" aria-roledescription="slide">';

		if ( 'yes' === $settings['show_rating'] ) {
			$this->captwiki_render_rating( $rating );
		}

		if ( '' !== $content ) {
			echo '<div class="captwiki-testimonial__content">' . wp_kses_post( nl2br( esc_html( $content ) ) ) . '</div>';
		}

		echo '<div class="captwiki-testimonial__person">';

		if ( 'yes' === $settings['show_avatar'] && '' !== $img ) {
			$alt = '' !== $name ? $name : esc_attr__( 'Reviewer', 'captain-widgets-kit' );
			echo '<img class="captwiki-testimonial__avatar" src="' . esc_url( $img ) . '" alt="' . esc_attr( $alt ) . '" loading="lazy" />';
		}

		if ( '' !== $name || '' !== $role ) {
			echo '<div class="captwiki-testimonial__meta">';

			if ( '' !== $name ) {
				echo '<span class="captwiki-testimonial__name">' . esc_html( $name ) . '</span>';
			}

			if ( '' !== $role ) {
				echo '<span class="captwiki-testimonial__role">' . esc_html( $role ) . '</span>';
			}

			echo '</div>';
		}

		echo '</div>';

		echo '</div>';
	}

	/**
	 * Render a navigation arrow button.
	 *
	 * @since 1.3.0
	 * @param string $dir 'prev' or 'next'.
	 * @return void
	 */
	private function captwiki_render_arrow( string $dir ): void {
		$label = 'prev' === $dir ? esc_attr__( 'Previous testimonial', 'captain-widgets-kit' ) : esc_attr__( 'Next testimonial', 'captain-widgets-kit' );
		$path  = 'prev' === $dir ? 'M15 18l-6-6 6-6' : 'M9 6l6 6-6 6';

		echo '<button type="button" class="captwiki-testimonial__arrow captwiki-testimonial__arrow--' . esc_attr( $dir ) . '" aria-label="' . esc_attr( $label ) . '">';
		echo '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="' . esc_attr( $path ) . '"/></svg>';
		echo '</button>';
	}

	/**
	 * Render widget output on the frontend.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	protected function render(): void {
		$settings = $this->get_settings_for_display();

		$items = ! empty( $settings['testimonials'] ) && is_array( $settings['testimonials'] ) ? $settings['testimonials'] : array();

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

		$allowed_styles = array_keys( $this->captwiki_style_options() );
		$style          = in_array( $settings['widget_style'], $allowed_styles, true ) ? $settings['widget_style'] : 'style-1';

		// Load only the active style stylesheet, depending on the common one.
		wp_enqueue_style(
			'captwiki-testimonial-' . $style,
			CAPTWIKI_URL . 'assets/css/widgets/testimonial/captwiki-testimonial-' . $style . '.css',
			array( 'captwiki_testimonial' ),
			CAPTWIKI_VERSION
		);

		$animation   = 'fade' === $settings['animation'] ? 'fade' : 'slide';
		$autoplay    = 'yes' === $settings['autoplay'] ? '1' : '0';
		$speed       = isset( $settings['autoplay_speed'] ) ? max( 1000, absint( $settings['autoplay_speed'] ) ) : 4000;
		$pause       = 'yes' === $settings['pause_on_hover'] ? '1' : '0';
		$loop        = 'yes' === $settings['loop'] ? '1' : '0';
		$show_arrows = 'yes' === $settings['show_arrows'] && count( $items ) > 1;
		$show_dots   = 'yes' === $settings['show_dots'] && count( $items ) > 1;
		$unique      = 'captwiki-widget-' . $this->get_id();

		$data  = ' data-animation="' . esc_attr( $animation ) . '"';
		$data .= ' data-autoplay="' . esc_attr( $autoplay ) . '"';
		$data .= ' data-speed="' . esc_attr( $speed ) . '"';
		$data .= ' data-pause="' . esc_attr( $pause ) . '"';
		$data .= ' data-loop="' . esc_attr( $loop ) . '"';

		echo '<div class="captwiki-testimonial captwiki-' . esc_attr( $style ) . ' captwiki-anim-' . esc_attr( $animation ) . ' ' . esc_attr( $unique ) . '"' . $data . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

			echo '<div class="captwiki-testimonial__viewport">';
				echo '<div class="captwiki-testimonial__track">';

		foreach ( $items as $index => $item ) {
			$this->captwiki_render_slide( $item, $settings, (int) $index );
		}

				echo '</div>';
			echo '</div>';

		if ( $show_arrows ) {
			echo '<div class="captwiki-testimonial__arrows">';
				$this->captwiki_render_arrow( 'prev' );
				$this->captwiki_render_arrow( 'next' );
			echo '</div>';
		}

		if ( $show_dots ) {
			echo '<div class="captwiki-testimonial__dots" role="tablist">';

			foreach ( $items as $index => $item ) {
				$active = 0 === $index ? ' is-active' : '';
				/* translators: %d: slide number. */
				$label = sprintf( esc_attr__( 'Go to testimonial %d', 'captain-widgets-kit' ), (int) $index + 1 );
				echo '<button type="button" class="captwiki-testimonial__dot' . esc_attr( $active ) . '" data-index="' . esc_attr( $index ) . '" aria-label="' . esc_attr( $label ) . '"></button>';
			}

			echo '</div>';
		}

		echo '</div>';
	}
}
