<?php
/**
 * Global related posts widget.
 *
 * @package IMPACT_WIDGETS_ELEMENTOR
 */

namespace ImpactAddons\ImpactWidgetsForElementor\Widgets;

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

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

class Related_Posts extends Widget_Base {
	use Post_Context;

	public function get_name(): string {
		return 'impact_widgets_elementor_related-posts';
	}

	public function get_title(): string {
		return esc_html__( 'Related Posts', 'impact-widgets-for-elementor' );
	}

	public function get_icon(): string {
		return 'eicon-post-list';
	}

	public function get_categories(): array {
		return array( 'impact-widgets-elementor' );
	}

	public function get_keywords(): array {
		return array( 'blog', 'post', 'related', 'recent', 'articles', 'query', 'list' );
	}

	public function get_style_depends(): array {
		return array( 'impact_widgets_elementor_post-widgets' );
	}

	protected function register_controls(): void {
		$this->register_query_controls();
		$this->register_layout_controls();
		$this->register_content_controls();
		$this->register_card_style_controls();
		$this->register_heading_style_controls();
		$this->register_layout_style_controls();
		$this->register_image_style_controls();
		$this->register_title_style_controls();
		$this->register_meta_style_controls();
		$this->register_excerpt_style_controls();
		$this->register_read_more_style_controls();
	}

