<?php
/**
 * Widget Name: Accordion
 * Description: An accessible FAQ / accordion widget with smoothly animated
 *              panels, optional per-item icons, single or multi open mode and
 *              selectable visual styles — classic bordered, separated cards,
 *              minimal underline, filled accent and modern soft. Headers are
 *              real buttons with full ARIA wiring and keyboard navigation.
 *              Only the selected style CSS file is loaded on the frontend.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.7.0
 */

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

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Repeater;
use Elementor\Group_Control_Typography;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Box_Shadow;
use Elementor\Icons_Manager;

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

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

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

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

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

	/**
	 * Get widget keywords.
	 *
	 * @since 1.7.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'accordion', 'faq', 'toggle', 'collapse', 'questions', 'captain-widgets-kit' );
	}

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

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

	/**
	 * Disable Elementor's default inner wrapper.
	 *
	 * @since 1.7.0
	 * @return bool
	 */
	public function has_widget_inner_wrapper(): bool {
		return ! \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
	}

	/**
	 * Selectable visual styles.
	 *
	 * @since 1.7.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Classic Bordered', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Separated Cards', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Minimal Underline', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Filled Accent', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Modern Soft', 'captain-widgets-kit' ),
		);
	}

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

		$this->register_general_style_controls();
		$this->register_header_style_controls();
		$this->register_content_style_controls();
	}

	/**
	 * Content tab — items.
	 *
	 * @since 1.7.0
	 * @return void
	 */
	private function register_items_controls(): void {

		$this->start_controls_section(
			'section_items',
			array(
				'label' => esc_html__( 'Accordion', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'widget_style',
			array(
				'label'   => esc_html__( 'Style', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'style-1',
				'options' => $this->captwiki_style_options(),
			)
		);

		$repeater = new Repeater();

		$repeater->add_control(
			'item_title',
			array(
				'label'       => esc_html__( 'Title', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Accordion Item', 'captain-widgets-kit' ),
				'label_block' => true,
				'dynamic'     => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'item_content',
			array(
				'label'   => esc_html__( 'Content', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::WYSIWYG,
				'default' => esc_html__( 'Add the answer or panel content here. Links, lists and media are all supported.', 'captain-widgets-kit' ),
				'dynamic' => array( 'active' => true ),
			)
		);

		$repeater->add_control(
			'item_icon',
			array(
				'label'       => esc_html__( 'Icon (optional)', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::ICONS,
				'skin'        => 'inline',
				'label_block' => false,
			)
		);

		$this->add_control(
			'items',
			array(
				'label'       => esc_html__( 'Items', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $repeater->get_controls(),
				'default'     => array(
					array(
						'item_title'   => esc_html__( 'What is included in the package?', 'captain-widgets-kit' ),
						'item_content' => esc_html__( 'Every plan includes all core widgets, lifetime updates and access to our template library.', 'captain-widgets-kit' ),
					),
					array(
						'item_title'   => esc_html__( 'Can I cancel my subscription anytime?', 'captain-widgets-kit' ),
						'item_content' => esc_html__( 'Yes — you can cancel anytime from your account dashboard with a single click.', 'captain-widgets-kit' ),
					),
					array(
						'item_title'   => esc_html__( 'Do you offer customer support?', 'captain-widgets-kit' ),
						'item_content' => esc_html__( 'Our support team replies within 24 hours on business days, for every plan.', 'captain-widgets-kit' ),
					),
				),
				'title_field' => '{{{ item_title }}}',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — behaviour settings.
	 *
	 * @since 1.7.0
	 * @return void
	 */
	private function register_settings_controls(): void {

		$this->start_controls_section(
			'section_settings',
			array(
				'label' => esc_html__( 'Settings', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'title_tag',
			array(
				'label'   => esc_html__( 'Title HTML Tag', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'h3',
				'options' => array(
					'h2'  => 'H2',
					'h3'  => 'H3',
					'h4'  => 'H4',
					'h5'  => 'H5',
					'h6'  => 'H6',
					'div' => 'div',
				),
			)
		);

		$this->add_control(
			'first_open',
			array(
				'label'        => esc_html__( 'Open First Item', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'No', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'allow_multiple',
			array(
				'label'        => esc_html__( 'Allow Multiple Open', '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(
			'indicator_type',
			array(
				'label'   => esc_html__( 'Indicator', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'arrow',
				'options' => array(
					'arrow' => esc_html__( 'Arrow', 'captain-widgets-kit' ),
					'plus'  => esc_html__( 'Plus / Minus', 'captain-widgets-kit' ),
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — general.
	 *
	 * @since 1.7.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_control(
			'accent_color',
			array(
				'label'     => esc_html__( 'Accent Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-accordion' => '--captwiki-acc-accent: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'items_gap',
			array(
				'label'      => esc_html__( 'Gap Between Items', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array(
					'px' => array(
						'min' => 0,
						'max' => 60,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-accordion' => '--captwiki-acc-gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

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

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

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

		$this->end_controls_section();
	}

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

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

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'title_typography',
				'label'    => esc_html__( 'Title Typography', 'captain-widgets-kit' ),
				'selector' => '{{WRAPPER}} .captwiki-accordion__title',
			)
		);

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

		$this->add_responsive_control(
			'indicator_size',
			array(
				'label'      => esc_html__( 'Indicator Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array(
					'px' => array(
						'min' => 10,
						'max' => 40,
					),
				),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-accordion' => '--captwiki-acc-indicator: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->start_controls_tabs( 'tabs_header_style' );

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

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

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

		$this->end_controls_tab();

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

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

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

		$this->end_controls_tab();

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

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

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

		$this->end_controls_tab();

		$this->end_controls_tabs();

		$this->end_controls_section();
	}

	/**
	 * Style tab — content panel.
	 *
	 * @since 1.7.0
	 * @return void
	 */
	private function register_content_style_controls(): void {

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

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

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

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

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

		$this->end_controls_section();
	}

	/**
	 * Capture an Elementor icon as an HTML string.
	 *
	 * @since 1.7.0
	 * @param array $icon Icon control value.
	 * @return string
	 */
	private function captwiki_get_icon_html( array $icon ): string {
		ob_start();
		Icons_Manager::render_icon( $icon, array( 'aria-hidden' => 'true' ) );
		return (string) ob_get_clean();
	}

	/**
	 * Render the open / close indicator markup.
	 *
	 * @since 1.7.0
	 * @param string $type Indicator type — 'arrow' or 'plus'.
	 * @return void
	 */
	private function captwiki_render_indicator( string $type ): void {

		if ( 'plus' === $type ) {
			echo '<span class="captwiki-accordion__indicator captwiki-accordion__indicator--plus" aria-hidden="true">'
				. '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><line class="captwiki-accordion__plus-v" x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>'
				. '</span>';
			return;
		}

		echo '<span class="captwiki-accordion__indicator captwiki-accordion__indicator--arrow" aria-hidden="true">'
			. '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>'
			. '</span>';
	}

	/**
	 * Render a single accordion item.
	 *
	 * @since 1.7.0
	 * @param array  $item      Repeater item.
	 * @param int    $index     0-based item index.
	 * @param bool   $is_open   Whether the panel starts expanded.
	 * @param string $title_tag Sanitised heading tag.
	 * @param string $indicator Indicator type.
	 * @return void
	 */
	private function captwiki_render_item( array $item, int $index, bool $is_open, string $title_tag, string $indicator ): void {

		$title    = isset( $item['item_title'] ) ? trim( (string) $item['item_title'] ) : '';
		$content  = isset( $item['item_content'] ) ? (string) $item['item_content'] : '';
		$icon     = isset( $item['item_icon'] ) ? (array) $item['item_icon'] : array();
		$item_id  = ! empty( $item['_id'] ) ? sanitize_html_class( $item['_id'] ) : (string) $index;
		$btn_id   = 'captwiki-acc-btn-' . $this->get_id() . '-' . $item_id;
		$panel_id = 'captwiki-acc-panel-' . $this->get_id() . '-' . $item_id;

		echo '<div class="captwiki-accordion__item' . ( $is_open ? ' is-open' : '' ) . ' elementor-repeater-item-' . esc_attr( $item_id ) . '">';

		echo '<' . esc_attr( $title_tag ) . ' class="captwiki-accordion__header">';
		printf(
			'<button type="button" class="captwiki-accordion__button" id="%1$s" aria-expanded="%2$s" aria-controls="%3$s">',
			esc_attr( $btn_id ),
			$is_open ? 'true' : 'false',
			esc_attr( $panel_id )
		);

		if ( ! empty( $icon['value'] ) ) {
			echo '<span class="captwiki-accordion__icon" aria-hidden="true">' . $this->captwiki_get_icon_html( $icon ) . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		}

		echo '<span class="captwiki-accordion__title">' . esc_html( $title ) . '</span>';

		$this->captwiki_render_indicator( $indicator );

		echo '</button>';
		echo '</' . esc_attr( $title_tag ) . '>';

		printf(
			'<div class="captwiki-accordion__panel" id="%1$s" role="region" aria-labelledby="%2$s"%3$s>',
			esc_attr( $panel_id ),
			esc_attr( $btn_id ),
			$is_open ? '' : ' hidden'
		);
		echo '<div class="captwiki-accordion__content">' . wp_kses_post( $content ) . '</div>';
		echo '</div>';

		echo '</div>';
	}

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

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

		$allowed_styles = array_keys( $this->captwiki_style_options() );
		$style          = in_array( $settings['widget_style'], $allowed_styles, true ) ? $settings['widget_style'] : 'style-1';
		$title_tag      = in_array( $settings['title_tag'], array( 'h2', 'h3', 'h4', 'h5', 'h6', 'div' ), true ) ? $settings['title_tag'] : 'h3';
		$indicator      = 'plus' === $settings['indicator_type'] ? 'plus' : 'arrow';
		$multiple       = 'yes' === $settings['allow_multiple'] ? 'yes' : 'no';
		$first_open     = 'yes' === $settings['first_open'];

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

		printf(
			'<div class="captwiki-accordion captwiki-%1$s" data-multiple="%2$s">',
			esc_attr( $style ),
			esc_attr( $multiple )
		);

		$index = 0;
		foreach ( $settings['items'] as $item ) {
			$this->captwiki_render_item( (array) $item, $index, $first_open && 0 === $index, $title_tag, $indicator );
			++$index;
		}

		echo '</div>';
	}
}
