<?php
/**
 * Widget Name: Advanced Table
 * Description: A flexible, accessible data table with five distinctive layouts —
 *              modern striped, minimal lines, bordered grid, soft cards (responsive
 *              stack) and a feature-comparison highlight table. Supports header icons,
 *              column alignment, a highlighted column, tick / cross / dash markers,
 *              optional client-side sorting, live search, sticky header and a mobile
 *              card stack. Only the selected style CSS file is loaded on the frontend.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.4.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_Box_Shadow;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Background;
use Elementor\Icons_Manager;

/**
 * Class Captwiki_Table
 *
 * @since 1.4.0
 */
class Captwiki_Table extends Widget_Base {

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

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

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

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

	/**
	 * Get widget keywords.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'table', 'data', 'grid', 'comparison', 'pricing', 'list', 'captain-widgets-kit' );
	}

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

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

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

	/**
	 * Selectable visual styles ( table-specific layouts ).
	 *
	 * @since 1.4.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Modern Striped', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Minimal Lines', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Bordered Grid', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Soft Cards', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Comparison Highlight', 'captain-widgets-kit' ),
		);
	}

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

		$this->register_table_style_controls();
		$this->register_header_style_controls();
		$this->register_body_style_controls();
		$this->register_highlight_style_controls();
		$this->register_toolbar_style_controls();
	}

	/**
	 * Content tab — columns repeater.
	 *
	 * @since 1.4.0
	 * @return void
	 */
	private function register_columns_controls(): void {

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

		$column = new Repeater();

		$column->add_control(
			'col_heading',
			array(
				'label'       => esc_html__( 'Heading', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Column', 'captain-widgets-kit' ),
				'label_block' => true,
				'dynamic'     => array( 'active' => true ),
			)
		);

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

		$column->add_control(
			'col_badge',
			array(
				'label'       => esc_html__( 'Badge Text', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => '',
				'label_block' => true,
				'description' => esc_html__( 'Optional small label shown under the heading ( e.g. "Most Popular" ).', 'captain-widgets-kit' ),
			)
		);

		$column->add_control(
			'col_align',
			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',
					),
				),
			)
		);

