<?php
/**
 * Widget Name: Animated Marquee
 * Description: A seamless, infinitely scrolling marquee / ticker with selectable
 *              visual styles. Add any number of text items ( each with an optional
 *              icon and link ), choose direction, speed, gap, pause-on-hover and
 *              soft edge-fade. The loop is pure CSS ( duplicated track ) so it is
 *              smooth and dependency-free. Only the selected style CSS file is
 *              loaded on the frontend.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.6.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_Border;
use Elementor\Group_Control_Background;
use Elementor\Icons_Manager;

/**
 * Class Captwiki_Animated_Marquee
 *
 * @since 1.6.0
 */
class Captwiki_Animated_Marquee extends Widget_Base {

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

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

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

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

	/**
	 * Get widget keywords.
	 *
	 * @since 1.6.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'marquee', 'ticker', 'scroll', 'slider', 'news', 'announcement', 'loop', 'captain-widgets-kit' );
	}

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

	/**
	 * Disable Elementor's default inner wrapper.
	 *
	 * @since 1.6.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.6.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Clean Ticker', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Pill Tags', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Bold Display', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Outline Stroke', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Chip Cards', 'captain-widgets-kit' ),
		);
	}

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

		$this->register_general_style_controls();
		$this->register_items_style_controls();
		$this->register_separator_style_controls();
	}

	/**
	 * Content tab — marquee items controls.
	 *
	 * @since 1.6.0
	 * @return void
	 */
	private function register_items_controls(): void {

		$this->start_controls_section(
			'section_items',
			array(
				'label' => esc_html__( 'Items', '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(
			'item_text',
			array(
				'label'       => esc_html__( 'Text', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Marquee item', 'captain-widgets-kit' ),
				'label_block' => true,
				'dynamic'     => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'item_icon',
			array(
				'label'       => esc_html__( 'Icon', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::ICONS,
				'skin'        => 'inline',
				'label_block' => false,
			)
		);

		$repeater->add_control(
			'item_link',
			array(
				'label'         => esc_html__( 'Link', 'captain-widgets-kit' ),
				'type'          => Controls_Manager::URL,
				'placeholder'   => esc_html__( 'https://your-link.com', 'captain-widgets-kit' ),
				'show_external' => true,
				'default'       => array( 'url' => '' ),
				'dynamic'       => array( 'active' => true ),
			)
		);

		$this->add_control(
			'items',
			array(
				'label'       => esc_html__( 'Marquee Items', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $repeater->get_controls(),
				'default'     => array(
					array( 'item_text' => esc_html__( 'Fast Delivery', 'captain-widgets-kit' ) ),
					array( 'item_text' => esc_html__( '24/7 Support', 'captain-widgets-kit' ) ),
					array( 'item_text' => esc_html__( 'Secure Payment', 'captain-widgets-kit' ) ),
					array( 'item_text' => esc_html__( 'Free Returns', 'captain-widgets-kit' ) ),
					array( 'item_text' => esc_html__( 'Best Quality', 'captain-widgets-kit' ) ),
				),
				'title_field' => '{{{ item_text }}}',
			)
		);

		$this->add_control(
			'show_separator',
			array(
				'label'        => esc_html__( 'Show Separator', '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',
				'separator'    => 'before',
			)
		);

		$this->add_control(
			'separator_icon',
			array(
				'label'       => esc_html__( 'Separator Icon', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::ICONS,
				'default'     => array(
					'value'   => 'fas fa-circle',
					'library' => 'fa-solid',
				),
				'skin'        => 'inline',
				'label_block' => false,
				'condition'   => array( 'show_separator' => 'yes' ),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — marquee behaviour controls.
	 *
	 * @since 1.6.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(
			'direction',
			array(
				'label'   => esc_html__( 'Direction', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::CHOOSE,
				'default' => 'left',
				'options' => array(
					'left'  => array(
						'title' => esc_html__( 'Left', 'captain-widgets-kit' ),
						'icon'  => 'eicon-arrow-left',
					),
					'right' => array(
						'title' => esc_html__( 'Right', 'captain-widgets-kit' ),
						'icon'  => 'eicon-arrow-right',
					),
				),
				'toggle'  => false,
			)
		);

		$this->add_control(
			'speed',
			array(
				'label'      => esc_html__( 'Speed ( seconds per loop )', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 's' ),
				'range'      => array(
					's' => array(
						'min'  => 5,
						'max'  => 120,
						'step' => 1,
					),
				),
				'default'    => array(
					'unit' => 's',
					'size' => 25,
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-marquee' => '--captwiki-mq-duration: {{SIZE}}s;',
				),
				'description' => esc_html__( 'Lower value scrolls faster.', 'captain-widgets-kit' ),
			)
		);

		$this->add_responsive_control(
			'item_gap',
			array(
				'label'      => esc_html__( 'Gap Between Items', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 160,
					),
				),
				'default'    => array(
					'unit' => 'px',
					'size' => 44,
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-marquee' => '--captwiki-mq-gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$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',
			)
		);

		$this->add_control(
			'edge_fade',
			array(
				'label'        => esc_html__( 'Edge Fade', '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',
				'description'  => esc_html__( 'Softly fade the marquee into the background at both edges.', 'captain-widgets-kit' ),
			)
		);

		$this->end_controls_section();
	}

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

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

		$this->add_control(
			'accent_color',
			array(
				'label'       => esc_html__( 'Accent Color', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::COLOR,
				'default'     => '',
				'selectors'   => array(
					'{{WRAPPER}} .captwiki-marquee' => '--captwiki-mq-accent: {{VALUE}};',
				),
				'description' => esc_html__( 'Drives separators, pills and style highlights.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'accent_color_2',
			array(
				'label'     => esc_html__( 'Secondary Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-marquee' => '--captwiki-mq-accent-2: {{VALUE}};',
				),
			)
		);

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

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

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

		$this->add_responsive_control(
			'box_padding',
			array(
				'label'      => esc_html__( 'Vertical Padding', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 120,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-marquee' => 'padding-top: {{SIZE}}{{UNIT}}; padding-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Item style controls.
	 *
	 * @since 1.6.0
	 * @return void
	 */
	private function register_items_style_controls(): void {

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

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

		$this->start_controls_tabs( 'item_color_tabs' );

		$this->start_controls_tab(
			'item_normal_tab',
			array( 'label' => esc_html__( 'Normal', 'captain-widgets-kit' ) )
		);

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

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

		$this->end_controls_tab();

		$this->start_controls_tab(
			'item_hover_tab',
			array( 'label' => esc_html__( 'Hover', 'captain-widgets-kit' ) )
		);

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

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

		$this->end_controls_tab();
		$this->end_controls_tabs();

		$this->add_responsive_control(
			'item_icon_size',
			array(
				'label'      => esc_html__( 'Icon Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array(
					'px' => array(
						'min' => 8,
						'max' => 80,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-marquee__item-icon' => 'font-size: {{SIZE}}{{UNIT}};',
				),
				'separator'  => 'before',
			)
		);

		$this->add_responsive_control(
			'item_padding',
			array(
				'label'      => esc_html__( 'Padding', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-marquee__item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
				'description' => esc_html__( 'Best paired with the Pill Tags or Chip Cards styles.', 'captain-widgets-kit' ),
			)
		);

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

		$this->end_controls_section();
	}

	/**
	 * Separator style controls.
	 *
	 * @since 1.6.0
	 * @return void
	 */
	private function register_separator_style_controls(): void {

		$this->start_controls_section(
			'section_separator_style',
			array(
				'label'     => esc_html__( 'Separator', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_separator' => 'yes' ),
			)
		);

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

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

		$this->end_controls_section();
	}

	/**
	 * Render a single marquee item ( icon + text, optionally linked ).
	 *
	 * @since 1.6.0
	 * @param array $item Repeater item settings.
	 * @return string
	 */
	private function captwiki_get_item_html( array $item ): string {
		$text = isset( $item['item_text'] ) ? trim( (string) $item['item_text'] ) : '';

		if ( '' === $text ) {
			return '';
		}

		$inner = '';

		if ( ! empty( $item['item_icon']['value'] ) ) {
			$inner .= '<span class="captwiki-marquee__item-icon" aria-hidden="true">';
			$inner .= $this->captwiki_get_icon_html( $item['item_icon'] );
			$inner .= '</span>';
		}

		$inner .= '<span class="captwiki-marquee__text">' . esc_html( $text ) . '</span>';

		$url = ! empty( $item['item_link']['url'] ) ? $item['item_link']['url'] : '';

		if ( '' !== $url ) {
			$target = ! empty( $item['item_link']['is_external'] ) ? ' target="_blank"' : '';
			$rel    = ! empty( $item['item_link']['nofollow'] ) ? ' rel="nofollow"' : '';

			return '<a class="captwiki-marquee__item" href="' . esc_url( $url ) . '"' . $target . $rel . '>' . $inner . '</a>';
		}

		return '<span class="captwiki-marquee__item">' . $inner . '</span>';
	}

	/**
	 * Capture an Elementor icon as an HTML string.
	 *
	 * @since 1.6.0
	 * @param array $icon Icon control value.
	 * @return string
	 */
	private function captwiki_get_icon_html( array $icon ): string {
		ob_start();
		Icons_Manager::render_icon( $icon, array( 'aria-hidden' => 'true' ) );
		return (string) ob_get_clean();
	}

	/**
	 * Build the inner HTML for one marquee group ( items + separators ).
	 *
	 * @since 1.6.0
	 * @param array  $items          Repeater items.
	 * @param bool   $show_separator Whether to print separators.
	 * @param string $separator_html Pre-rendered separator markup.
	 * @return string
	 */
	private function captwiki_get_group_html( array $items, bool $show_separator, string $separator_html ): string {
		$html = '';

		foreach ( $items as $item ) {
			$item_html = $this->captwiki_get_item_html( (array) $item );

			if ( '' === $item_html ) {
				continue;
			}

			$html .= $item_html;

			if ( $show_separator && '' !== $separator_html ) {
				$html .= $separator_html;
			}
		}

		return $html;
	}

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

		if ( empty( $settings['items'] ) || ! is_array( $settings['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-animated-marquee-' . $style,
			CAPTWIKI_URL . 'assets/css/widgets/animated-marquee/captwiki-animated-marquee-' . $style . '.css',
			array( 'captwiki_animated_marquee' ),
			CAPTWIKI_VERSION
		);

		$direction      = 'right' === $settings['direction'] ? 'right' : 'left';
		$show_separator = 'yes' === $settings['show_separator'];
		$pause          = 'yes' === $settings['pause_on_hover'] ? ' is-pause' : '';
		$fade           = 'yes' === $settings['edge_fade'] ? ' is-fade' : '';

		$separator_html = '';

		if ( $show_separator && ! empty( $settings['separator_icon']['value'] ) ) {
			$separator_html = '<span class="captwiki-marquee__sep" aria-hidden="true">' . $this->captwiki_get_icon_html( $settings['separator_icon'] ) . '</span>';
		}

		$group_html = $this->captwiki_get_group_html( $settings['items'], $show_separator, $separator_html );

		if ( '' === $group_html ) {
			return;
		}

		$classes = sprintf(
			'captwiki-marquee captwiki-%1$s captwiki-marquee--%2$s%3$s%4$s',
			esc_attr( $style ),
			esc_attr( $direction ),
			esc_attr( $pause ),
			esc_attr( $fade )
		);

		echo '<div class="' . esc_attr( $classes ) . '">'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo '<div class="captwiki-marquee__track">';

		// First group is read by assistive tech; the duplicate is hidden — together
		// they make the CSS -50% translate loop perfectly seamless.
		echo '<div class="captwiki-marquee__group">' . $group_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo '<div class="captwiki-marquee__group" aria-hidden="true">' . $group_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

		echo '</div>'; // track.
		echo '</div>'; // marquee.
	}
}
