<?php
defined( 'ABSPATH' ) || exit;

use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
use Elementor\Repeater;
use Elementor\Widget_Base;

/**
 * Elementor AWP Slider widget.
 */
class AWP_Slider_Widget extends Widget_Base {

	/**
	 * @return string
	 */
	public function get_name() {
		return 'awp_slider';
	}

	/**
	 * @return string
	 */
	public function get_title() {
		return __( 'AWP Slider', 'advance-wp-slider' );
	}

	/**
	 * @return string
	 */
	public function get_icon() {
		return 'eicon-slider-push';
	}

	/**
	 * @return array
	 */
	public function get_categories() {
		return array( 'awp-slider', 'general' );
	}

	/**
	 * @return array
	 */
	public function get_keywords() {
		return array( 'slider', 'carousel', 'swiper', 'awp', 'gallery' );
	}

	/**
	 * @return array
	 */
	public function get_script_depends() {
		return array( 'swiper', 'awp-slider' );
	}

	/**
	 * @return array
	 */
	public function get_style_depends() {
		return array( 'swiper', 'awp-slider' );
	}

	/**
	 * Register controls.
	 */
	protected function register_controls() {
		$defaults = AWP_Settings::defaults();

		$this->start_controls_section(
			'section_content',
			array(
				'label' => __( 'Content', 'advance-wp-slider' ),
			)
		);

		$this->add_control(
			'source',
			array(
				'label'   => __( 'Slide source', 'advance-wp-slider' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'custom',
				'options' => array(
					'custom' => __( 'Custom slides', 'advance-wp-slider' ),
					'cpt'    => __( 'AWP Sliders (CPT)', 'advance-wp-slider' ),
				),
			)
		);

		$repeater = new Repeater();

		$repeater->add_control(
			'image',
			array(
				'label'   => __( 'Image', 'advance-wp-slider' ),
				'type'    => Controls_Manager::MEDIA,
				'default' => array(
					'url' => '',
				),
			)
		);

		$repeater->add_control(
			'subtitle',
			array(
				'label'       => __( 'Subtitle', 'advance-wp-slider' ),
				'type'        => Controls_Manager::TEXT,
				'label_block' => true,
			)
		);

		$repeater->add_control(
			'title',
			array(
				'label'       => __( 'Title', 'advance-wp-slider' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => __( 'Slide title', 'advance-wp-slider' ),
				'label_block' => true,
			)
		);

		$repeater->add_control(
			'content',
			array(
				'label'      => __( 'Description', 'advance-wp-slider' ),
				'type'       => Controls_Manager::TEXTAREA,
				'default'    => __( 'Add supporting text for this slide.', 'advance-wp-slider' ),
				'rows'       => 3,
			)
		);

		$repeater->add_control(
			'button_text',
			array(
				'label'   => __( 'Button text', 'advance-wp-slider' ),
				'type'    => Controls_Manager::TEXT,
				'default' => __( 'Learn more', 'advance-wp-slider' ),
			)
		);

		$repeater->add_control(
			'button_link',
			array(
				'label'       => __( 'Button link', 'advance-wp-slider' ),
				'type'        => Controls_Manager::URL,
				'placeholder' => 'https://',
				'default'     => array(
					'url' => '#',
				),
			)
		);

		$this->add_control(
			'slides',
			array(
				'label'       => __( 'Slides', 'advance-wp-slider' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $repeater->get_controls(),
				'default'     => array(
					array(
						'image'       => array(
							'url' => AWP_SLIDER_PLUGIN_URL . 'assets/img/hero-1.jpg',
						),
						'title'       => __( 'First slide', 'advance-wp-slider' ),
						'content'     => __( 'Create beautiful carousels with full control.', 'advance-wp-slider' ),
						'button_text' => __( 'Get started', 'advance-wp-slider' ),
						'button_link' => array( 'url' => '#' ),
					),
					array(
						'image'       => array(
							'url' => AWP_SLIDER_PLUGIN_URL . 'assets/img/hero-2.jpg',
						),
						'title'       => __( 'Second slide', 'advance-wp-slider' ),
						'content'     => __( 'Tune colors, autoplay, effects, and navigation.', 'advance-wp-slider' ),
						'button_text' => __( 'Explore', 'advance-wp-slider' ),
						'button_link' => array( 'url' => '#' ),
					),
				),
				'title_field' => '{{{ title }}}',
				'condition'   => array(
					'source' => 'custom',
				),
			)
		);

		$this->add_control(
			'cpt_limit',
			array(
				'label'     => __( 'Number of CPT slides', 'advance-wp-slider' ),
				'type'      => Controls_Manager::NUMBER,
				'default'   => 10,
				'min'       => 1,
				'max'       => 50,
				'condition' => array(
					'source' => 'cpt',
				),
			)
		);

		$this->add_control(
			'cpt_order',
			array(
				'label'     => __( 'Order', 'advance-wp-slider' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'ASC',
				'options'   => array(
					'ASC'  => __( 'Ascending', 'advance-wp-slider' ),
					'DESC' => __( 'Descending', 'advance-wp-slider' ),
				),
				'condition' => array(
					'source' => 'cpt',
				),
			)
		);

		$this->end_controls_section();

		$this->start_controls_section(
			'section_carousel',
			array(
				'label' => __( 'Carousel', 'advance-wp-slider' ),
			)
		);

		$this->add_control(
			'autoplay',
			array(
				'label'        => __( 'Autoplay', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => ! empty( $defaults['autoplay'] ) ? 'yes' : '',
			)
		);

		$this->add_control(
			'autoplay_delay',
			array(
				'label'     => __( 'Autoplay delay (ms)', 'advance-wp-slider' ),
				'type'      => Controls_Manager::NUMBER,
				'default'   => $defaults['autoplay_delay'],
				'condition' => array(
					'autoplay' => 'yes',
				),
			)
		);

		$this->add_control(
			'loop',
			array(
				'label'        => __( 'Loop', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => ! empty( $defaults['loop'] ) ? 'yes' : '',
			)
		);

		$this->add_control(
			'speed',
			array(
				'label'   => __( 'Speed (ms)', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['speed'],
			)
		);

		$this->add_control(
			'effect',
			array(
				'label'   => __( 'Effect', 'advance-wp-slider' ),
				'type'    => Controls_Manager::SELECT,
				'default' => $defaults['effect'],
				'options' => array(
					'slide'     => __( 'Slide', 'advance-wp-slider' ),
					'fade'      => __( 'Fade', 'advance-wp-slider' ),
					'cube'      => __( 'Cube', 'advance-wp-slider' ),
					'coverflow' => __( 'Coverflow', 'advance-wp-slider' ),
					'flip'      => __( 'Flip', 'advance-wp-slider' ),
				),
			)
		);

		$this->add_responsive_control(
			'slides_per_view',
			array(
				'label'          => __( 'Slides per view', 'advance-wp-slider' ),
				'type'           => Controls_Manager::NUMBER,
				'default'        => $defaults['slides_per_view'],
				'tablet_default' => $defaults['slides_per_view_tablet'],
				'mobile_default' => $defaults['slides_per_view_mobile'],
				'min'            => 1,
				'step'           => 0.1,
			)
		);

		$this->add_control(
			'space_between',
			array(
				'label'   => __( 'Space between', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['space_between'],
			)
		);

		$this->add_control(
			'centered_slides',
			array(
				'label'        => __( 'Centered slides', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => '',
			)
		);

		$this->add_control(
			'pause_on_hover',
			array(
				'label'        => __( 'Pause on hover', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'keyboard',
			array(
				'label'        => __( 'Keyboard', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'grab_cursor',
			array(
				'label'        => __( 'Grab cursor', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'show_arrows',
			array(
				'label'        => __( 'Arrows', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'show_pagination',
			array(
				'label'        => __( 'Pagination', 'advance-wp-slider' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'pagination_type',
			array(
				'label'     => __( 'Pagination type', 'advance-wp-slider' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'bullets',
				'options'   => array(
					'bullets'     => __( 'Bullets', 'advance-wp-slider' ),
					'fraction'    => __( 'Fraction', 'advance-wp-slider' ),
					'progressbar' => __( 'Progress bar', 'advance-wp-slider' ),
				),
				'condition' => array(
					'show_pagination' => 'yes',
				),
			)
		);

		$this->add_control(
			'slide_height',
			array(
				'label'   => __( 'Slide height (px)', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['slide_height'],
				'min'     => 200,
			)
		);

		$this->add_control(
			'content_align',
			array(
				'label'   => __( 'Content align', 'advance-wp-slider' ),
				'type'    => Controls_Manager::CHOOSE,
				'options' => array(
					'left'   => array(
						'title' => __( 'Left', 'advance-wp-slider' ),
						'icon'  => 'eicon-text-align-left',
					),
					'center' => array(
						'title' => __( 'Center', 'advance-wp-slider' ),
						'icon'  => 'eicon-text-align-center',
					),
					'right'  => array(
						'title' => __( 'Right', 'advance-wp-slider' ),
						'icon'  => 'eicon-text-align-right',
					),
				),
				'default' => 'center',
			)
		);

		$this->add_control(
			'overlay_opacity',
			array(
				'label'   => __( 'Overlay opacity (%)', 'advance-wp-slider' ),
				'type'    => Controls_Manager::SLIDER,
				'range'   => array(
					'%' => array(
						'min' => 0,
						'max' => 100,
					),
				),
				'default' => array(
					'size' => $defaults['overlay_opacity'],
					'unit' => '%',
				),
			)
		);

		$this->end_controls_section();

		$this->start_controls_section(
			'section_style_colors',
			array(
				'label' => __( 'Colors', 'advance-wp-slider' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$color_map = array(
			'color_heading'        => array( __( 'Heading', 'advance-wp-slider' ), $defaults['color_heading'] ),
			'color_text'           => array( __( 'Text', 'advance-wp-slider' ), $defaults['color_text'] ),
			'color_btn_bg'         => array( __( 'Button background', 'advance-wp-slider' ), $defaults['color_btn_bg'] ),
			'color_btn_text'       => array( __( 'Button text', 'advance-wp-slider' ), $defaults['color_btn_text'] ),
			'color_btn_hover_bg'   => array( __( 'Button hover background', 'advance-wp-slider' ), $defaults['color_btn_hover_bg'] ),
			'color_btn_hover_text' => array( __( 'Button hover text', 'advance-wp-slider' ), $defaults['color_btn_hover_text'] ),
			'color_arrow'          => array( __( 'Arrow', 'advance-wp-slider' ), $defaults['color_arrow'] ),
			'color_arrow_bg'       => array( __( 'Arrow background', 'advance-wp-slider' ), '#111827' ),
			'color_arrow_hover'    => array( __( 'Arrow hover', 'advance-wp-slider' ), $defaults['color_arrow_hover'] ),
			'color_dot'            => array( __( 'Pagination inactive', 'advance-wp-slider' ), '#ffffff' ),
			'color_dot_active'     => array( __( 'Pagination active', 'advance-wp-slider' ), $defaults['color_dot_active'] ),
			'color_overlay'        => array( __( 'Overlay', 'advance-wp-slider' ), $defaults['color_overlay'] ),
		);

		foreach ( $color_map as $key => $meta ) {
			$this->add_control(
				$key,
				array(
					'label'   => $meta[0],
					'type'    => Controls_Manager::COLOR,
					'default' => $meta[1],
				)
			);
		}

		$this->end_controls_section();

		$this->start_controls_section(
			'section_style_typography',
			array(
				'label' => __( 'Typography & Button', 'advance-wp-slider' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'title_typography',
				'label'    => __( 'Title typography', 'advance-wp-slider' ),
				'selector' => '{{WRAPPER}} .awp-slide__title',
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'text_typography',
				'label'    => __( 'Text typography', 'advance-wp-slider' ),
				'selector' => '{{WRAPPER}} .awp-slide__text',
			)
		);

		$this->add_control(
			'btn_radius',
			array(
				'label'   => __( 'Button radius', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['btn_radius'],
			)
		);

		$this->add_control(
			'btn_padding_y',
			array(
				'label'   => __( 'Button padding Y', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['btn_padding_y'],
			)
		);

		$this->add_control(
			'btn_padding_x',
			array(
				'label'   => __( 'Button padding X', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['btn_padding_x'],
			)
		);

		$this->add_control(
			'arrow_size',
			array(
				'label'   => __( 'Arrow size', 'advance-wp-slider' ),
				'type'    => Controls_Manager::NUMBER,
				'default' => $defaults['arrow_size'],
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Build settings array from widget controls.
	 *
	 * @param array $settings Elementor settings.
	 * @return array
	 */
	private function map_settings( $settings ) {
		$global = AWP_Settings::get();

		$spv        = isset( $settings['slides_per_view'] ) ? $settings['slides_per_view'] : $global['slides_per_view'];
		$spv_tablet = isset( $settings['slides_per_view_tablet'] ) ? $settings['slides_per_view_tablet'] : $global['slides_per_view_tablet'];
		$spv_mobile = isset( $settings['slides_per_view_mobile'] ) ? $settings['slides_per_view_mobile'] : $global['slides_per_view_mobile'];

		$overlay = $global['overlay_opacity'];
		if ( isset( $settings['overlay_opacity']['size'] ) ) {
			$overlay = $settings['overlay_opacity']['size'];
		}

		return array(
			'autoplay'                 => ( ! empty( $settings['autoplay'] ) && 'yes' === $settings['autoplay'] ) ? 1 : 0,
			'autoplay_delay'           => isset( $settings['autoplay_delay'] ) ? absint( $settings['autoplay_delay'] ) : $global['autoplay_delay'],
			'loop'                     => ( ! empty( $settings['loop'] ) && 'yes' === $settings['loop'] ) ? 1 : 0,
			'speed'                    => isset( $settings['speed'] ) ? absint( $settings['speed'] ) : $global['speed'],
			'effect'                   => isset( $settings['effect'] ) ? $settings['effect'] : $global['effect'],
			'slides_per_view'          => floatval( $spv ),
			'slides_per_view_tablet'   => floatval( $spv_tablet ),
			'slides_per_view_mobile'   => floatval( $spv_mobile ),
			'space_between'            => isset( $settings['space_between'] ) ? absint( $settings['space_between'] ) : $global['space_between'],
			'centered_slides'          => ( ! empty( $settings['centered_slides'] ) && 'yes' === $settings['centered_slides'] ) ? 1 : 0,
			'pause_on_hover'           => ( ! empty( $settings['pause_on_hover'] ) && 'yes' === $settings['pause_on_hover'] ) ? 1 : 0,
			'keyboard'                 => ( ! empty( $settings['keyboard'] ) && 'yes' === $settings['keyboard'] ) ? 1 : 0,
			'grab_cursor'              => ( ! empty( $settings['grab_cursor'] ) && 'yes' === $settings['grab_cursor'] ) ? 1 : 0,
			'show_arrows'              => ( ! empty( $settings['show_arrows'] ) && 'yes' === $settings['show_arrows'] ) ? 1 : 0,
			'show_pagination'          => ( ! empty( $settings['show_pagination'] ) && 'yes' === $settings['show_pagination'] ) ? 1 : 0,
			'pagination_type'          => isset( $settings['pagination_type'] ) ? $settings['pagination_type'] : $global['pagination_type'],
			'slide_height'             => isset( $settings['slide_height'] ) ? absint( $settings['slide_height'] ) : $global['slide_height'],
			'content_align'            => isset( $settings['content_align'] ) ? $settings['content_align'] : $global['content_align'],
			'overlay_opacity'          => absint( $overlay ),
			'color_heading'            => $settings['color_heading'] ?? $global['color_heading'],
			'color_text'               => $settings['color_text'] ?? $global['color_text'],
			'color_btn_bg'             => $settings['color_btn_bg'] ?? $global['color_btn_bg'],
			'color_btn_text'           => $settings['color_btn_text'] ?? $global['color_btn_text'],
			'color_btn_hover_bg'       => $settings['color_btn_hover_bg'] ?? $global['color_btn_hover_bg'],
			'color_btn_hover_text'     => $settings['color_btn_hover_text'] ?? $global['color_btn_hover_text'],
			'color_arrow'              => $settings['color_arrow'] ?? $global['color_arrow'],
			'color_arrow_bg'           => $settings['color_arrow_bg'] ?? $global['color_arrow_bg'],
			'color_arrow_hover'        => $settings['color_arrow_hover'] ?? $global['color_arrow_hover'],
			'color_dot'                => $settings['color_dot'] ?? $global['color_dot'],
			'color_dot_active'         => $settings['color_dot_active'] ?? $global['color_dot_active'],
			'color_overlay'            => $settings['color_overlay'] ?? $global['color_overlay'],
			'btn_radius'               => isset( $settings['btn_radius'] ) ? absint( $settings['btn_radius'] ) : $global['btn_radius'],
			'btn_padding_y'            => isset( $settings['btn_padding_y'] ) ? absint( $settings['btn_padding_y'] ) : $global['btn_padding_y'],
			'btn_padding_x'            => isset( $settings['btn_padding_x'] ) ? absint( $settings['btn_padding_x'] ) : $global['btn_padding_x'],
			'arrow_size'               => isset( $settings['arrow_size'] ) ? absint( $settings['arrow_size'] ) : $global['arrow_size'],
		);
	}

	/**
	 * Collect slides for output.
	 *
	 * @param array $settings Settings.
	 * @return array
	 */
	private function collect_slides( $settings ) {
		if ( isset( $settings['source'] ) && 'cpt' === $settings['source'] ) {
			return AWP_Renderer::slides_from_cpt(
				array(
					'posts_per_page' => isset( $settings['cpt_limit'] ) ? absint( $settings['cpt_limit'] ) : 10,
					'order'          => isset( $settings['cpt_order'] ) ? $settings['cpt_order'] : 'ASC',
				)
			);
		}

		$slides = array();
		if ( empty( $settings['slides'] ) || ! is_array( $settings['slides'] ) ) {
			return $slides;
		}

		foreach ( $settings['slides'] as $item ) {
			$image = '';
			if ( ! empty( $item['image']['url'] ) ) {
				$image = $item['image']['url'];
			}

			$link = '#';
			if ( ! empty( $item['button_link']['url'] ) ) {
				$link = $item['button_link']['url'];
			}

			$slides[] = array(
				'image'       => $image,
				'title'       => isset( $item['title'] ) ? $item['title'] : '',
				'subtitle'    => isset( $item['subtitle'] ) ? $item['subtitle'] : '',
				'content'     => isset( $item['content'] ) ? $item['content'] : '',
				'button_text' => isset( $item['button_text'] ) ? $item['button_text'] : '',
				'button_link' => $link,
			);
		}

		return $slides;
	}

	/**
	 * Render widget.
	 */
	protected function render() {
		$settings = $this->get_settings_for_display();
		$slides   = $this->collect_slides( $settings );
		$mapped   = $this->map_settings( $settings );

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- renderer escapes.
		echo AWP_Renderer::render( $slides, $mapped, array( 'class' => 'awp-slider--elementor' ) );
	}
}
