<?php
/**
 * Nestable Table element.
 *
 * @package BricksExtras
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Nestable Table element class.
 */
class X_Nestable_Table extends \Bricks\Element {

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';
	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xnestabletable';
	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-layout-cta-btn-left';
	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '';
	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xNestableTable' );
	/**
	 * Element is nestable.
	 *
	 * @var bool
	 */
	public $nestable = true;


	/**
	 * Get element label.
	 */
	public function get_label() {
		return esc_html__( 'Nestable Table', 'bricksextras' );
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( 'table' );
	}

	/**
	 * Set control groups.
	 */
	public function set_control_groups() {

		$this->control_groups['header_group'] = array(
			'title' => esc_html__( 'Header', 'bricks' ) . ' (' . esc_html__( 'Styles', 'bricks' ) . ')',
			'tab'   => 'content',
		);

		$this->control_groups['rows_group'] = array(
			'title' => esc_html__( 'Table cell', 'bricks' ) . ' / ' . esc_html__( 'Row', 'bricks' ) . ' (' . esc_html__( 'Styles', 'bricks' ) . ')',
			'tab'   => 'content',
		);

		$this->control_groups['sticky_header_group'] = array(
			'title' => esc_html__( 'Sticky header', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['mobile_group'] = array(
			'title' => esc_html__( 'Stack vertically', 'bricksextras' ),
			'tab'   => 'content',
		);
	}

	/**
	 * Set element controls.
	 */
	public function set_controls() {

		$this->controls['table_layout'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Layout', 'bricks' ),
			'type'    => 'select',
			'inline'  => true,
			'options' => array(
				'auto'  => esc_html__( 'Auto', 'bricks' ),
				'fixed' => esc_html__( 'Fixed', 'bricks' ),
			),
			'css'     => array(
				array(
					'property' => 'table-layout',
				),
			),
		);

		/* header */

		$this->controls['header_bg'] = array(
			'tab'    => 'content',
			'label'  => esc_html__( 'Background', 'bricks' ),
			'group'  => 'header_group',
			'type'   => 'color',
			'inline' => true,
			'css'    => array(
				array(
					'property' => 'background-color',
					'selector' => 'th',
				),
				array(
					'property' => 'background-color',
					'selector' => '&.x-nestable-table_stacked td:before',
				),
			),
		);

			$this->controls['header_typography'] = array(
				'tab'   => 'content',
				'group' => 'header_group',
				'type'  => 'typography',
				'label' => esc_html__( 'Typography', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'font',
						'selector' => 'th',
					),
					array(
						'property' => 'font',
						'selector' => '&.x-nestable-table_stacked td:before',
					),
				),
			);

			$this->controls['header_padding'] = array(
				'tab'         => 'content',
				'group'       => 'header_group',
				'label'       => esc_html__( 'Padding', 'bricks' ),
				'type'        => 'spacing',
				'css'         => array(
					array(
						'property' => 'padding',
						'selector' => 'th',
					),
				),
				'placeholder' => array(
					'top'    => '14px',
					'right'  => '24px',
					'bottom' => '14px',
					'left'   => '24px',
				),
			);

			/* table rows */

			$this->controls['cell_borders'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Border color', 'bricks' ),
				'group'  => 'rows_group',
				'type'   => 'color',
				'inline' => true,
				'css'    => array(
					array(
						'property' => '--x-table-border-color',
						'selector' => '',
					),

				),
			);

			$this->controls['cell_borders_width'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Border width', 'bricks' ),
				'group'       => 'rows_group',
				'type'        => 'number',
				'units'       => true,
				'inline'      => true,
				'placeholder' => '1px',
				'small'       => true,
				'css'         => array(
					array(
						'property' => '--x-table-border-width',
						'selector' => '',
					),

				),
			);

			$this->controls['row_bg'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Background', 'bricks' ),
				'group'  => 'rows_group',
				'type'   => 'color',
				'inline' => true,
				'css'    => array(
					array(
						'property' => 'background-color',
						'selector' => 'td',
					),
				),
			);

			$this->controls['row_bg_even'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Background', 'bricks' ) . ' (' . esc_html__( 'Even', 'bricksextras' ) . ')',
				'group'  => 'rows_group',
				'type'   => 'color',
				'inline' => true,
				'css'    => array(
					array(
						'property' => 'background-color',
						'selector' => 'tr:nth-child(even) td',
					),
				),
			);

			$this->controls['row_color'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Text color', 'bricks' ),
				'group'  => 'rows_group',
				'type'   => 'color',
				'inline' => true,
				'css'    => array(
					array(
						'property' => 'color',
						'selector' => 'td',
					),
				),
			);

			$this->controls['row_color_even'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Text color', 'bricks' ) . ' (' . esc_html__( 'Even', 'bricksextras' ) . ')',
				'group'  => 'rows_group',
				'type'   => 'color',
				'inline' => true,
				'css'    => array(
					array(
						'property' => 'color',
						'selector' => '.tr:nth-child(even) td',
					),
				),
			);

			$this->controls['row_typography'] = array(
				'tab'   => 'content',
				'group' => 'rows_group',
				'type'  => 'typography',
				'label' => esc_html__( 'Typography', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'font',
						'selector' => 'td',
					),
				),
			);

			$this->controls['row_padding'] = array(
				'tab'         => 'content',
				'group'       => 'rows_group',
				'label'       => esc_html__( 'Padding', 'bricks' ),
				'type'        => 'spacing',
				'css'         => array(
					array(
						'property' => 'padding',
						'selector' => 'td',
					),
				),
				'placeholder' => array(
					'top'    => '14px',
					'right'  => '24px',
					'bottom' => '14px',
					'left'   => '24px',
				),
			);

			$this->controls['row_min_height'] = array(
				'tab'    => 'content',
				'label'  => esc_html__( 'Height', 'bricks' ) . ' (' . esc_html__( 'Row', 'bricks' ) . ')',
				'group'  => 'rows_group',
				'type'   => 'number',
				'units'  => true,
				'inline' => true,
				'css'    => array(
					array(
						'property' => 'height',
						'selector' => 'td',
					),
				),
			);

			/* sticky header */

			$this->controls['sticky_sep'] = array(
				'tab'   => 'style',
				'group' => 'sticky_header_group',
				'label' => esc_html__( 'Sticky header', 'bricks' ),
				'type'  => 'separator',
			);

			$this->controls['position'] = array(
				'tab'     => 'style',
				'group'   => 'sticky_header_group',
				'label'   => esc_html__( 'Position', 'bricks' ),
				'type'    => 'select',
				'options' => array(
					'sticky' => 'Sticky',
					'static' => 'Static',
				),
				'css'     => array(
					array(
						'property' => 'position',
						'selector' => 'thead:not(.x-nestable-table_stacked thead)',
					),
				),
				'inline'  => true,
			);

			$this->controls['top'] = array(
				'tab'         => 'style',
				'group'       => 'sticky_header_group',
				'label'       => esc_html__( 'Top', 'bricks' ),
				'type'        => 'number',
				'placeholder' => '0',
				'units'       => true,
				'css'         => array(
					array(
						'property' => 'top',
						'selector' => 'thead:not(.x-nestable-table_stacked thead)',
					),
				),
				'inline'      => true,
				'required'    => array( 'position', '=', 'sticky' ),
			);

			/* stacked */
			$breakpoint_options = array();

			foreach ( \Bricks\Breakpoints::$breakpoints as $breakpoint ) {
				$breakpoint_options[ $breakpoint['width'] ] = $breakpoint['label'] . ' (<= ' . $breakpoint['width'] . 'px )';
			}

			$breakpoint_options['false'] = 'None';

			$this->controls['maybeStack'] = array(
				'tab'         => 'content',
				'group'       => 'mobile_group',
				'label'       => esc_html__( 'Stack columns vertically at breakpoint', 'bricksextras' ),
				'type'        => 'select',
				'options'     => $breakpoint_options,
				'placeholder' => 'None',
			);

			$this->controls['stackRowGap'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Row gap', 'bricks' ),
				'group'       => 'mobile_group',
				'type'        => 'number',
				'inline'      => true,
				'placeholder' => '1em',
				'units'       => true,
				'css'         => array(
					array(
						'property' => 'gap',
						'selector' => '&.x-nestable-table_stacked tbody',
					),
				),
			);

			$this->controls['stackLabels'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Cell content on new line', 'bricksextras' ),
				'type'        => 'select',
				'group'       => 'mobile_group',
				'options'     => array(
					'true'  => esc_html__( 'True', 'bricks' ),
					'false' => esc_html__( 'False', 'bricks' ),
				),
				'inline'      => true,
				'small'       => false,
				'placeholder' => esc_html__( 'False', 'bricks' ),
			);

			$this->controls['stackLabelsSep'] = array(
				'tab'   => 'content',
				'type'  => 'separator',
				'label' => esc_html__( 'Column labels', 'bricksextras' ),
				'group' => 'mobile_group',
			);

			$this->controls['stackWidth'] = array(
				'tab'      => 'content',
				'label'    => esc_html__( 'Width', 'bricks' ),
				'group'    => 'mobile_group',
				'type'     => 'number',
				'min'      => 0,
				'max'      => 100,
				'step'     => 1,
				'inline'   => true,
				'units'    => true,
				'css'      => array(
					array(
						'property' => 'width',
						'selector' => '&:not([data-x-nestable-table*=stackLabels]).x-nestable-table_stacked td:before',
					),
				),
				'required' => array( 'stackLabels', '!=', 'true' ),
			);

			$this->controls['stackMinWidth'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Min. width', 'bricks' ),
				'group'       => 'mobile_group',
				'type'        => 'number',
				'min'         => 0,
				'max'         => 1000,
				'step'        => 1,
				'inline'      => true,
				'placeholder' => '150px',
				'units'       => true,
				'css'         => array(
					array(
						'property' => 'min-width',
						'selector' => '&:not([data-x-nestable-table*=stackLabels]).x-nestable-table_stacked td:before',
					),
				),
				'required'    => array( 'stackLabels', '!=', 'true' ),
			);

			$this->controls['alignTitle'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Align', 'bricks' ),
				'group'       => 'mobile_group',
				'inline'      => true,
				'placeholder' => esc_html__( 'Center', 'bricks' ),
				'type'        => 'select',
				'options'     => array(
					'flex-start' => 'flex-start',
					'center'     => esc_html__( 'Center', 'bricks' ),
					'flex-end'   => 'flex-end',
				),
				'css'         => array(
					array(
						'property' => 'align-items',
						'selector' => '&.x-nestable-table_stacked td:before',
					),
				),
				'required'    => array( 'stackLabels', '!=', 'true' ),
			);

			$this->controls['labelPadding'] = array(
				'tab'   => 'content',
				'label' => esc_html__( 'Padding', 'bricks' ),
				'group' => 'mobile_group',
				'type'  => 'spacing',
				'units' => true,
				'css'   => array(
					array(
						'property' => 'padding',
						'selector' => '&.x-nestable-table_stacked td:before',
					),
				),
			);

			$this->controls['cellsSep'] = array(
				'tab'   => 'content',
				'label' => esc_html__( 'Cells', 'bricksextras' ),
				'group' => 'mobile_group',
				'type'  => 'separator',
			);

			$this->controls['stackPadding'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Cell inline padding', 'bricksextras' ),
				'info'        => esc_html__( 'Padding behind the label', 'bricksextras' ),
				'group'       => 'mobile_group',
				'type'        => 'number',
				'min'         => 0,
				'max'         => 1000,
				'inline'      => true,
				'placeholder' => '150px',
				'units'       => true,
				'css'         => array(
					array(
						'property' => 'padding-inline-start',
						'selector' => '&:not([data-x-nestable-table*=stackLabels]).x-nestable-table_stacked td',
					),
				),
				'required'    => array( 'stackLabels', '!=', 'true' ),
			);

			$this->controls['stackCellTypography'] = array(
				'tab'   => 'content',
				'label' => esc_html__( 'Typography', 'bricks' ),
				'group' => 'mobile_group',
				'type'  => 'typography',
				'units' => true,
				'css'   => array(
					array(
						'property' => 'font',
						'selector' => '&.x-nestable-table_stacked td',
					),
				),
			);

			$this->controls['cellAlign'] = array(
				'tab'     => 'content',
				'label'   => esc_html__( 'Align', 'bricks' ),
				'group'   => 'mobile_group',
				'type'    => 'text-align',
				'units'   => true,
				'exclude' => array(
					'justify',
				),
				'css'     => array(
					array(
						'property' => 'text-align',
						'selector' => '&.x-nestable-table_stacked td',
					),
					array(
						'property' => 'align-items',
						'selector' => '&.x-nestable-table_stacked td',
						'value'    => 'flex-start',
						'required' => 'left',
					),
					array(
						'property' => 'align-items',
						'selector' => '&.x-nestable-table_stacked td',
						'value'    => 'center',
						'required' => 'center',
					),
					array(
						'property' => 'align-items',
						'selector' => '&.x-nestable-table_stacked td',
						'value'    => 'flex-end',
						'required' => 'right',
					),
				),
			);

			$this->controls['stackCellPadding'] = array(
				'tab'      => 'content',
				'label'    => esc_html__( 'Padding', 'bricks' ) . ' (' . esc_html__( 'Table cell', 'bricks' ) . ')',
				'group'    => 'mobile_group',
				'type'     => 'spacing',
				'units'    => true,
				'css'      => array(
					array(
						'property' => 'padding',
						'selector' => '&[data-x-nestable-table*=stackLabels].x-nestable-table_stacked td > span',
					),
				),
				'required' => array( 'stackLabels', '=', 'true' ),
			);
	}


