<?php
/**
 * Widget Name: Before After
 * Description: An image comparison slider — two images stacked with a
 *              draggable divider that reveals the "before" shot over the
 *              "after" shot. Supports horizontal and vertical dragging, a
 *              configurable start position, labels, fixed aspect ratios and
 *              full keyboard control ( the divider is a real ARIA slider ).
 *              Ships with selectable visual styles. Only the selected style
 *              CSS file is loaded on the frontend.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.7.0
 */

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

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
use Elementor\Group_Control_Box_Shadow;
use Elementor\Control_Media;
use Elementor\Utils;

/**
 * Class Captwiki_Before_After
 *
 * @since 1.7.0
 */
class Captwiki_Before_After extends Widget_Base {

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

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

	/**
	 * Get widget icon.
	 *
	 * @since 1.7.0
	 * @return string
	 */
	public function get_icon(): string {
		return 'eicon-image-before-after captwiki-el-logo';
	}

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

	/**
	 * Get widget keywords.
	 *
	 * @since 1.7.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'before', 'after', 'compare', 'comparison', 'image', 'slider', 'captain-widgets-kit' );
	}

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

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

	/**
	 * Disable Elementor's default inner wrapper.
	 *
	 * @since 1.7.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.7.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Classic Round', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Minimal Line', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Accent Grip', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Pill Labels', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Dark Elegant', 'captain-widgets-kit' ),
		);
	}

	/**
	 * Allowed aspect ratio options.
	 *
	 * @since 1.7.0
	 * @return array
	 */
	private function captwiki_ratio_options(): array {
		return array(
			'auto' => esc_html__( 'Original Image', 'captain-widgets-kit' ),
			'1-1'  => '1:1',
			'4-3'  => '4:3',
			'3-2'  => '3:2',
			'16-9' => '16:9',
			'9-16' => '9:16',
		);
	}

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

