<?php
namespace SabaiApps\Directories\Component\Display\Element;

use SabaiApps\Directories\Context;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Display\Model\Display;
use SabaiApps\Directories\Component\Display\Model\Element;

class ButtonElement extends AbstractElement {

	protected function _displayElementInfo( Bundle $bundle ) {
		return array(
			'type'             => 'content',
			'label'            => _x( 'Button', 'display element name', 'directories-pro' ),
			'description'      => __( 'Call to action button', 'directories-pro' ),
			'default_settings' => array(
				'size'           => '',
				'btn'            => true,
				'dropdown'       => false,
				'dropdown_icon'  => 'fas fa-cog',
				'dropdown_label' => '',
				'dropdown_right' => false,
				'separate'       => true,
				'arrangement'    => null,
				'tooltip'        => true,
				'buttons'        => array(),
			),
			'icon'             => 'far fa-hand-pointer',
			'inlineable'       => true,
			'headingable'      => true,
			'designable'       => array( 'margin' ),
		);
	}

	protected function _getButtonSizeOptions() {
		return array(
			'sm' => __( 'Small', 'directories-pro' ),
			''   => __( 'Medium', 'directories-pro' ),
			'lg' => __( 'Large', 'directories-pro' ),
		);
	}

	public function displayElementSettingsForm( Bundle $bundle, array $settings, Display $display, array $parents = array(), $tab = null, $isEdit = false, array $submitValues = array() ) {
		switch ( $tab ) {
			case 'buttons':
				return $this->_application->Display_Buttons_settingsForm( $bundle, $settings['buttons'], $display->name, $parents, array( 'general', 'settings', 'arrangement' ) );
			default:
				$options = $defaults = array();
				foreach ( array_keys( $this->_application->Display_Buttons( $bundle ) ) as $btn_name ) {
					if ( ! $btn = $this->_application->Display_Buttons_impl( $bundle, $btn_name, true ) ) {
						continue;
					}

					$info = $btn->displayButtonInfo( $bundle );
					if ( ! empty( $info['multiple'] ) ) {
						foreach ( $info['multiple'] as $_btn_name => $_btn_info ) {
							$_btn_name             = $btn_name . '-' . $_btn_name;
							$options[ $_btn_name ] = $_btn_info['label'];
							if ( ! empty( $_btn_info['default_checked'] ) ) {
								$defaults[] = $_btn_name;
							}
						}
					} else {
						$options[ $btn_name ] = $info['label'];
						if ( ! empty( $info['default_checked'] ) ) {
							$defaults[] = $btn_name;
						}
					}
				}
				return array(
					'#tabs'           => array(
						'buttons' => _x( 'Buttons', 'settings tab', 'directories-pro' ),
					),
					'size'            => array(
						'#type'          => 'select',
						'#title'         => __( 'Button size', 'directories-pro' ),
						'#options'       => $this->_getButtonSizeOptions(),
						'#horizontal'    => true,
						'#default_value' => $settings['size'],
					),
					'dropdown'        => array(
						'#type'          => 'checkbox',
						'#title'         => __( 'Display as single dropdown', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => ! empty( $settings['dropdown'] ),
						'#description'   => __( 'Individual button color settings will be ignored.', 'directories-pro' ),
					),
					'dropdown_icon'   => array(
						'#type'          => 'iconpicker',
						'#title'         => __( 'Dropdown icon', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => $settings['dropdown_icon'],
						'#states'        => $visible_if_dropdown = array(
							'visible' => array(
								sprintf( 'input[name="%s[dropdown]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
									'type'  => 'checked',
									'value' => true,
								),
							),
						),
					),
					'dropdown_label'  => array(
						'#type'          => 'textfield',
						'#title'         => __( 'Dropdown label', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => $settings['dropdown_label'],
						'#states'        => $visible_if_dropdown,
					),
					'dropdown_right'  => array(
						'#type'          => 'checkbox',
						'#title'         => __( 'Right align dropdown items', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => ! empty( $settings['dropdown_right'] ),
						'#states'        => $visible_if_dropdown,
					),
					'dropdown_up'     => array(
						'#type'          => 'checkbox',
						'#title'         => __( 'Display dropdown upwards', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => ! empty( $settings['dropdown_up'] ),
						'#states'        => $visible_if_dropdown,
					),
					'dropdown_center' => array(
						'#type'          => 'checkbox',
						'#title'         => __( 'Display dropdown centered above button', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => ! empty( $settings['dropdown_center'] ),
						'#states'        => $visible_if_dropdown = array(
							'visible' => array(
								sprintf( 'input[name="%s[dropdown]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
									'type'  => 'checked',
									'value' => true,
								),
								sprintf( 'input[name="%s[dropdown_right]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
									'type'  => 'checked',
									'value' => false,
								),
							),
						),
					),
					'separate'        => array(
						'#type'          => 'checkbox',
						'#title'         => __( 'Separate buttons', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => ! empty( $settings['separate'] ),
						'#states'        => array(
							'visible' => array(
								sprintf( 'input[name="%s[dropdown]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
									'type'  => 'checked',
									'value' => false,
								),
							),
						),
					),
					'tooltip'         => array(
						'#type'          => 'checkbox',
						'#title'         => __( 'Show tooltip if no label', 'directories-pro' ),
						'#horizontal'    => true,
						'#default_value' => ! empty( $settings['tooltip'] ),
						'#states'        => array(
							'visible' => array(
								sprintf( 'input[name="%s[dropdown]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
									'type'  => 'checked',
									'value' => false,
								),
							),
						),
					),
					'arrangement'     => array(
						'#type'          => 'sortablecheckboxes',
						'#title'         => __( 'Select buttons', 'directories-pro' ),
						'#horizontal'    => true,
						'#options'       => $options,
						'#default_value' => isset( $settings['arrangement'] ) ? $settings['arrangement'] : $defaults,
					),
				);
		}
	}

	protected function _displayElementSupports( Bundle $bundle, Display $display ) {
		if ( $display->type !== 'entity' ) {
			return false;
		}

		$buttons = $this->_application->Display_Buttons( $bundle );
		return ! empty( $buttons );
	}

	public function displayElementRender( Bundle $bundle, array $element, $var, ?array $context = null ) {
		$display_name = isset( $element['display'] ) ? $element['display'] : 'detailed';
		return $this->_application->Display_Buttons_renderButtons( $bundle, $element['settings'], $element['settings']['buttons'], $display_name, $var );
	}

	public function displayElementIsPreRenderable( Bundle $bundle, array &$element ) {
		foreach ( $element['settings']['arrangement'] as $btn_name ) {
			if ( ( $btn = $this->_application->Display_Buttons_impl( $bundle, $btn_name, true ) )
				&& ( $btn->displayButtonIsPreRenderable( $bundle, (array) @$element['settings']['buttons'][ $btn_name ]['settings'] ) )
			) {
				return true;
			}
		}
		return false;
	}

	public function displayElementPreRender( Bundle $bundle, array $element, &$var ) {
		foreach ( $element['settings']['arrangement'] as $btn_name ) {
			if ( ( $btn = $this->_application->Display_Buttons_impl( $bundle, $btn_name, true ) )
				&& ! empty( $element['settings']['buttons'][ $btn_name ]['settings'] )
				&& ( $btn->displayButtonIsPreRenderable( $bundle, $btn_settings = (array) $element['settings']['buttons'][ $btn_name ]['settings'] ) )
			) {
				$btn->displayButtonPreRender( $bundle, $btn_settings, $var['entities'] ?? array() );
			}
		}
	}

	public function displayElementOnCreate( Bundle $bundle, array &$data, $weight, Display $display, $elementName, $elementId ) {
		$this->_unsetDisabledButtonSettings( $data );
	}

	public function displayElementOnUpdate( Bundle $bundle, array &$data, Element $element ) {
		$this->_unsetDisabledButtonSettings( $data );
	}

	protected function _unsetDisabledButtonSettings( array &$data ) {
		if ( empty( $data['settings']['buttons'] ) ) {
			return;
		}

		foreach ( array_keys( $data['settings']['buttons'] ) as $btn_name ) {
			if ( ! in_array( $btn_name, $data['settings']['arrangement'] ) ) {
				unset( $data['settings']['buttons'][ $btn_name ] );
			}
		}
	}

	protected function _displayElementReadableInfo( Bundle $bundle, Element $element ) {
		$settings = $element->data['settings'];
		if ( empty( $settings['arrangement'] ) ) {
			return;
		}

		$ret = array(
			'buttons'     => array(
				'label' => __( 'Buttons', 'directories-pro' ),
				'value' => implode( ', ', $this->_application->Display_Buttons_buttonLabels( $bundle, $settings['arrangement'] ) ),
			),
			'button_size' => array(
				'label' => __( 'Button size', 'directories-pro' ),
				'value' => $this->_getButtonSizeOptions()[ $settings['size'] ],
			),
		);
		return array( 'settings' => array( 'value' => $ret ) );
	}
}
