<?php
/**
 * Widget Name: Heading Title
 * Description: A unique, highly flexible heading widget with selectable visual
 *              styles, an optional highlighted phrase, subtitle, separator,
 *              link and complete typography / spacing controls. Only the
 *              selected style CSS file is loaded on the frontend.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.3.0
 */

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

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

/**
 * Class Captwiki_Heading_Title
 *
 * @since 1.3.0
 */
class Captwiki_Heading_Title extends Widget_Base {

	/**
	 * Get widget name.
	 *
	 * @since 1.3.0
	 * @return string
	 */
	public function get_name(): string {
		return 'captwiki-heading-title';
	}

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

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

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

	/**
	 * Get widget keywords.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'heading', 'title', 'headline', 'text', 'typography', 'captain-widgets-kit' );
	}

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

	/**
	 * Disable Elementor's default inner wrapper.
	 *
	 * @since 1.3.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.3.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Classic', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Underline Accent', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Gradient Text', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Highlight Marker', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Side Accent Bar', 'captain-widgets-kit' ),
			'style-6' => esc_html__( 'Style 6 – Stacked Subtitle', 'captain-widgets-kit' ),
		);
	}

	/**
	 * Allowed HTML tags for the heading.
	 *
	 * @since 1.3.0
	 * @return array
	 */
	private function captwiki_tag_options(): array {
		return array(
			'h1'   => 'H1',
			'h2'   => 'H2',
			'h3'   => 'H3',
			'h4'   => 'H4',
			'h5'   => 'H5',
			'h6'   => 'H6',
			'div'  => 'div',
			'span' => 'span',
			'p'    => 'p',
		);
	}