		$this->register_layout_style_controls();
		$this->register_label_style_controls();
		$this->register_handle_style_controls();
	}

	/**
	 * Content tab — images & labels.
	 *
	 * @since 1.7.0
	 * @return void
	 */
	private function register_images_controls(): void {

		$this->start_controls_section(
			'section_images',
			array(
				'label' => esc_html__( 'Images', '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(),
			)
		);

		$this->add_control(
			'before_image',
			array(
				'label'   => esc_html__( 'Before Image', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::MEDIA,
				'default' => array( 'url' => Utils::get_placeholder_image_src() ),
				'dynamic' => array( 'active' => true ),
			)
		);

		$this->add_control(
			'after_image',
			array(
				'label'   => esc_html__( 'After Image', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::MEDIA,
				'default' => array( 'url' => Utils::get_placeholder_image_src() ),
				'dynamic' => array( 'active' => true ),
			)
		);

		$this->add_control(
			'show_labels',
			array(
				'label'        => esc_html__( 'Show Labels', '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(
			'before_label',
			array(
				'label'     => esc_html__( 'Before Label', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => esc_html__( 'Before', 'captain-widgets-kit' ),
				'dynamic'   => array( 'active' => true ),
				'condition' => array( 'show_labels' => 'yes' ),
			)
		);

		$this->add_control(
			'after_label',
			array(
				'label'     => esc_html__( 'After Label', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => esc_html__( 'After', 'captain-widgets-kit' ),
				'dynamic'   => array( 'active' => true ),
				'condition' => array( 'show_labels' => 'yes' ),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — behaviour settings.
	 *
	 * @since 1.7.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(
			'orientation',
			array(
				'label'   => esc_html__( 'Orientation', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'horizontal',
				'options' => array(
					'horizontal' => esc_html__( 'Horizontal ( drag left / right )', 'captain-widgets-kit' ),
					'vertical'   => esc_html__( 'Vertical ( drag up / down )', 'captain-widgets-kit' ),
				),
			)
		);

		$this->add_control(
			'initial_position',
			array(
				'label'   => esc_html__( 'Start Position (%)', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SLIDER,
				'range'   => array(
					'px' => array(
						'min' => 0,
						'max' => 100,
					),
				),
				'default' => array( 'size' => 50 ),
			)
		);

		$this->add_control(
			'move_on_hover',
			array(
				'label'        => esc_html__( 'Follow Mouse 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'      => '',
				'description'  => esc_html__( 'The divider follows the cursor without dragging. Drag and keyboard still work.', 'captain-widgets-kit' ),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — layout ( width, alignment, ratio ).
	 *
	 * @since 1.7.0
	 * @return void
	 */
	private function register_layout_style_controls(): void {

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

		$this->add_responsive_control(
			'box_width',
			array(
				'label'      => esc_html__( 'Width', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array(
					'px' => array(
						'min' => 120,
						'max' => 1400,
					),
					'%'  => array(
						'min' => 10,
						'max' => 100,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-ba' => 'max-width: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'box_align',
			array(
				'label'                => esc_html__( 'Alignment', 'captain-widgets-kit' ),
				'type'                 => Controls_Manager::CHOOSE,
				'default'              => 'center',
				'options'              => array(
					'left'   => array(
						'title' => esc_html__( 'Left', 'captain-widgets-kit' ),
						'icon'  => 'eicon-text-align-left',
					),
					'center' => array(
						'title' => esc_html__( 'Center', 'captain-widgets-kit' ),
						'icon'  => 'eicon-text-align-center',
					),
					'right'  => array(
						'title' => esc_html__( 'Right', 'captain-widgets-kit' ),
						'icon'  => 'eicon-text-align-right',
					),
				),
				'selectors_dictionary' => array(
					'left'   => 'margin-left: 0; margin-right: auto;',
					'center' => 'margin-left: auto; margin-right: auto;',
					'right'  => 'margin-left: auto; margin-right: 0;',
				),
				'selectors'            => array(
					'{{WRAPPER}} .captwiki-ba' => '{{VALUE}}',
				),
			)
		);

		$this->add_control(
			'aspect_ratio',
			array(
				'label'                => esc_html__( 'Aspect Ratio', 'captain-widgets-kit' ),
				'type'                 => Controls_Manager::SELECT,
				'default'              => 'auto',
				'options'              => $this->captwiki_ratio_options(),
				'selectors_dictionary' => array(
					'auto' => '',
					'1-1'  => '--captwiki-ba-ratio: 1 / 1;',
					'4-3'  => '--captwiki-ba-ratio: 4 / 3;',
					'3-2'  => '--captwiki-ba-ratio: 3 / 2;',
					'16-9' => '--captwiki-ba-ratio: 16 / 9;',
					'9-16' => '--captwiki-ba-ratio: 9 / 16;',
				),
				'selectors'            => array(
					'{{WRAPPER}} .captwiki-ba' => '{{VALUE}}',
				),
			)
		);

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

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

		$this->end_controls_section();
	}

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

		$this->start_controls_section(
			'section_label_style',
			array(
				'label'     => esc_html__( 'Labels', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_labels' => 'yes' ),
			)
		);

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

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

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

		$this->end_controls_section();
	}

	/**
	 * Style tab — divider & handle.
	 *
	 * @since 1.7.0
	 * @return void
	 */
	private function register_handle_style_controls(): void {

		$this->start_controls_section(
			'section_handle_style',
			array(
				'label' => esc_html__( 'Divider & Handle', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

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

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

		$this->add_control(
			'handle_bg_color',
			array(
				'label'     => esc_html__( 'Handle Background', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-ba' => '--captwiki-ba-handle-bg: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'handle_size',
			array(
				'label'      => esc_html__( 'Handle Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 28,
						'max' => 80,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-ba' => '--captwiki-ba-handle: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Resolve the alt text for an image control value.
	 *
	 * @since 1.7.0
	 * @param array  $image    Image control value.
	 * @param string $fallback Fallback alt text.
	 * @return string
	 */
	private function captwiki_image_alt( array $image, string $fallback ): string {

		$alt = ! empty( $image['id'] ) ? Control_Media::get_image_alt( $image ) : '';

		return '' !== $alt ? $alt : $fallback;
	}

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

		$before_url = ! empty( $settings['before_image']['url'] ) ? $settings['before_image']['url'] : '';
		$after_url  = ! empty( $settings['after_image']['url'] ) ? $settings['after_image']['url'] : '';

		if ( '' === $before_url || '' === $after_url ) {
			return;
		}

		$allowed_styles = array_keys( $this->captwiki_style_options() );
		$style          = in_array( $settings['widget_style'], $allowed_styles, true ) ? $settings['widget_style'] : 'style-1';
		$orientation    = 'vertical' === $settings['orientation'] ? 'vertical' : 'horizontal';
		$initial        = isset( $settings['initial_position']['size'] ) ? (int) $settings['initial_position']['size'] : 50;
		$initial        = max( 0, min( 100, $initial ) );
		$fixed_ratio    = ! empty( $settings['aspect_ratio'] ) && 'auto' !== $settings['aspect_ratio'];
		$show_labels    = 'yes' === $settings['show_labels'];
		$hover_move     = 'yes' === $settings['move_on_hover'] ? 'yes' : 'no';
		$before_label   = trim( (string) $settings['before_label'] );
		$after_label    = trim( (string) $settings['after_label'] );
		$before_alt     = $this->captwiki_image_alt( (array) $settings['before_image'], esc_html__( 'Before', 'captain-widgets-kit' ) );
		$after_alt      = $this->captwiki_image_alt( (array) $settings['after_image'], esc_html__( 'After', 'captain-widgets-kit' ) );

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

		$classes = 'captwiki-ba captwiki-' . $style . ' captwiki-ba--' . $orientation;

		if ( $fixed_ratio ) {
			$classes .= ' captwiki-ba--fixed-ratio';
		}

		printf(
			'<div class="%1$s" data-initial="%2$d" data-hover-move="%3$s">',
			esc_attr( $classes ),
			esc_attr( $initial ),
			esc_attr( $hover_move )
		);

		printf( '<div class="captwiki-ba__frame" style="--captwiki-ba-pos: %d%%;">', esc_attr( $initial ) );

		printf(
			'<img class="captwiki-ba__after-img" src="%1$s" alt="%2$s" loading="lazy" />',
			esc_url( $after_url ),
			esc_attr( $after_alt )
		);

		echo '<div class="captwiki-ba__before" aria-hidden="true">';
		printf(
			'<img class="captwiki-ba__before-img" src="%1$s" alt="" loading="lazy" />',
			esc_url( $before_url )
		);
		echo '</div>';

		if ( $show_labels && '' !== $before_label ) {
			echo '<span class="captwiki-ba__label captwiki-ba__label--before">' . esc_html( $before_label ) . '</span>';
		}

		if ( $show_labels && '' !== $after_label ) {
			echo '<span class="captwiki-ba__label captwiki-ba__label--after">' . esc_html( $after_label ) . '</span>';
		}

		printf(
			'<div class="captwiki-ba__divider" role="slider" tabindex="0" aria-label="%1$s" aria-orientation="%2$s" aria-valuemin="0" aria-valuemax="100" aria-valuenow="%3$d">',
			esc_attr__( 'Comparison slider', 'captain-widgets-kit' ),
			esc_attr( $orientation ),
			esc_attr( $initial )
		);
		echo '<span class="captwiki-ba__handle" aria-hidden="true">'
			. '<svg class="captwiki-ba__arrows" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 3 12 9 18"></polyline><polyline points="15 6 21 12 15 18"></polyline></svg>'
			. '</span>';
		echo '</div>';

		echo '</div>'; // frame.
		echo '</div>'; // ba.
	}
}