	protected function register_layout_controls(): void {
		$this->start_controls_section(
			'section_layout',
			array(
				'label' => esc_html__( 'Layout', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'layout',
			array(
				'label'   => esc_html__( 'Results Layout', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'list',
				'options' => array(
					'list' => esc_html__( 'List', 'impact-widgets-for-elementor' ),
					'grid' => esc_html__( 'Grid', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'card_preset',
			array(
				'label'   => esc_html__( 'Card Preset', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'default',
				'options' => array(
					'default'       => esc_html__( 'Default', 'impact-widgets-for-elementor' ),
					'feature_split' => esc_html__( 'Feature Split Card', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_responsive_control(
			'columns',
			array(
				'label'           => esc_html__( 'Columns', 'impact-widgets-for-elementor' ),
				'type'            => Controls_Manager::SELECT,
				'default'         => '2',
				'tablet_default'  => '2',
				'mobile_default'  => '1',
				'options'         => array(
					'1' => '1',
					'2' => '2',
					'3' => '3',
					'4' => '4',
				),
				'selectors'       => array(
					'{{WRAPPER}} .iaew-post-related--grid .iaew-post-related__list' => 'grid-template-columns: repeat({{VALUE}}, minmax(0, 1fr));',
				),
				'condition'       => array(
					'layout' => 'grid',
				),
			)
		);

		$this->add_control(
			'card_orientation',
			array(
				'label'   => esc_html__( 'Card Orientation', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'horizontal',
				'options' => array(
					'horizontal' => esc_html__( 'Horizontal', 'impact-widgets-for-elementor' ),
					'vertical'   => esc_html__( 'Vertical', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'image_position',
			array(
				'label'     => esc_html__( 'Image Position', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'before',
				'options'   => array(
					'before' => esc_html__( 'Before Content', 'impact-widgets-for-elementor' ),
					'after'  => esc_html__( 'After Content', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'show_image' => 'yes',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_query_controls(): void {
		$this->start_controls_section(
			'section_query',
			array(
				'label' => esc_html__( 'Query', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'query_source',
			array(
				'label'   => esc_html__( 'Source', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'recent',
				'options' => array(
					'related'            => esc_html__( 'Related to Current Post', 'impact-widgets-for-elementor' ),
					'recent'             => esc_html__( 'Recent Posts', 'impact-widgets-for-elementor' ),
					'selected_categories' => esc_html__( 'Selected Categories', 'impact-widgets-for-elementor' ),
					'selected_tags'      => esc_html__( 'Selected Tags', 'impact-widgets-for-elementor' ),
					'manual'             => esc_html__( 'Manually Selected Posts', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'related_by',
			array(
				'label'     => esc_html__( 'Related By', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'category_or_tag',
				'options'   => array(
					'category'        => esc_html__( 'Category', 'impact-widgets-for-elementor' ),
					'tag'             => esc_html__( 'Tag', 'impact-widgets-for-elementor' ),
					'category_or_tag' => esc_html__( 'Category or Tag', 'impact-widgets-for-elementor' ),
					'category_and_tag' => esc_html__( 'Category and Tag', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'query_source' => 'related',
				),
			)
		);

		$this->add_control(
			'query_categories',
			array(
				'label'       => esc_html__( 'Categories', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::SELECT2,
				'options'     => $this->get_term_options( 'category' ),
				'multiple'    => true,
				'label_block' => true,
				'condition'   => array(
					'query_source' => 'selected_categories',
				),
			)
		);

		$this->add_control(
			'query_tags',
			array(
				'label'       => esc_html__( 'Tags', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::SELECT2,
				'options'     => $this->get_term_options( 'post_tag' ),
				'multiple'    => true,
				'label_block' => true,
				'condition'   => array(
					'query_source' => 'selected_tags',
				),
			)
		);

		$this->add_control(
			'manual_posts',
			array(
				'label'       => esc_html__( 'Posts', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::SELECT2,
				'options'     => $this->get_post_options(),
				'multiple'    => true,
				'label_block' => true,
				'condition'   => array(
					'query_source' => 'manual',
				),
			)
		);

		$this->add_control(
			'posts_per_page',
			array(
				'label'     => esc_html__( 'Number of Posts', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::NUMBER,
				'min'       => 1,
				'max'       => 50,
				'default'   => 4,
				'condition' => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->add_control(
			'offset',
			array(
				'label'     => esc_html__( 'Offset', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::NUMBER,
				'min'       => 0,
				'max'       => 100,
				'default'   => 0,
				'condition' => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->add_control(
			'orderby',
			array(
				'label'     => esc_html__( 'Order By', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'date',
				'options'   => array(
					'date'          => esc_html__( 'Date', 'impact-widgets-for-elementor' ),
					'title'         => esc_html__( 'Title', 'impact-widgets-for-elementor' ),
					'rand'          => esc_html__( 'Random', 'impact-widgets-for-elementor' ),
					'comment_count' => esc_html__( 'Comment Count', 'impact-widgets-for-elementor' ),
					'modified'      => esc_html__( 'Last Modified', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->add_control(
			'order',
			array(
				'label'     => esc_html__( 'Order', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'DESC',
				'options'   => array(
					'ASC'  => esc_html__( 'Ascending', 'impact-widgets-for-elementor' ),
					'DESC' => esc_html__( 'Descending', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'query_source!' => 'manual',
					'orderby!'      => 'rand',
				),
			)
		);

		$this->add_control(
			'exclude_current',
			array(
				'label'        => esc_html__( 'Exclude Current Post', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'No', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
				'condition'    => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->add_control(
			'exclude_posts',
			array(
				'label'       => esc_html__( 'Exclude Posts', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::SELECT2,
				'options'     => $this->get_post_options(),
				'multiple'    => true,
				'label_block' => true,
				'condition'   => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->add_control(
			'exclude_post_ids',
			array(
				'label'       => esc_html__( 'Exclude Post IDs', 'impact-widgets-for-elementor' ),
				'description' => esc_html__( 'Enter post IDs separated by commas, for example: 12, 25, 48.', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::TEXT,
				'label_block' => true,
				'condition'   => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->add_control(
			'ignore_sticky',
			array(
				'label'        => esc_html__( 'Ignore Sticky Posts', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'No', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
				'condition'    => array(
					'query_source!' => 'manual',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_content_controls(): void {
		$this->start_controls_section(
			'section_content',
			array(
				'label' => esc_html__( 'Content', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'show_heading',
			array(
				'label'        => esc_html__( 'Show Heading', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'heading',
			array(
				'label'     => esc_html__( 'Heading', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => esc_html__( 'Recent Articles', 'impact-widgets-for-elementor' ),
				'condition' => array(
					'show_heading' => 'yes',
				),
			)
		);

		$this->add_control(
			'heading_tag',
			array(
				'label'     => esc_html__( 'Heading HTML Tag', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'h3',
				'options'   => array(
					'h2'  => 'H2',
					'h3'  => 'H3',
					'h4'  => 'H4',
					'h5'  => 'H5',
					'div' => 'div',
				),
				'condition' => array(
					'show_heading' => 'yes',
				),
			)
		);

		$this->add_control(
			'show_image',
			array(
				'label'        => esc_html__( 'Show Featured Image', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'image_size',
			array(
				'label'     => esc_html__( 'Image Size', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'thumbnail',
				'options'   => array(
					'thumbnail' => esc_html__( 'Thumbnail', 'impact-widgets-for-elementor' ),
					'medium'    => esc_html__( 'Medium', 'impact-widgets-for-elementor' ),
					'large'     => esc_html__( 'Large', 'impact-widgets-for-elementor' ),
					'full'      => esc_html__( 'Full', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'show_image' => 'yes',
				),
			)
		);

		$this->add_control(
			'image_source',
			array(
				'label'     => esc_html__( 'Image Source', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'featured_content',
				'options'   => array(
					'featured'         => esc_html__( 'Featured Image Only', 'impact-widgets-for-elementor' ),
					'featured_content' => esc_html__( 'Featured, Then Content Image', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'show_image' => 'yes',
				),
			)
		);

		$this->add_control(
			'fallback_image',
			array(
				'label'       => esc_html__( 'Fallback Image', 'impact-widgets-for-elementor' ),
				'description' => esc_html__( 'Used when a post does not have a featured image.', 'impact-widgets-for-elementor' ),
				'type'        => Controls_Manager::MEDIA,
				'condition'   => array(
					'show_image' => 'yes',
				),
			)
		);

		$this->add_control(
			'show_date',
			array(
				'label'        => esc_html__( 'Show Date', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'content_order',
			array(
				'label'   => esc_html__( 'Content Order', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'standard',
				'options' => array(
					'standard' => esc_html__( 'Title, Meta, Excerpt', 'impact-widgets-for-elementor' ),
					'feature'  => esc_html__( 'Badge, Meta, Title, Excerpt', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'date_format',
			array(
				'label'     => esc_html__( 'Date Format', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => get_option( 'date_format' ),
				'condition' => array(
					'show_date' => 'yes',
				),
			)
		);

		$this->add_control(
			'show_author',
			array(
				'label'        => esc_html__( 'Show Author', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => '',
			)
		);

		$this->add_control(
			'author_prefix',
			array(
				'label'     => esc_html__( 'Author Prefix', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => '',
				'condition' => array(
					'show_author' => 'yes',
				),
			)
		);

		$this->add_control(
			'show_categories',
			array(
				'label'        => esc_html__( 'Show Categories', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => '',
			)
		);

		$this->add_control(
			'meta_separator',
			array(
				'label'   => esc_html__( 'Meta Separator', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::TEXT,
				'default' => '/',
			)
		);

		$this->add_control(
			'meta_order',
			array(
				'label'   => esc_html__( 'Meta Order', 'impact-widgets-for-elementor' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'date_author',
				'options' => array(
					'date_author' => esc_html__( 'Date, Author', 'impact-widgets-for-elementor' ),
					'author_date' => esc_html__( 'Author, Date', 'impact-widgets-for-elementor' ),
				),
			)
		);

		$this->add_control(
			'category_display',
			array(
				'label'     => esc_html__( 'Category Display', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'meta',
				'options'   => array(
					'meta'  => esc_html__( 'Inside Meta', 'impact-widgets-for-elementor' ),
					'badge' => esc_html__( 'Badge Above Content', 'impact-widgets-for-elementor' ),
				),
				'condition' => array(
					'show_categories' => 'yes',
				),
			)
		);

		$this->add_control(
			'show_excerpt',
			array(
				'label'        => esc_html__( 'Show Excerpt', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => '',
			)
		);

		$this->add_control(
			'excerpt_words',
			array(
				'label'     => esc_html__( 'Excerpt Words', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::NUMBER,
				'min'       => 5,
				'max'       => 100,
				'default'   => 18,
				'condition' => array(
					'show_excerpt' => 'yes',
				),
			)
		);

		$this->add_control(
			'excerpt_lines',
			array(
				'label'     => esc_html__( 'Maximum Lines', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::NUMBER,
				'min'       => 0,
				'max'       => 10,
				'default'   => 0,
				'description' => esc_html__( 'Use 0 for no line limit.', 'impact-widgets-for-elementor' ),
				'condition' => array(
					'show_excerpt' => 'yes',
				),
			)
		);

		$this->add_control(
			'show_read_more',
			array(
				'label'        => esc_html__( 'Show Read More', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'impact-widgets-for-elementor' ),
				'label_off'    => esc_html__( 'Hide', 'impact-widgets-for-elementor' ),
				'return_value' => 'yes',
				'default'      => '',
			)
		);

		$this->add_control(
			'read_more_text',
			array(
				'label'     => esc_html__( 'Read More Text', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => esc_html__( 'Read More', 'impact-widgets-for-elementor' ),
				'condition' => array(
					'show_read_more' => 'yes',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_card_style_controls(): void {
		$this->start_controls_section(
			'section_card_style',
			array(
				'label' => esc_html__( 'Card', 'impact-widgets-for-elementor' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_group_control(
			Group_Control_Background::get_type(),
			array(
				'name'     => 'card_background',
				'types'    => array( 'classic', 'gradient' ),
				'selector' => '{{WRAPPER}} .iaew-post-related',
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'card_border',
				'selector' => '{{WRAPPER}} .iaew-post-related',
			)
		);

		$this->add_responsive_control(
			'card_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'default'    => array(
					'top'      => 8,
					'right'    => 8,
					'bottom'   => 8,
					'left'     => 8,
					'unit'     => 'px',
					'isLinked' => true,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'card_padding',
			array(
				'label'      => esc_html__( 'Padding', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', '%' ),
				'default'    => array(
					'top'      => 32,
					'right'    => 32,
					'bottom'   => 32,
					'left'     => 32,
					'unit'     => 'px',
					'isLinked' => true,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Box_Shadow::get_type(),
			array(
				'name'     => 'card_shadow',
				'selector' => '{{WRAPPER}} .iaew-post-related',
			)
		);

		$this->end_controls_section();
	}

	protected function register_heading_style_controls(): void {
		$this->start_controls_section(
			'section_heading_style',
			array(
				'label'     => esc_html__( 'Heading', 'impact-widgets-for-elementor' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'show_heading' => 'yes',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'heading_typography',
				'selector' => '{{WRAPPER}} .iaew-post-related__heading',
			)
		);

		$this->add_control(
			'heading_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#111827',
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__heading' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'heading_alignment',
			array(
				'label'     => esc_html__( 'Alignment', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::CHOOSE,
				'options'   => array(
					'left'   => array(
						'title' => esc_html__( 'Left', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-text-align-left',
					),
					'center' => array(
						'title' => esc_html__( 'Center', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-text-align-center',
					),
					'right'  => array(
						'title' => esc_html__( 'Right', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-text-align-right',
					),
				),
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__heading' => 'text-align: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'heading_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'default'    => array(
					'unit' => 'px',
					'size' => 28,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__heading' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_layout_style_controls(): void {
		$this->start_controls_section(
			'section_layout_style',
			array(
				'label' => esc_html__( 'Layout', 'impact-widgets-for-elementor' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_responsive_control(
			'items_gap',
			array(
				'label'      => esc_html__( 'Items Gap', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 100,
					),
				),
				'default'    => array(
					'unit' => 'px',
					'size' => 28,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__list' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'content_gap',
			array(
				'label'      => esc_html__( 'Image and Content Gap', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'default'    => array(
					'unit' => 'px',
					'size' => 20,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__item' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'content_padding',
			array(
				'label'      => esc_html__( 'Content Padding', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'content_vertical_alignment',
			array(
				'label'     => esc_html__( 'Content Vertical Position', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::CHOOSE,
				'options'   => array(
					'flex-start' => array( 'title' => esc_html__( 'Top', 'impact-widgets-for-elementor' ), 'icon' => 'eicon-v-align-top' ),
					'center'     => array( 'title' => esc_html__( 'Middle', 'impact-widgets-for-elementor' ), 'icon' => 'eicon-v-align-middle' ),
					'flex-end'   => array( 'title' => esc_html__( 'Bottom', 'impact-widgets-for-elementor' ), 'icon' => 'eicon-v-align-bottom' ),
				),
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__content' => 'justify-content: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'equal_height_image',
			array(
				'label'        => esc_html__( 'Stretch Image to Card Height', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => '',
				'condition'    => array(
					'card_orientation' => 'horizontal',
					'show_image'       => 'yes',
				),
			)
		);

		$this->add_control(
			'clip_item_content',
			array(
				'label'        => esc_html__( 'Clip Content to Card Radius', 'impact-widgets-for-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'return_value' => 'yes',
				'default'      => '',
			)
		);

		$this->add_responsive_control(
			'vertical_alignment',
			array(
				'label'     => esc_html__( 'Vertical Alignment', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::CHOOSE,
				'options'   => array(
					'flex-start' => array(
						'title' => esc_html__( 'Top', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-v-align-top',
					),
					'center'     => array(
						'title' => esc_html__( 'Middle', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-v-align-middle',
					),
					'flex-end'   => array(
						'title' => esc_html__( 'Bottom', 'impact-widgets-for-elementor' ),
						'icon'  => 'eicon-v-align-bottom',
					),
				),
				'default'   => 'flex-start',
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__item' => 'align-items: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'item_padding',
			array(
				'label'      => esc_html__( 'Item Padding', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'item_background',
			array(
				'label'     => esc_html__( 'Item Background', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__item' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'item_border',
				'selector' => '{{WRAPPER}} .iaew-post-related__item',
			)
		);

		$this->add_responsive_control(
			'item_radius',
			array(
				'label'      => esc_html__( 'Item Border Radius', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__item' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Box_Shadow::get_type(),
			array(
				'name'     => 'item_shadow',
				'selector' => '{{WRAPPER}} .iaew-post-related__item',
			)
		);

		$this->add_control(
			'divider_color',
			array(
				'label'     => esc_html__( 'List Divider Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related--list .iaew-post-related__item:not(:last-child)' => 'border-bottom-color: {{VALUE}};',
				),
				'condition' => array(
					'layout' => 'list',
				),
			)
		);

		$this->add_responsive_control(
			'divider_width',
			array(
				'label'      => esc_html__( 'List Divider Width', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 10,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related--list .iaew-post-related__item:not(:last-child)' => 'border-bottom-width: {{SIZE}}{{UNIT}}; border-bottom-style: solid;',
				),
				'condition' => array(
					'layout' => 'list',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_image_style_controls(): void {
		$this->start_controls_section(
			'section_image_style',
			array(
				'label'     => esc_html__( 'Image', 'impact-widgets-for-elementor' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'show_image' => 'yes',
				),
			)
		);

		$this->add_responsive_control(
			'image_width',
			array(
				'label'      => esc_html__( 'Width', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array(
					'px' => array(
						'min' => 40,
						'max' => 800,
					),
					'%' => array(
						'min' => 10,
						'max' => 100,
					),
				),
				'default'    => array(
					'unit' => 'px',
					'size' => 130,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related--card-horizontal .iaew-post-related__image' => 'flex-basis: {{SIZE}}{{UNIT}}; width: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'image_width_percent',
			array(
				'label'      => esc_html__( 'Split Width', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( '%' ),
				'range'      => array(
					'%' => array(
						'min' => 20,
						'max' => 80,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related--card-horizontal .iaew-post-related__image' => 'flex-basis: {{SIZE}}%; width: {{SIZE}}%;',
				),
				'condition'  => array(
					'card_orientation' => 'horizontal',
				),
			)
		);

		$this->add_responsive_control(
			'image_height',
			array(
				'label'      => esc_html__( 'Height', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 40,
						'max' => 800,
					),
				),
				'default'    => array(
					'unit' => 'px',
					'size' => 120,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__image img' => 'height: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'image_fit',
			array(
				'label'     => esc_html__( 'Object Fit', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'cover',
				'options'   => array(
					'cover'   => esc_html__( 'Cover', 'impact-widgets-for-elementor' ),
					'contain' => esc_html__( 'Contain', 'impact-widgets-for-elementor' ),
					'fill'    => esc_html__( 'Fill', 'impact-widgets-for-elementor' ),
				),
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__image img' => 'object-fit: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'image_border',
				'selector' => '{{WRAPPER}} .iaew-post-related__image img',
			)
		);

		$this->add_responsive_control(
			'image_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'default'    => array(
					'top'      => 10,
					'right'    => 10,
					'bottom'   => 10,
					'left'     => 10,
					'unit'     => 'px',
					'isLinked' => true,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__image img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Box_Shadow::get_type(),
			array(
				'name'     => 'image_shadow',
				'selector' => '{{WRAPPER}} .iaew-post-related__image img',
			)
		);

		$this->end_controls_section();
	}

	protected function register_title_style_controls(): void {
		$this->start_controls_section(
			'section_title_style',
			array(
				'label' => esc_html__( 'Post Title', 'impact-widgets-for-elementor' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'title_typography',
				'selector' => '{{WRAPPER}} .iaew-post-related__title',
			)
		);

		$this->add_control(
			'title_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#111827',
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__title' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'title_hover_color',
			array(
				'label'     => esc_html__( 'Hover Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#4f2df5',
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__title:hover, {{WRAPPER}} .iaew-post-related__title:focus' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'title_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'default'    => array(
					'unit' => 'px',
					'size' => 10,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__title' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_meta_style_controls(): void {
		$this->start_controls_section(
			'section_meta_style',
			array(
				'label' => esc_html__( 'Meta', 'impact-widgets-for-elementor' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'meta_typography',
				'selector' => '{{WRAPPER}} .iaew-post-related__meta',
			)
		);

		$this->add_control(
			'meta_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#8a94a6',
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__meta, {{WRAPPER}} .iaew-post-related__meta a' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'meta_link_hover_color',
			array(
				'label'     => esc_html__( 'Link Hover Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__meta a:hover, {{WRAPPER}} .iaew-post-related__meta a:focus' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'meta_gap',
			array(
				'label'      => esc_html__( 'Item Gap', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'default'    => array(
					'unit' => 'px',
					'size' => 7,
				),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__meta' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'meta_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__meta' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();

		$this->start_controls_section(
			'section_badge_style',
			array(
				'label'     => esc_html__( 'Category Badge', 'impact-widgets-for-elementor' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'show_categories'  => 'yes',
					'category_display' => 'badge',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'badge_typography',
				'selector' => '{{WRAPPER}} .iaew-post-related__badge',
			)
		);

		$this->add_control(
			'badge_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__badge' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'badge_background',
			array(
				'label'     => esc_html__( 'Background', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__badge' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'badge_padding',
			array(
				'label'      => esc_html__( 'Padding', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__badge' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'badge_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__badge' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'badge_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__badge' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_excerpt_style_controls(): void {
		$this->start_controls_section(
			'section_excerpt_style',
			array(
				'label'     => esc_html__( 'Excerpt', 'impact-widgets-for-elementor' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'show_excerpt' => 'yes',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'excerpt_typography',
				'selector' => '{{WRAPPER}} .iaew-post-related__excerpt',
			)
		);

		$this->add_control(
			'read_more_decoration',
			array(
				'label'     => esc_html__( 'Text Decoration', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'none',
				'options'   => array(
					'none'      => esc_html__( 'None', 'impact-widgets-for-elementor' ),
					'underline' => esc_html__( 'Underline', 'impact-widgets-for-elementor' ),
				),
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__read-more' => 'text-decoration: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'excerpt_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__excerpt' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'excerpt_spacing',
			array(
				'label'      => esc_html__( 'Bottom Spacing', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__excerpt' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function register_read_more_style_controls(): void {
		$this->start_controls_section(
			'section_read_more_style',
			array(
				'label'     => esc_html__( 'Read More', 'impact-widgets-for-elementor' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'show_read_more' => 'yes',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'read_more_typography',
				'selector' => '{{WRAPPER}} .iaew-post-related__read-more',
			)
		);

		$this->start_controls_tabs( 'read_more_tabs' );

		$this->start_controls_tab(
			'read_more_normal_tab',
			array(
				'label' => esc_html__( 'Normal', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'read_more_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__read-more' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'read_more_background',
			array(
				'label'     => esc_html__( 'Background', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__read-more' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'read_more_border',
				'selector' => '{{WRAPPER}} .iaew-post-related__read-more',
			)
		);

		$this->end_controls_tab();

		$this->start_controls_tab(
			'read_more_hover_tab',
			array(
				'label' => esc_html__( 'Hover', 'impact-widgets-for-elementor' ),
			)
		);

		$this->add_control(
			'read_more_hover_color',
			array(
				'label'     => esc_html__( 'Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__read-more:hover, {{WRAPPER}} .iaew-post-related__read-more:focus' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'read_more_hover_background',
			array(
				'label'     => esc_html__( 'Background', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__read-more:hover, {{WRAPPER}} .iaew-post-related__read-more:focus' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'read_more_hover_border_color',
			array(
				'label'     => esc_html__( 'Border Color', 'impact-widgets-for-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .iaew-post-related__read-more:hover, {{WRAPPER}} .iaew-post-related__read-more:focus' => 'border-color: {{VALUE}};',
				),
			)
		);

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

		$this->add_responsive_control(
			'read_more_padding',
			array(
				'label'      => esc_html__( 'Padding', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__read-more' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'read_more_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'impact-widgets-for-elementor' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .iaew-post-related__read-more' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	protected function render(): void {
		$settings    = $this->get_settings_for_display();
		$context     = $this->iaew_get_blog_context_post();
		$query       = new \WP_Query( $this->get_query_args( $settings, $context ) );
		$heading_tag = in_array( $settings['heading_tag'], array( 'h2', 'h3', 'h4', 'h5', 'div' ), true ) ? $settings['heading_tag'] : 'h3';
		$layout      = 'grid' === $settings['layout'] ? 'grid' : 'list';
		$orientation = 'vertical' === ( $settings['card_orientation'] ?? 'horizontal' ) ? 'vertical' : 'horizontal';
		$image_side  = in_array( $settings['image_position'] ?? 'before', array( 'after', 'right' ), true ) ? 'after' : 'before';
		$preset      = 'feature_split' === ( $settings['card_preset'] ?? 'default' ) ? ' iaew-post-related--preset-feature' : '';
		$stretch     = 'yes' === ( $settings['equal_height_image'] ?? '' ) || '' !== $preset ? ' iaew-post-related--stretch-image' : '';
		$clip        = 'yes' === ( $settings['clip_item_content'] ?? '' ) || '' !== $preset ? ' iaew-post-related--clip-items' : '';

		echo '<div class="iaew-post-related iaew-post-related--' . esc_attr( $layout ) . ' iaew-post-related--card-' . esc_attr( $orientation ) . ' iaew-post-related--image-' . esc_attr( $image_side ) . esc_attr( $preset ) . esc_attr( $stretch ) . esc_attr( $clip ) . '">';

		if ( 'yes' === $settings['show_heading'] && '' !== trim( (string) $settings['heading'] ) ) {
			printf(
				'<%1$s class="iaew-post-related__heading">%2$s</%1$s>',
				esc_attr( $heading_tag ),
				esc_html( $settings['heading'] )
			);
		}

		if ( ! $query->have_posts() ) {
			echo '<div class="iaew-post-related__empty">' . esc_html__( 'No posts found.', 'impact-widgets-for-elementor' ) . '</div>';
			echo '</div>';
			wp_reset_postdata();
			return;
		}

		echo '<div class="iaew-post-related__list">';

		while ( $query->have_posts() ) {
			$query->the_post();
			$post = get_post();

			if ( ! $post ) {
				continue;
			}

			$this->render_post( $post, $settings );
		}

		echo '</div></div>';
		wp_reset_postdata();
	}

	protected function render_post( \WP_Post $post, array $settings ): void {
		$permalink = get_permalink( $post );
		$image     = 'yes' === $settings['show_image'] ? $this->get_post_image( $post, $settings ) : '';

		echo '<article class="iaew-post-related__item">';

		if ( '' !== $image ) {
			printf(
				'<a class="iaew-post-related__image" href="%1$s" aria-hidden="true" tabindex="-1">%2$s</a>',
				esc_url( $permalink ),
				$image // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			);
		}

		echo '<div class="iaew-post-related__content">';
		$feature_order = 'feature' === ( $settings['content_order'] ?? 'standard' ) || 'feature_split' === ( $settings['card_preset'] ?? 'default' );
		$badge         = $this->get_category_badge( $post, $settings );
		$meta = $this->get_post_meta_items( $post, $settings );

		if ( $feature_order && '' !== $badge ) {
			echo $badge; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}

		if ( $feature_order && ! empty( $meta ) ) {
			echo '<div class="iaew-post-related__meta">' . implode( '<span class="iaew-post-related__separator">' . esc_html( $settings['meta_separator'] ) . '</span>', $meta ) . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}

		printf(
			'<a class="iaew-post-related__title" href="%1$s">%2$s</a>',
			esc_url( $permalink ),
			esc_html( get_the_title( $post ) )
		);

		if ( ! $feature_order && ! empty( $meta ) ) {
			echo '<div class="iaew-post-related__meta">' . implode( '<span class="iaew-post-related__separator">' . esc_html( $settings['meta_separator'] ) . '</span>', $meta ) . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}

		if ( 'yes' === $settings['show_excerpt'] ) {
			$excerpt = has_excerpt( $post ) ? get_the_excerpt( $post ) : wp_trim_words( wp_strip_all_tags( $post->post_content ), max( 1, absint( $settings['excerpt_words'] ) ) );
			$lines   = absint( $settings['excerpt_lines'] ?? 0 );
			$class   = $lines > 0 ? ' iaew-post-related__excerpt--clamped' : '';
			$style   = $lines > 0 ? ' style="--iaew-excerpt-lines:' . esc_attr( (string) $lines ) . ';"' : '';
			echo '<div class="iaew-post-related__excerpt' . esc_attr( $class ) . '"' . $style . '>' . esc_html( $excerpt ) . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}

		if ( 'yes' === $settings['show_read_more'] && '' !== trim( (string) $settings['read_more_text'] ) ) {
			printf(
				'<a class="iaew-post-related__read-more" href="%1$s">%2$s</a>',
				esc_url( $permalink ),
				esc_html( $settings['read_more_text'] )
			);
		}

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

	private function get_category_badge( \WP_Post $post, array $settings ): string {
		if ( 'yes' !== ( $settings['show_categories'] ?? '' ) || 'badge' !== ( $settings['category_display'] ?? 'meta' ) ) {
			return '';
		}

		$terms = get_the_terms( $post, 'category' );

		if ( is_wp_error( $terms ) || empty( $terms ) ) {
			return '';
		}

		$term = reset( $terms );

		$url = get_term_link( $term );

		if ( is_wp_error( $url ) ) {
			return '';
		}

		return sprintf(
			'<a class="iaew-post-related__badge" href="%1$s">%2$s</a>',
			esc_url( $url ),
			esc_html( $term->name )
		);
	}

	private function get_post_image( \WP_Post $post, array $settings ): string {
		$size = in_array( $settings['image_size'], array( 'thumbnail', 'medium', 'large', 'full' ), true ) ? $settings['image_size'] : 'thumbnail';

		if ( has_post_thumbnail( $post ) ) {
			return (string) get_the_post_thumbnail( $post, $size );
		}

		if ( 'featured_content' === ( $settings['image_source'] ?? 'featured_content' ) && class_exists( '\WP_HTML_Tag_Processor' ) ) {
			$processor = new \WP_HTML_Tag_Processor( (string) $post->post_content );

			if ( $processor->next_tag( 'img' ) ) {
				$src = $processor->get_attribute( 'src' );

				if ( is_string( $src ) && '' !== $src ) {
					return sprintf( '<img src="%1$s" alt="" loading="lazy" />', esc_url( $src ) );
				}
			}
		}

		if ( ! empty( $settings['fallback_image']['id'] ) ) {
			return (string) wp_get_attachment_image( absint( $settings['fallback_image']['id'] ), $size );
		}

		if ( ! empty( $settings['fallback_image']['url'] ) ) {
			return sprintf( '<img src="%1$s" alt="" loading="lazy" />', esc_url( $settings['fallback_image']['url'] ) );
		}

		return '';
	}

	protected function get_post_meta_items( \WP_Post $post, array $settings ): array {
		$items       = array();
		$date_item   = '';
		$author_item = '';

		if ( 'yes' === $settings['show_date'] ) {
			$format  = '' !== trim( (string) $settings['date_format'] ) ? $settings['date_format'] : get_option( 'date_format' );
			$date_item = sprintf(
				'<time datetime="%1$s">%2$s</time>',
				esc_attr( get_the_date( DATE_W3C, $post ) ),
				esc_html( get_the_date( $format, $post ) )
			);
		}

		if ( 'yes' === $settings['show_author'] ) {
			$author = get_the_author_meta( 'display_name', $post->post_author );

			if ( '' !== trim( (string) $author ) ) {
				$author_item = '<span>' . esc_html( (string) ( $settings['author_prefix'] ?? '' ) . $author ) . '</span>';
			}
		}

		if ( 'author_date' === ( $settings['meta_order'] ?? 'date_author' ) ) {
			$items = array_filter( array( $author_item, $date_item ) );
		} else {
			$items = array_filter( array( $date_item, $author_item ) );
		}

		if ( 'yes' === $settings['show_categories'] && 'badge' !== ( $settings['category_display'] ?? 'meta' ) ) {
			$categories = get_the_category_list( ', ', '', $post->ID );

			if ( is_string( $categories ) && '' !== $categories ) {
				$items[] = '<span>' . $categories . '</span>';
			}
		}

		return $items;
	}

	protected function get_query_args( array $settings, ?\WP_Post $context ): array {
		$source = in_array( $settings['query_source'], array( 'related', 'recent', 'selected_categories', 'selected_tags', 'manual' ), true ) ? $settings['query_source'] : 'recent';

		if ( 'manual' === $source ) {
			$post_ids = isset( $settings['manual_posts'] ) && is_array( $settings['manual_posts'] ) ? array_values( array_filter( array_map( 'absint', $settings['manual_posts'] ) ) ) : array();

			return array(
				'post_type'           => 'post',
				'post_status'         => 'publish',
				'post__in'            => ! empty( $post_ids ) ? $post_ids : array( 0 ),
				'orderby'             => 'post__in',
				'posts_per_page'      => count( $post_ids ),
				'ignore_sticky_posts' => true,
				'no_found_rows'       => true,
			);
		}

		$args = array(
			'post_type'           => 'post',
			'post_status'         => 'publish',
			'posts_per_page'      => max( 1, absint( $settings['posts_per_page'] ) ),
			'offset'              => max( 0, absint( $settings['offset'] ) ),
			'orderby'             => in_array( $settings['orderby'], array( 'date', 'title', 'rand', 'comment_count', 'modified' ), true ) ? $settings['orderby'] : 'date',
			'order'               => 'ASC' === $settings['order'] ? 'ASC' : 'DESC',
			'ignore_sticky_posts' => 'yes' === $settings['ignore_sticky'],
			'no_found_rows'       => true,
		);

		$excluded_posts = isset( $settings['exclude_posts'] ) && is_array( $settings['exclude_posts'] ) ? array_map( 'absint', $settings['exclude_posts'] ) : array();
		$excluded_ids   = isset( $settings['exclude_post_ids'] ) ? preg_split( '/[\s,]+/', (string) $settings['exclude_post_ids'] ) : array();
		$excluded_ids   = is_array( $excluded_ids ) ? array_map( 'absint', $excluded_ids ) : array();
		$excluded       = array_values( array_filter( array_unique( array_merge( $excluded_posts, $excluded_ids ) ) ) );

		if ( $context && 'yes' === $settings['exclude_current'] ) {
			$excluded[] = $context->ID;
		}

		if ( ! empty( $excluded ) ) {
			$args['post__not_in'] = array_values( array_unique( $excluded ) );
		}

		if ( 'selected_categories' === $source ) {
			$terms = isset( $settings['query_categories'] ) && is_array( $settings['query_categories'] ) ? array_values( array_filter( array_map( 'absint', $settings['query_categories'] ) ) ) : array();
			$args['category__in'] = ! empty( $terms ) ? $terms : array( 0 );
		} elseif ( 'selected_tags' === $source ) {
			$terms = isset( $settings['query_tags'] ) && is_array( $settings['query_tags'] ) ? array_values( array_filter( array_map( 'absint', $settings['query_tags'] ) ) ) : array();
			$args['tag__in'] = ! empty( $terms ) ? $terms : array( 0 );
		} elseif ( 'related' === $source ) {
			$args = $this->add_related_tax_query( $args, $settings, $context );
		}

		return $args;
	}

	private function add_related_tax_query( array $args, array $settings, ?\WP_Post $context ): array {
		if ( ! $context ) {
			$args['post__in'] = array( 0 );
			return $args;
		}

		$related_by = in_array( $settings['related_by'], array( 'category', 'tag', 'category_or_tag', 'category_and_tag' ), true ) ? $settings['related_by'] : 'category_or_tag';
		$categories = wp_get_post_categories( $context->ID );
		$tags       = wp_get_post_tags( $context->ID, array( 'fields' => 'ids' ) );
		$tax_query  = array();

		if ( in_array( $related_by, array( 'category', 'category_or_tag', 'category_and_tag' ), true ) && ! empty( $categories ) ) {
			$tax_query[] = array(
				'taxonomy' => 'category',
				'field'    => 'term_id',
				'terms'    => $categories,
			);
		}

		if ( in_array( $related_by, array( 'tag', 'category_or_tag', 'category_and_tag' ), true ) && ! empty( $tags ) ) {
			$tax_query[] = array(
				'taxonomy' => 'post_tag',
				'field'    => 'term_id',
				'terms'    => $tags,
			);
		}

		if ( empty( $tax_query ) ) {
			$args['post__in'] = array( 0 );
			return $args;
		}

		if ( count( $tax_query ) > 1 ) {
			$tax_query['relation'] = 'category_and_tag' === $related_by ? 'AND' : 'OR';
		}

		$args['tax_query'] = $tax_query;
		return $args;
	}

	protected function get_term_options( string $taxonomy ): array {
		$options = array();
		$terms   = get_terms(
			array(
				'taxonomy'   => $taxonomy,
				'hide_empty' => false,
				'orderby'    => 'name',
				'order'      => 'ASC',
			)
		);

		if ( is_wp_error( $terms ) ) {
			return $options;
		}

		foreach ( $terms as $term ) {
			$options[ (string) $term->term_id ] = $term->name;
		}

		return $options;
	}

	protected function get_post_options(): array {
		$options = array();
		$posts   = get_posts(
			array(
				'post_type'      => 'post',
				'post_status'    => 'publish',
				'posts_per_page' => 200,
				'orderby'        => 'date',
				'order'          => 'DESC',
			)
		);

		foreach ( $posts as $post ) {
			$options[ (string) $post->ID ] = get_the_title( $post );
		}

		return $options;
	}
}