	/**
	 * Register widget controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	protected function register_controls(): void {
		$this->register_content_controls();
		$this->register_general_style_controls();
		$this->register_title_style_controls();
		$this->register_highlight_style_controls();
		$this->register_subtitle_style_controls();
		$this->register_separator_style_controls();
	}

	/**
	 * Content tab controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_content_controls(): void {

		$this->start_controls_section(
			'section_heading_content',
			array(
				'label' => esc_html__( 'Heading', '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(
			'title_text',
			array(
				'label'       => esc_html__( 'Title', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXTAREA,
				'rows'        => 3,
				'default'     => esc_html__( 'Add Your Heading Text Here', 'captain-widgets-kit' ),
				'placeholder' => esc_html__( 'Enter your heading', 'captain-widgets-kit' ),
				'dynamic'     => array( 'active' => true ),
			)
		);

		$this->add_control(
			'highlight_text',
			array(
				'label'       => esc_html__( 'Highlighted Words', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Heading', 'captain-widgets-kit' ),
				'placeholder' => esc_html__( 'Word(s) inside the title to highlight', 'captain-widgets-kit' ),
				'description' => esc_html__( 'A matching word/phrase inside the title gets the highlight style. Leave empty to disable.', 'captain-widgets-kit' ),
				'label_block' => true,
				'dynamic'     => array( 'active' => true ),
			)
		);

		$this->add_control(
			'title_tag',
			array(
				'label'   => esc_html__( 'HTML Tag', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'h2',
				'options' => $this->captwiki_tag_options(),
			)
		);

		$this->add_control(
			'title_link',
			array(
				'label'       => esc_html__( 'Link', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::URL,
				'placeholder' => esc_html__( 'https://example.com', 'captain-widgets-kit' ),
				'default'     => array( 'url' => '' ),
				'dynamic'     => array( 'active' => true ),
				'label_block' => true,
			)
		);

		$this->add_control(
			'subtitle_heading',
			array(
				'label'     => esc_html__( 'Subtitle', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		$this->add_control(
			'show_subtitle',
			array(
				'label'        => esc_html__( 'Show Subtitle', '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'      => '',
			)
		);

		$this->add_control(
			'subtitle_text',
			array(
				'label'       => esc_html__( 'Subtitle Text', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXTAREA,
				'rows'        => 2,
				'default'     => esc_html__( 'Supporting subtitle text goes here.', 'captain-widgets-kit' ),
				'placeholder' => esc_html__( 'Enter subtitle', 'captain-widgets-kit' ),
				'dynamic'     => array( 'active' => true ),
				'condition'   => array( 'show_subtitle' => 'yes' ),
			)
		);

		$this->add_control(
			'subtitle_position',
			array(
				'label'     => esc_html__( 'Subtitle Position', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'below',
				'options'   => array(
					'above' => esc_html__( 'Above Title', 'captain-widgets-kit' ),
					'below' => esc_html__( 'Below Title', 'captain-widgets-kit' ),
				),
				'condition' => array( 'show_subtitle' => 'yes' ),
			)
		);

		$this->add_control(
			'separator_heading',
			array(
				'label'     => esc_html__( 'Separator', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

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

		$this->end_controls_section();
	}

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

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

		$this->add_responsive_control(
			'alignment',
			array(
				'label'     => esc_html__( 'Alignment', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::CHOOSE,
				'default'   => 'left',
				'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' => array(
					'{{WRAPPER}} .captwiki-heading-title' => 'text-align: {{VALUE}};',
				),
			)
		);

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

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

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

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

		$this->add_responsive_control(
			'wrapper_padding',
			array(
				'label'      => esc_html__( 'Padding', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%', 'em', 'rem' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'wrapper_margin',
			array(
				'label'      => esc_html__( 'Margin', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%', 'em', 'rem' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Title style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_title_style_controls(): void {

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

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

		$this->add_group_control(
			Group_Control_Text_Shadow::get_type(),
			array(
				'name'     => 'title_text_shadow',
				'label'    => esc_html__( 'Text Shadow', 'captain-widgets-kit' ),
				'selector' => '{{WRAPPER}} .captwiki-heading-title__heading',
			)
		);

		$this->add_control(
			'title_hover_transition',
			array(
				'label'     => esc_html__( 'Hover Transition (s)', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::SLIDER,
				'range'     => array(
					'px' => array( 'min' => 0, 'max' => 3, 'step' => 0.1 ),
				),
				'default'   => array( 'size' => 0.3 ),
				'selectors' => array(
					'{{WRAPPER}} .captwiki-heading-title__heading, {{WRAPPER}} .captwiki-heading-title__link' => 'transition: all {{SIZE}}s ease;',
				),
			)
		);

		$this->start_controls_tabs( 'tabs_title_colors' );

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

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

			$this->end_controls_tab();

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

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

			$this->end_controls_tab();

		$this->end_controls_tabs();

		$this->add_responsive_control(
			'title_spacing',
			array(
				'label'      => esc_html__( 'Margin', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', '%' ),
				'separator'  => 'before',
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__heading' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Highlighted phrase style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_highlight_style_controls(): void {

		$this->start_controls_section(
			'section_highlight_style',
			array(
				'label'     => esc_html__( 'Highlight', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'highlight_text!' => '' ),
			)
		);

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

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

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

		$this->add_responsive_control(
			'highlight_padding',
			array(
				'label'      => esc_html__( 'Padding', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__highlight' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'highlight_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 50 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__highlight' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Subtitle style controls.
	 *
	 * @since 1.3.0
	 * @return void
	 */
	private function register_subtitle_style_controls(): void {

		$this->start_controls_section(
			'section_subtitle_style',
			array(
				'label'     => esc_html__( 'Subtitle', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_subtitle' => 'yes' ),
			)
		);

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

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

		$this->add_responsive_control(
			'subtitle_spacing',
			array(
				'label'      => esc_html__( 'Margin', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', '%' ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__subtitle' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

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

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

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

		$this->add_responsive_control(
			'separator_width',
			array(
				'label'      => esc_html__( 'Width', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array(
					'px' => array( 'min' => 10, 'max' => 600, 'step' => 1 ),
					'%'  => array( 'min' => 1, 'max' => 100, 'step' => 1 ),
				),
				'default'    => array( 'unit' => 'px', 'size' => 80 ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__separator' => 'width: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'separator_height',
			array(
				'label'      => esc_html__( 'Thickness', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array( 'min' => 1, 'max' => 30, 'step' => 1 ),
				),
				'default'    => array( 'unit' => 'px', 'size' => 4 ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__separator' => 'height: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'separator_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 30 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 4 ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__separator' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'separator_spacing',
			array(
				'label'      => esc_html__( 'Spacing', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array(
					'px' => array( 'min' => 0, 'max' => 80, 'step' => 1 ),
				),
				'default'    => array( 'unit' => 'px', 'size' => 16 ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-heading-title__separator' => 'margin-top: {{SIZE}}{{UNIT}}; margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Build the title HTML, wrapping the highlighted phrase when present.
	 *
	 * @since 1.3.0
	 * @param array $settings Widget settings.
	 * @return string Safe HTML for the title inner content.
	 */
	private function captwiki_get_title_html( array $settings ): string {
		$title     = trim( (string) $settings['title_text'] );
		$highlight = trim( (string) $settings['highlight_text'] );

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

		$safe_title = esc_html( $title );

		if ( '' === $highlight ) {
			return $safe_title;
		}

		$safe_highlight = esc_html( $highlight );

		// Replace only the first case-insensitive match within the escaped title.
		// Callback avoids $ / backslash in the matched text being read as backreferences.
		$pattern = '/' . preg_quote( $safe_highlight, '/' ) . '/i';
		$result  = preg_replace_callback(
			$pattern,
			static function ( $matches ) {
				return '<span class="captwiki-heading-title__highlight">' . $matches[0] . '</span>';
			},
			$safe_title,
			1
		);

		return null === $result ? $safe_title : $result;
	}

	/**
	 * Render the subtitle block.
	 *
	 * @since 1.3.0
	 * @param array $settings Widget settings.
	 * @return void
	 */
	private function captwiki_render_subtitle( array $settings ): void {
		if ( 'yes' !== $settings['show_subtitle'] || '' === trim( (string) $settings['subtitle_text'] ) ) {
			return;
		}

		echo '<p class="captwiki-heading-title__subtitle">' . esc_html( $settings['subtitle_text'] ) . '</p>';
	}

	/**
	 * Render the separator element.
	 *
	 * @since 1.3.0
	 * @param array $settings Widget settings.
	 * @return void
	 */
	private function captwiki_render_separator( array $settings ): void {
		if ( 'yes' !== $settings['show_separator'] ) {
			return;
		}

		echo '<span class="captwiki-heading-title__separator" aria-hidden="true"></span>';
	}

	/**
	 * Render widget output on the frontend.
	 *
	 * Loads only the selected style CSS file (depends on the common stylesheet).
	 *
	 * @since 1.3.0
	 * @return void
	 */
	protected function render(): void {
		$settings = $this->get_settings_for_display();

		$title_html = $this->captwiki_get_title_html( $settings );
		if ( '' === $title_html ) {
			return;
		}

		$allowed_styles = array_keys( $this->captwiki_style_options() );
		$style          = in_array( $settings['widget_style'], $allowed_styles, true ) ? $settings['widget_style'] : 'style-1';

		$allowed_tags = array_keys( $this->captwiki_tag_options() );
		$tag          = in_array( $settings['title_tag'], $allowed_tags, true ) ? $settings['title_tag'] : 'h2';

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

		$unique_class = 'captwiki-widget-' . $this->get_id();
		$subtitle_pos = ! empty( $settings['subtitle_position'] ) ? $settings['subtitle_position'] : 'below';
		$has_link     = ! empty( $settings['title_link']['url'] );
		$allowed_html = array( 'span' => array( 'class' => array() ) );

		echo '<div class="captwiki-heading-title captwiki-' . esc_attr( $style ) . ' ' . esc_attr( $unique_class ) . '">';

		if ( 'above' === $subtitle_pos ) {
			$this->captwiki_render_subtitle( $settings );
		}

		echo '<' . esc_attr( $tag ) . ' class="captwiki-heading-title__heading">';

		if ( $has_link ) {
			$link_target = ! empty( $settings['title_link']['is_external'] ) ? ' target="_blank"' : '';
			$link_rel    = ! empty( $settings['title_link']['nofollow'] ) ? ' rel="nofollow"' : '';

			echo '<a class="captwiki-heading-title__link" href="' . esc_url( $settings['title_link']['url'] ) . '"' . $link_target . $link_rel . '>';
			echo wp_kses( $title_html, $allowed_html );
			echo '</a>';
		} else {
			echo wp_kses( $title_html, $allowed_html );
		}

		echo '</' . esc_attr( $tag ) . '>';

		$this->captwiki_render_separator( $settings );

		if ( 'below' === $subtitle_pos ) {
			$this->captwiki_render_subtitle( $settings );
		}

		echo '</div>';
	}
}