		$column->add_control(
			'col_highlight',
			array(
				'label'        => esc_html__( 'Highlight Column', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'No', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => '',
				'description'  => esc_html__( 'Make this column pop ( great for the recommended plan in a comparison table ).', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'columns',
			array(
				'label'       => esc_html__( 'Columns', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $column->get_controls(),
				'default'     => array(
					array( 'col_heading' => esc_html__( 'Feature', 'captain-widgets-kit' ) ),
					array( 'col_heading' => esc_html__( 'Starter', 'captain-widgets-kit' ) ),
					array(
						'col_heading'   => esc_html__( 'Pro', 'captain-widgets-kit' ),
						'col_badge'     => esc_html__( 'Most Popular', 'captain-widgets-kit' ),
						'col_highlight' => 'yes',
						'col_align'     => 'center',
					),
				),
				'title_field' => '{{{ col_heading }}}',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — rows repeater.
	 *
	 * @since 1.4.0
	 * @return void
	 */
	private function register_rows_controls(): void {

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

		$row = new Repeater();

		$row->add_control(
			'row_cells',
			array(
				'label'       => esc_html__( 'Cells', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXTAREA,
				'rows'        => 3,
				'default'     => '',
				'label_block' => true,
				'dynamic'     => array( 'active' => true ),
				'description' => esc_html__( 'Separate each cell with a vertical bar "|". Use :check: :cross: :dash: for tick / cross / dash marks. Basic HTML ( <strong>, <a>, <br> ) is allowed.', 'captain-widgets-kit' ),
			)
		);

		$row->add_control(
			'row_highlight',
			array(
				'label'        => esc_html__( 'Highlight Row', '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(
			'rows',
			array(
				'label'       => esc_html__( 'Rows', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::REPEATER,
				'fields'      => $row->get_controls(),
				'default'     => array(
					array( 'row_cells' => esc_html__( 'Unlimited Projects | :cross: | :check:', 'captain-widgets-kit' ) ),
					array( 'row_cells' => esc_html__( 'Priority Support | :dash: | :check:', 'captain-widgets-kit' ) ),
					array( 'row_cells' => esc_html__( 'Team Members | <strong>3</strong> | <strong>Unlimited</strong>', 'captain-widgets-kit' ) ),
					array( 'row_cells' => esc_html__( 'Monthly Price | $9 | $29', 'captain-widgets-kit' ) ),
				),
				'title_field' => '{{{ row_cells }}}',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Content tab — behaviour & layout settings.
	 *
	 * @since 1.4.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(
			'caption',
			array(
				'label'       => esc_html__( 'Table Caption', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => '',
				'label_block' => true,
				'description' => esc_html__( 'Optional title shown above the table ( improves accessibility ).', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'first_col_header',
			array(
				'label'        => esc_html__( 'First Cell as Row Header', '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',
				'description'  => esc_html__( 'Render each row\'s first cell as a header cell.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'enable_stripe',
			array(
				'label'        => esc_html__( 'Striped Rows', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'enable_hover',
			array(
				'label'        => esc_html__( 'Row Hover Highlight', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'sticky_header',
			array(
				'label'        => esc_html__( 'Sticky Header', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => '',
				'description'  => esc_html__( 'Keep the header visible while scrolling long tables.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'enable_sort',
			array(
				'label'        => esc_html__( 'Sortable Columns', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => '',
				'description'  => esc_html__( 'Visitors can click a heading to sort the rows.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'enable_search',
			array(
				'label'        => esc_html__( 'Live Search', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => '',
				'description'  => esc_html__( 'Show a search box that filters rows as the visitor types.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'search_placeholder',
			array(
				'label'     => esc_html__( 'Search Placeholder', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => esc_html__( 'Search…', 'captain-widgets-kit' ),
				'condition' => array( 'enable_search' => 'yes' ),
			)
		);

		$this->add_control(
			'responsive_stack',
			array(
				'label'        => esc_html__( 'Stack on Mobile', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'On', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Off', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
				'description'  => esc_html__( 'Turn each row into a labelled card on small screens.', 'captain-widgets-kit' ),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — table wrapper.
	 *
	 * @since 1.4.0
	 * @return void
	 */
	private function register_table_style_controls(): void {

		$this->start_controls_section(
			'section_table_style',
			array(
				'label' => esc_html__( 'Table', '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-table' => '--captwiki-table-accent: {{VALUE}};',
				),
				'description' => esc_html__( 'Drives the header, highlight column, sort arrows and check marks.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'check_color',
			array(
				'label'     => esc_html__( 'Check Mark Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-table__mark--check' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'cross_color',
			array(
				'label'     => esc_html__( 'Cross Mark Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-table__mark--cross' => 'color: {{VALUE}};',
				),
			)
		);

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

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

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

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

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

		$this->end_controls_section();
	}

	/**
	 * Style tab — header cells.
	 *
	 * @since 1.4.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'     => 'header_typography',
				'selector' => '{{WRAPPER}} .captwiki-table__th',
			)
		);

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

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

		$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-table__th' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

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

		$this->add_responsive_control(
			'header_icon_size',
			array(
				'label'      => esc_html__( 'Icon Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array( 'px' => array( 'min' => 8, 'max' => 48 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-table__th-icon' => 'font-size: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — body cells.
	 *
	 * @since 1.4.0
	 * @return void
	 */
	private function register_body_style_controls(): void {

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

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

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

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

		$this->add_control(
			'stripe_bg_color',
			array(
				'label'     => esc_html__( 'Striped Row Background', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-table--stripe .captwiki-table__tbody .captwiki-table__row:nth-child(even)' => 'background-color: {{VALUE}};',
				),
				'condition' => array( 'enable_stripe' => 'yes' ),
			)
		);

		$this->add_control(
			'hover_bg_color',
			array(
				'label'     => esc_html__( 'Hover Background', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-table--hover .captwiki-table__tbody .captwiki-table__row:hover' => 'background-color: {{VALUE}};',
				),
				'condition' => array( 'enable_hover' => 'yes' ),
			)
		);

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

		$this->add_control(
			'cell_border_color',
			array(
				'label'     => esc_html__( 'Border Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-table' => '--captwiki-table-border: {{VALUE}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Style tab — highlighted column.
	 *
	 * @since 1.4.0
	 * @return void
	 */
	private function register_highlight_style_controls(): void {

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

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

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

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

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

		$this->end_controls_section();
	}

	/**
	 * Style tab — search toolbar.
	 *
	 * @since 1.4.0
	 * @return void
	 */
	private function register_toolbar_style_controls(): void {

		$this->start_controls_section(
			'section_toolbar_style',
			array(
				'label'     => esc_html__( 'Search Box', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'enable_search' => 'yes' ),
			)
		);

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

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

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

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

		$this->end_controls_section();
	}

	/**
	 * Normalise the columns repeater into a clean, predictable structure.
	 *
	 * @since 1.4.0
	 * @param array $settings Widget settings.
	 * @return array List of column definitions.
	 */
	private function captwiki_get_columns( array $settings ): array {
		$columns = ! empty( $settings['columns'] ) && is_array( $settings['columns'] ) ? $settings['columns'] : array();
		$clean   = array();

		foreach ( $columns as $column ) {
			$clean[] = array(
				'heading'   => isset( $column['col_heading'] ) ? (string) $column['col_heading'] : '',
				'icon'      => isset( $column['col_icon'] ) ? $column['col_icon'] : array(),
				'badge'     => isset( $column['col_badge'] ) ? trim( (string) $column['col_badge'] ) : '',
				'align'     => isset( $column['col_align'] ) && $column['col_align'] ? $column['col_align'] : 'left',
				'highlight' => isset( $column['col_highlight'] ) && 'yes' === $column['col_highlight'],
			);
		}

		return $clean;
	}

	/**
	 * Replace the cell marker tokens with accessible mark spans.
	 *
	 * Tokens: :check: :cross: :dash:. The result is passed through wp_kses_post
	 * so admin-entered inline HTML stays safe.
	 *
	 * @since 1.4.0
	 * @param string $raw Raw cell text.
	 * @return string Safe HTML.
	 */
	private function captwiki_render_cell_content( string $raw ): string {
		$raw = trim( $raw );

		$tokens = array(
			':check:' => '<span class="captwiki-table__mark captwiki-table__mark--check" role="img" aria-label="' . esc_attr__( 'Yes', 'captain-widgets-kit' ) . '">&#10003;</span>',
			':cross:' => '<span class="captwiki-table__mark captwiki-table__mark--cross" role="img" aria-label="' . esc_attr__( 'No', 'captain-widgets-kit' ) . '">&#10005;</span>',
			':dash:'  => '<span class="captwiki-table__mark captwiki-table__mark--dash" role="img" aria-label="' . esc_attr__( 'Not applicable', 'captain-widgets-kit' ) . '">&#8211;</span>',
		);

		$raw = str_replace( array_keys( $tokens ), array_values( $tokens ), $raw );

		return wp_kses_post( $raw );
	}

	/**
	 * Render the table header row.
	 *
	 * @since 1.4.0
	 * @param array $columns  Column definitions.
	 * @param array $settings Widget settings.
	 * @return void
	 */
	private function captwiki_render_head( array $columns, array $settings ): void {
		$sortable   = 'yes' === $settings['enable_sort'];
		$show_icon  = true;

		echo '<thead class="captwiki-table__thead"><tr class="captwiki-table__head-row">';

		foreach ( $columns as $index => $column ) {
			$classes  = 'captwiki-table__th';
			$classes .= ' captwiki-table__th--' . $column['align'];
			$classes .= $column['highlight'] ? ' is-highlight' : '';

			$tag_attrs = ' scope="col"';

			if ( $sortable ) {
				$tag_attrs .= ' aria-sort="none" tabindex="0" role="columnheader" data-sort-index="' . esc_attr( $index ) . '"';
				$classes   .= ' captwiki-table__th--sortable';
			}

			echo '<th class="' . esc_attr( $classes ) . '"' . $tag_attrs . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

			echo '<span class="captwiki-table__th-inner">';

			if ( $show_icon && ! empty( $column['icon']['value'] ) ) {
				echo '<span class="captwiki-table__th-icon" aria-hidden="true">';
				Icons_Manager::render_icon( $column['icon'], array( 'aria-hidden' => 'true' ) );
				echo '</span>';
			}

			echo '<span class="captwiki-table__th-label">' . esc_html( $column['heading'] ) . '</span>';

			if ( $sortable ) {
				echo '<span class="captwiki-table__sort-arrow" aria-hidden="true"></span>';
			}

			echo '</span>';

			if ( '' !== $column['badge'] ) {
				echo '<span class="captwiki-table__badge">' . esc_html( $column['badge'] ) . '</span>';
			}

			echo '</th>';
		}

		echo '</tr></thead>';
	}

	/**
	 * Render a single body row.
	 *
	 * @since 1.4.0
	 * @param array $row      Row repeater item.
	 * @param array $columns  Column definitions.
	 * @param array $settings Widget settings.
	 * @return void
	 */
	private function captwiki_render_row( array $row, array $columns, array $settings ): void {
		$raw_cells    = isset( $row['row_cells'] ) ? (string) $row['row_cells'] : '';
		$cells        = array_map( 'trim', explode( '|', $raw_cells ) );
		$col_count    = count( $columns );
		$first_header = 'yes' === $settings['first_col_header'];
		$row_class    = 'captwiki-table__row';
		$row_class   .= ( isset( $row['row_highlight'] ) && 'yes' === $row['row_highlight'] ) ? ' is-highlight-row' : '';

		echo '<tr class="' . esc_attr( $row_class ) . '">';

		for ( $index = 0; $index < $col_count; $index++ ) {
			$column   = $columns[ $index ];
			$value    = isset( $cells[ $index ] ) ? $cells[ $index ] : '';
			$content  = $this->captwiki_render_cell_content( $value );

			$classes  = 'captwiki-table__cell';
			$classes .= ' captwiki-table__cell--' . $column['align'];
			$classes .= $column['highlight'] ? ' is-highlight' : '';

			$label_attr = ' data-label="' . esc_attr( $column['heading'] ) . '"';

			if ( 0 === $index && $first_header ) {
				echo '<th scope="row" class="' . esc_attr( $classes . ' captwiki-table__cell--rowhead' ) . '"' . $label_attr . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				echo '</th>';
			} else {
				echo '<td class="' . esc_attr( $classes ) . '"' . $label_attr . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				echo '</td>';
			}
		}

		echo '</tr>';
	}

	/**
	 * Render the optional search toolbar.
	 *
	 * @since 1.4.0
	 * @param array  $settings Widget settings.
	 * @param string $base_id  Widget instance id base.
	 * @return void
	 */
	private function captwiki_render_toolbar( array $settings, string $base_id ): void {
		if ( 'yes' !== $settings['enable_search'] ) {
			return;
		}

		$placeholder = isset( $settings['search_placeholder'] ) ? $settings['search_placeholder'] : esc_html__( 'Search…', 'captain-widgets-kit' );
		$input_id    = $base_id . '-search';

		echo '<div class="captwiki-table__toolbar">';
		echo '<label class="captwiki-table__search-label" for="' . esc_attr( $input_id ) . '">';
		echo '<span class="captwiki-table__search-icon" aria-hidden="true">';
		echo '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><path d="M21 21l-4.35-4.35"></path></svg>';
		echo '</span>';
		echo '<input type="search" id="' . esc_attr( $input_id ) . '" class="captwiki-table__search" placeholder="' . esc_attr( $placeholder ) . '" aria-label="' . esc_attr__( 'Search table', 'captain-widgets-kit' ) . '">';
		echo '</label>';
		echo '</div>';
	}

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

		$columns = $this->captwiki_get_columns( $settings );
		$rows    = ! empty( $settings['rows'] ) && is_array( $settings['rows'] ) ? $settings['rows'] : array();

		if ( empty( $columns ) || empty( $rows ) ) {
			return;
		}

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

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

		$base_id   = 'captwiki-table-' . $this->get_id();
		$unique    = 'captwiki-widget-' . $this->get_id();
		$caption   = isset( $settings['caption'] ) ? trim( (string) $settings['caption'] ) : '';

		$wrap_class  = 'captwiki-table captwiki-' . $style . ' ' . $unique;
		$wrap_class .= 'yes' === $settings['enable_stripe'] ? ' captwiki-table--stripe' : '';
		$wrap_class .= 'yes' === $settings['enable_hover'] ? ' captwiki-table--hover' : '';
		$wrap_class .= 'yes' === $settings['sticky_header'] ? ' captwiki-table--sticky' : '';
		$wrap_class .= 'yes' === $settings['responsive_stack'] ? ' captwiki-table--stack' : '';
		$wrap_class .= 'yes' === $settings['enable_sort'] ? ' captwiki-table--sortable' : '';

		$data_attrs  = 'yes' === $settings['enable_sort'] ? ' data-sortable="true"' : '';
		$data_attrs .= 'yes' === $settings['enable_search'] ? ' data-searchable="true"' : '';

		echo '<div class="' . esc_attr( $wrap_class ) . '"' . $data_attrs . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

			$this->captwiki_render_toolbar( $settings, $base_id );

			echo '<div class="captwiki-table__scroll">';
			echo '<table class="captwiki-table__table">';

		if ( '' !== $caption ) {
			echo '<caption class="captwiki-table__caption">' . esc_html( $caption ) . '</caption>';
		}

			$this->captwiki_render_head( $columns, $settings );

			echo '<tbody class="captwiki-table__tbody">';

		foreach ( $rows as $row ) {
			if ( is_array( $row ) ) {
				$this->captwiki_render_row( $row, $columns, $settings );
			}
		}

			echo '</tbody>';
			echo '</table>';
			echo '</div>';

		if ( 'yes' === $settings['enable_search'] ) {
			echo '<p class="captwiki-table__empty" hidden>' . esc_html__( 'No matching results found.', 'captain-widgets-kit' ) . '</p>';
		}

		echo '</div>';
	}
}