	/**
	 * Enqueue scripts.
	 */
	public function enqueue_scripts() {

		if ( bricks_is_builder_main() ) {
			return;
		}

		wp_enqueue_script( 'x-nestable-table', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'nestabletable' ) . '.js', array( 'bricks-scripts' ), \BricksExtras\Plugin::VERSION, true );

		if ( ! \BricksExtras\Helpers::element_css_added( $this->name ) ) {
			wp_enqueue_style( 'x-nestable-table', BRICKSEXTRAS_URL . 'components/assets/css/nestabletable.css', array(), \BricksExtras\Plugin::VERSION );
		}
	}

	/**
	 * Render element output.
	 */
	public function render() {

		$settings = $this->settings;

		$stack_labels = isset( $settings['stackLabels'] ) ? $settings['stackLabels'] : 'false';

		$config = array(
			'stack' => isset( $settings['maybeStack'] ) ? $settings['maybeStack'] : 'false',
		);

		if ( 'true' === $stack_labels ) {
			$config += array(
				'stackLabels' => $stack_labels,
			);
		}

		$this->set_attribute( '_root', 'data-x-nestable-table', wp_json_encode( $config ) );

		$tag = ! BricksExtras\Helpers::maybe_preview() ? 'table' : 'div';

		$output = '';

		$output .= '<' . $tag . " {$this->render_attributes( '_root' )}>";
		$output .= \Bricks\Frontend::render_children( $this );
		$output .= '</' . $tag . '>';

		echo $output;
	}




	/**
	 * Get nestable children.
	 */
	public function get_nestable_children() {
		return array(
			array(
				'name'      => 'div',
				'label'     => esc_html__( 'Head', 'bricks' ),
				'deletable' => false,
				'cloneable' => false,
				'settings'  => array(
					'tag'       => 'custom',
					'customTag' => 'thead',
				),
				'children'  => array(
					array(
						'name'      => 'div',
						'label'     => esc_html__( 'Row', 'bricks' ),
						'deletable' => false,
						'cloneable' => false,
						'settings'  => array(
							'tag'       => 'custom',
							'customTag' => 'tr',
						),
						'children'  => array(
							array(
								'name'     => 'div',
								'label'    => esc_html__( 'Cell', 'bricksextras' ),
								'settings' => array(
									'tag'       => 'custom',
									'customTag' => 'th',
								),
								'children' => array(
									array(
										'name'     => 'text-basic',
										'settings' => array(
											'text' => 'Post title',
											'tag'  => 'span',
										),
									),
								),
							),
							array(
								'name'     => 'div',
								'label'    => esc_html__( 'Cell', 'bricksextras' ),
								'settings' => array(
									'tag'       => 'custom',
									'customTag' => 'th',
								),
								'children' => array(
									array(
										'name'     => 'text-basic',
										'settings' => array(
											'text' => 'Post date',
											'tag'  => 'span',
										),
									),
								),
							),
						),
					),
				),
			),
			array(
				'name'      => 'div',
				'label'     => esc_html__( 'Body', 'bricks' ),
				'deletable' => false,
				'cloneable' => false,
				'settings'  => array(
					'tag'       => 'custom',
					'customTag' => 'tbody',
				),
				'children'  => array(
					array(
						'name'     => 'div',
						'label'    => esc_html__( 'Row', 'bricks' ),
						'settings' => array(
							'tag'       => 'custom',
							'customTag' => 'tr',
						),
						'children' => array(
							array(
								'name'     => 'div',
								'label'    => esc_html__( 'Cell', 'bricksextras' ),
								'settings' => array(
									'tag'       => 'custom',
									'customTag' => 'td',
								),
								'children' => array(
									array(
										'name'     => 'text-basic',
										'settings' => array(
											'text' => '{post_title}',
											'tag'  => 'span',
										),
									),
								),
							),
							array(
								'name'     => 'div',
								'label'    => esc_html__( 'Cell', 'bricksextras' ),
								'settings' => array(
									'tag'       => 'custom',
									'customTag' => 'td',
								),
								'children' => array(
									array(
										'name'     => 'text-basic',
										'settings' => array(
											'text' => '{post_date}',
											'tag'  => 'span',
										),
									),
								),
							),
						),
					),
				),
			),
		);
	}
}
