<?php
/**
 * Widget Name: Scroll Navigation Dots
 * Description: A fixed one-page scroll-spy navigation. Add a dot per page section
 *              ( target by CSS selector / id ); the active dot highlights as you
 *              scroll and clicking a dot smooth-scrolls to that section. Supports
 *              left / right / top / bottom placement, hover or always-on labels,
 *              a scroll offset for sticky headers and five distinct visual styles.
 *              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;

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

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

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

	/**
	 * Get widget icon.
	 *
	 * @since 1.6.0
	 * @return string
	 */
	public function get_icon(): string {
		return 'eicon-navigation-horizontal 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( 'scroll', 'navigation', 'dots', 'one page', 'scrollspy', 'anchor', 'sections', 'captain-widgets-kit' );
	}

	/**
	 * Frontend script dependency.
	 *
	 * @since 1.6.0
	 * @return array
	 */
	public function get_script_depends(): array {
		return array( 'captwiki-scroll-navigation-dots' );
	}

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

	/**
	 * 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 – Minimal Dots', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Line Ticks', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Outline Fill', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Numbered Pills', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Glow Track', 'captain-widgets-kit' ),
		);
	}

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

		$this->register_dots_style_controls();
		$this->register_label_style_controls();
	}

	/**
	 * Content tab — dots / sections.
	 *
	 * @since 1.6.0
	 * @return void
	 */
	private function register_dots_controls(): void {

		$this->start_controls_section(
			'section_dots',
			array(
				'label' => esc_html__( 'Dots', '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(
			'dot_label',
			array(
				'label'       => esc_html__( 'Label', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Section', 'captain-widgets-kit' ),
				'label_block' => true,
				'dynamic'     => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'dot_target',
			array(
				'label'       => esc_html__( 'Target Selector', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => '',
				'placeholder' => '#section-id',
				'description' => esc_html__( 'CSS id or selector of the section, e.g. #about or .hero.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'dots',
			array(
				'label'       => esc_html__( 'Sections', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $repeater->get_controls(),
				'default'     => array(
					array(
						'dot_label'  => esc_html__( 'Home', 'captain-widgets-kit' ),
						'dot_target' => '#section-1',
					),
					array(
						'dot_label'  => esc_html__( 'About', 'captain-widgets-kit' ),
						'dot_target' => '#section-2',
					),
					array(
						'dot_label'  => esc_html__( 'Services', 'captain-widgets-kit' ),
						'dot_target' => '#section-3',
					),
					array(
						'dot_label'  => esc_html__( 'Contact', 'captain-widgets-kit' ),
						'dot_target' => '#section-4',
					),
				),
				'title_field' => '{{{ dot_label }}}',
			)
		);

		$this->add_control(
			'dots_help',
			array(
				'type'            => Controls_Manager::RAW_HTML,
				'raw'             => esc_html__( 'Tip: give each Elementor section a CSS ID under Advanced → CSS ID, then reference it here as #your-id.', 'captain-widgets-kit' ),
				'content_classes' => 'elementor-descriptor',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — behaviour & placement.
	 *
	 * @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(
			'position',
			array(
				'label'   => esc_html__( 'Position', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'right',
				'options' => array(
					'right'  => esc_html__( 'Right ( vertical )', 'captain-widgets-kit' ),
					'left'   => esc_html__( 'Left ( vertical )', 'captain-widgets-kit' ),
					'top'    => esc_html__( 'Top ( horizontal )', 'captain-widgets-kit' ),
					'bottom' => esc_html__( 'Bottom ( horizontal )', 'captain-widgets-kit' ),
				),
			)
		);

		$this->add_control(
			'show_label',
			array(
				'label'   => esc_html__( 'Labels', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'hover',
				'options' => array(
					'hover'  => esc_html__( 'Show on Hover', 'captain-widgets-kit' ),
					'always' => esc_html__( 'Always Show', 'captain-widgets-kit' ),
					'none'   => esc_html__( 'Hide', 'captain-widgets-kit' ),
				),
			)
		);

		$this->add_control(
			'smooth_scroll',
			array(
				'label'        => esc_html__( 'Smooth Scroll', '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(
			'scroll_offset',
			array(
				'label'       => esc_html__( 'Scroll Offset', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::SLIDER,
				'size_units'  => array( 'px' ),
				'range'       => array(
					'px' => array(
						'min' => 0,
						'max' => 300,
					),
				),
				'default'     => array(
					'unit' => 'px',
					'size' => 0,
				),
				'description' => esc_html__( 'Pixels to subtract when scrolling — match your sticky header height.', 'captain-widgets-kit' ),
			)
		);

		$this->add_responsive_control(
			'edge_offset',
			array(
				'label'      => esc_html__( 'Distance From Edge', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'vh', 'vw' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 160,
					),
				),
				'default'    => array(
					'unit' => 'px',
					'size' => 28,
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-scrolldots' => '--captwiki-sd-offset: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'dot_gap',
			array(
				'label'      => esc_html__( 'Gap Between Dots', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 4,
						'max' => 48,
					),
				),
				'default'    => array(
					'unit' => 'px',
					'size' => 16,
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-scrolldots__list' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'hide_on_mobile',
			array(
				'label'        => esc_html__( 'Hide on Mobile', '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'      => '',
				'separator'    => 'before',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — dots.
	 *
	 * @since 1.6.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,
			)
		);

		$this->add_control(
			'dot_color',
			array(
				'label'     => esc_html__( 'Inactive Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-scrolldots' => '--captwiki-sd-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-scrolldots' => '--captwiki-sd-accent: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'dot_size',
			array(
				'label'      => esc_html__( 'Dot Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 6,
						'max' => 40,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-scrolldots' => '--captwiki-sd-size: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'num_color',
			array(
				'label'     => esc_html__( 'Number Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-scrolldots__num' => 'color: {{VALUE}};',
				),
				'separator' => 'before',
				'description' => esc_html__( 'Used by the Numbered Pills style.', 'captain-widgets-kit' ),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — labels.
	 *
	 * @since 1.6.0
	 * @return void
	 */
	private function register_label_style_controls(): void {

		$this->start_controls_section(
			'section_label_style',
			array(
				'label'     => esc_html__( 'Label', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_label!' => 'none' ),
			)
		);

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

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

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

		$this->add_responsive_control(
			'label_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 40,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-scrolldots__label' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * 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['dots'] ) || ! is_array( $settings['dots'] ) ) {
			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-scroll-navigation-dots-' . $style,
			CAPTWIKI_URL . 'assets/css/widgets/scroll-navigation-dots/captwiki-scroll-navigation-dots-' . $style . '.css',
			array( 'captwiki_scroll_navigation_dots' ),
			CAPTWIKI_VERSION
		);

		$allowed_pos = array( 'right', 'left', 'top', 'bottom' );
		$position    = in_array( $settings['position'], $allowed_pos, true ) ? $settings['position'] : 'right';
		$orientation = in_array( $position, array( 'top', 'bottom' ), true ) ? 'horizontal' : 'vertical';

		$allowed_label = array( 'hover', 'always', 'none' );
		$show_label    = in_array( $settings['show_label'], $allowed_label, true ) ? $settings['show_label'] : 'hover';

		$smooth = 'yes' === $settings['smooth_scroll'] ? 'yes' : 'no';
		$offset = isset( $settings['scroll_offset']['size'] ) ? absint( $settings['scroll_offset']['size'] ) : 0;
		$mobile = 'yes' === $settings['hide_on_mobile'] ? ' captwiki-scrolldots--hide-mobile' : '';

		$classes = sprintf(
			'captwiki-scrolldots captwiki-%1$s captwiki-scrolldots--%2$s captwiki-scrolldots--%3$s captwiki-scrolldots--label-%4$s%5$s',
			esc_attr( $style ),
			esc_attr( $position ),
			esc_attr( $orientation ),
			esc_attr( $show_label ),
			esc_attr( $mobile )
		);

		printf(
			'<div class="%1$s" data-smooth="%2$s" data-offset="%3$d" role="navigation" aria-label="%4$s">',
			esc_attr( $classes ),
			esc_attr( $smooth ),
			esc_attr( $offset ),
			esc_attr__( 'Page sections', 'captain-widgets-kit' )
		);

		echo '<ul class="captwiki-scrolldots__list">';

		$index = 0;

		foreach ( $settings['dots'] as $dot ) {
			++$index;

			$label  = isset( $dot['dot_label'] ) ? trim( (string) $dot['dot_label'] ) : '';
			$target = isset( $dot['dot_target'] ) ? trim( (string) $dot['dot_target'] ) : '';

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

			$num     = str_pad( (string) $index, 2, '0', STR_PAD_LEFT );
			$aria     = '' !== $label ? $label : sprintf( /* translators: %d: section number. */ esc_html__( 'Section %d', 'captain-widgets-kit' ), $index );
			$href     = '' !== $target && '#' === substr( $target, 0, 1 ) ? $target : '#';

			echo '<li class="captwiki-scrolldots__item">';
			printf(
				'<a class="captwiki-scrolldots__dot" href="%1$s" data-target="%2$s" aria-label="%3$s">',
				esc_attr( $href ),
				esc_attr( $target ),
				esc_attr( $aria )
			);

			echo '<span class="captwiki-scrolldots__marker" aria-hidden="true"></span>';
			echo '<span class="captwiki-scrolldots__num" aria-hidden="true">' . esc_html( $num ) . '</span>';

			if ( '' !== $label && 'none' !== $show_label ) {
				echo '<span class="captwiki-scrolldots__label">' . esc_html( $label ) . '</span>';
			}

			echo '</a>';
			echo '</li>';
		}

		echo '</ul>';
		echo '</div>';
	}
}
