<?php
namespace SabaiApps\Directories\Component\System\Helper;

use SabaiApps\Directories\Application;

/**
 * ButtonHelper provides various utility methods for button manipulation.
 */
class ButtonHelper {

	/**
	 * Renders an array of links as buttons or button groups.
	 *
	 * @param Application $application
	 * @param array|null  $links
	 * @param array       $options
	 * @return string
	 */
	public function links( Application $application, ?array $links = null, $options = array() ) {
		if ( empty( $links ) ) {
			return '';
		}

		$options  += array(
			'size'           => null,
			'label'          => false,
			'separator'      => PHP_EOL,
			'group'          => false,
			'right'          => false,
			'color'          => null,
			'class'          => '',
			'btn'            => true,
			'group_children' => false,
			'tooltip'        => false,
		);
		$btn_class = DRTS_BS_PREFIX . 'btn';
		foreach ( array_keys( $links ) as $i ) {
			// Show dropdowns if multiple links
			if ( is_array( $links[ $i ] ) ) {
				if ( count( $links[ $i ] ) > 1 ) {
					if ( $options['group_children'] ) {
						$links[ $i ] = $application->System_Button_links(
							$links[ $i ],
							array(
								'group'     => true,
								'separator' => '',
							) + $options
						);
					} else {
						$links[ $i ] = $application->System_Button_dropdownLinks( $links[ $i ], $options );
					}
					continue;
				} else {
					$links[ $i ] = array_shift( $links[ $i ] );
				}
			} elseif ( is_string( $links[ $i ] ) ) {
				continue;
			}
			$link = $links[ $i ];
			// Single link
			$class = $btn_class;
			if ( $options['size'] ) {
				$class .= ' ' . $btn_class . '-' . $options['size'];
			}
			if ( $options['color'] ) {
				$class .= ' ' . $btn_class . '-' . $options['color'];
			}
			if ( $_class = $link->getAttribute( 'class' ) ) {
				$class .= ' ' . $_class;
			}
			if ( null === $link->getBtn() ) {
				$link->setBtn( $options['btn'] );
			}
			$link->setAttribute( 'class', $class );
			if ( $options['tooltip'] ) {
				if ( $rel = $link->getAttribute( 'rel' ) ) {
					$rel .= ' sabaitooltip';
				} else {
					$rel = 'sabaitooltip';
				}
				$link->setAttribute( 'rel', $rel );
				// Use label as tooltip if no title is set
				if ( ! $options['label'] && ! $link->getAttribute( 'title' ) ) {
					$link->setAttribute( 'title', strip_tags( $link->getLabel() ) );
				}
				if ( is_int( $options['tooltip'] ) ) {
					$link->setAttribute( 'data-bs-offset', '[0, ' . $options['tooltip'] . ']' );
				}
			}
			if ( ! $options['label'] ) {
				$link->setLabel( '' );
			}
		}
		$buttons = implode( $options['separator'], $links );
		if ( ! $options['group'] ) {
			return $buttons;
		}

		return '<div class="' . $btn_class . '-group ' . $options['class'] . '">' . $buttons . '</div>';
	}

	/**
	 * Renders an array of links as a button toolbar.
	 *
	 * @param Application $application
	 * @param array       $links
	 * @param array       $options
	 * @return string
	 */
	public function toolbar( Application $application, array $links, array $options = array() ) {
		$options       += array(
			'tooltip'   => false,
			'label'     => true,
			'separator' => PHP_EOL,
			'class'     => DRTS_BS_PREFIX . 'd-inline-flex ' . DRTS_BS_PREFIX . 'justify-content-center ' . DRTS_BS_PREFIX . 'justify-content-sm-start',
		);
		$margin_x_class = DRTS_BS_PREFIX . 'me-2 ' . DRTS_BS_PREFIX . 'mb-2 ' . DRTS_BS_PREFIX . 'mb-sm-none';
		foreach ( array_keys( $links ) as $i ) {
			if ( is_string( $links[ $i ] ) ) {
				continue;
			}

			$is_first    = ! isset( $is_first );
			$links[ $i ] = $application->System_Button_links(
				array( $links[ $i ] ),
				array(
					'separator' => PHP_EOL,
					'group'     => true,
					'class'     => $margin_x_class,
				) + $options
			);
		}
		return '<div class="' . DRTS_BS_PREFIX . 'btn-toolbar ' . $options['class'] . '">' . implode( $options['separator'], $links ) . '</div>';
	}

	/**
	 * Renders an array of links as a dropdown button group.
	 *
	 * @param Application $application
	 * @param array|null  $links
	 * @param array       $options
	 * @return string
	 */
	public function dropdownLinks( Application $application, ?array $links = null, array $options = array() ) {
		if ( empty( $links ) ) {
			return '';
		}

		$options += array(
			'size'             => null,
			'label'            => true,
			'separator'        => PHP_EOL,
			'right'            => false,
			'up'               => false,
			'center'           => false,
			'format'           => null,
			'format_no_escape' => false,
			'color'            => null,
			'class'            => '',
			'split'            => false,
			'btn'              => true,
			'tooltip'          => false,
		);

		$dropdown_links      = array();
		$dropdown_link_class = DRTS_BS_PREFIX . 'dropdown-item';
		$i                   = 0;
		foreach ( $links as $link ) {
			if ( is_array( $link ) ) {
				$first_link = array_shift( $link );
				foreach ( $link as $_link ) {
					if ( ! $_link->isActive() || isset( $current ) ) {
						if ( ! $_link->getIcon() && $first_link->getIcon() ) {
							$_link->setIcon( $first_link->getIcon() );
						}
						if ( $first_link->getLabel() ) {
							$_link->setLabel( $first_link->getLabel() . ' - ' . $_link->getLabel() );
						}
						if ( null === $_link->getBtn() ) {
							$_link->setBtn( $options['btn'] );
						}
						$_link->setAttribute( 'title', '' );
						$dropdown_links[ $i ] = $_link;
						$dropdown_links[ $i ]->setAttribute( 'class', ( $class = $_link->getAttribute( 'class' ) ) ? $dropdown_link_class . ' ' . $class : $dropdown_link_class );
						++$i;
						continue;
					}
					$current = $this->_markCurrent( $application, $_link, $options );
				}
			} elseif ( is_string( $link ) ) {
				// Divider
				$dropdown_links[ $i ] = '<div class="' . DRTS_BS_PREFIX . 'dropdown-divider"></div>';
				++$i;
			} else {
				if ( ! $link->isActive() || isset( $current ) ) {
					if ( null === $link->getBtn() ) {
						$link->setBtn( $options['btn'] );
					}
					// $link->setAttribute('title', '');
					$dropdown_links[ $i ] = $link;
					$dropdown_links[ $i ]->setAttribute( 'class', ( $class = $link->getAttribute( 'class' ) ) ? $dropdown_link_class . ' ' . $class : $dropdown_link_class );
					++$i;
					continue;
				}
				$current = $this->_markCurrent( $application, $link, $options );
			}
		}
		if ( ! isset( $current ) ) { // this should not happen if there is at least one active link
			$first_link = array_shift( $links );
			$current    = $this->_markCurrent( $application, is_array( $first_link ) ? $first_link[1] : $first_link, $options );
			array_shift( $dropdown_links );
		}
		if ( $options['split'] ) {
			$current .= $application->LinkTo(
				'<span class="' . DRTS_BS_PREFIX . 'visually-hidden">Toggle Dropdown</span>',
				'',
				array(
					'btn'       => true,
					'no_escape' => true,
				),
				array( 'class' => $current->getAttribute( 'class' ) . ' ' . DRTS_BS_PREFIX . 'dropdown-toggle ' . DRTS_BS_PREFIX . 'dropdown-split' )
			)->setAttribute( 'data-bs-toggle', 'dropdown' );
		}
		$dropdown_class = DRTS_BS_PREFIX . 'dropdown-menu';
		if ( $options['right'] ) {
			$dropdown_class .= ' ' . DRTS_BS_PREFIX . 'dropdown-menu-end';
		}
		if ( $options['up'] ) {
			$options['class'] .= ' ' . DRTS_BS_PREFIX . 'dropup';
			if ( ! $options['right']
				&& $options['center']
			) {
				$options['class'] .= ' ' . DRTS_BS_PREFIX . 'dropup-center';
			}
		} elseif ( ! $options['right']
				&& $options['center']
			) {

				$options['class'] .= ' ' . DRTS_BS_PREFIX . 'dropdown-center';
		}
		return '<div class="' . DRTS_BS_PREFIX . 'btn-group ' . trim( $options['class'] ) . '">' . $current . '<div class="' . $dropdown_class . '">'
			. implode( PHP_EOL, $dropdown_links ) . '</div></div>';
	}

	/**
	 * Marks the current link as active and sets its attributes.
	 *
	 * @param Application $application
	 * @param mixed       $link
	 * @param array       $options
	 * @return mixed
	 */
	private function _markCurrent( Application $application, $link, array $options ) {
		$class = DRTS_BS_PREFIX . 'btn';
		if ( ! $options['split'] ) {
			$class .= ' ' . DRTS_BS_PREFIX . 'dropdown-toggle';
			$link->setActive( false )
				->setAttribute( 'onclick', '' )
				->setAttribute( 'data-bs-toggle', 'dropdown' );
		}
		if ( $options['size'] ) {
			$class .= ' ' . DRTS_BS_PREFIX . 'btn-' . $options['size'];
		}
		if ( $options['color'] ) {
			$class .= ' ' . DRTS_BS_PREFIX . 'btn-' . $options['color'];
		}
		if ( $_class = $link->getAttribute( 'class' ) ) {
			$class .= ' ' . $_class;
		}
		if ( $options['tooltip'] ) {
			if ( $rel = $link->getAttribute( 'rel' ) ) {
				$rel .= ' sabaitooltip';
			} else {
				$rel = 'sabaitooltip';
			}
			$link->setAttribute( 'rel', $rel );
			// Use label as tooltip if no title is set
			if ( ! $options['label'] && ! $link->getAttribute( 'title' ) ) {
				$link->setAttribute( 'title', strip_tags( $link->getLabel() ) );
			}
			if ( is_int( $options['tooltip'] ) ) {
				$link->setAttribute( 'data-bs-offset', '[0, ' . $options['tooltip'] . ']' );
			}
		}
		if ( $options['label'] || isset( $options['format'] ) ) {
			$label  = $link->isNoEscape() ? $link->getLabel() : $application->H( $link->getLabel() );
			$format = isset( $options['format'] ) ? ( empty( $options['format_no_escape'] ) ? $application->H( $options['format'] ) : $options['format'] ) : '%s';
			$link->setLabel( sprintf( $format, $label ), false );
		} else {
			$link->setLabel( '', false );
		}
		return $link->setBtn( true )->setAttribute( 'class', trim( str_replace( DRTS_BS_PREFIX . 'dropdown-item', '', $class ) ) );
	}

	/**
	 * Returns the Bootstrap button HTML class for given options.
	 *
	 * @param Application $application
	 * @param array       $options
	 * @param string      $color
	 * @param bool        $primary
	 * @return string
	 */
	public function htmlClass( Application $application, array $options, $color = '', $primary = false ) {
		$class = DRTS_BS_PREFIX . 'btn';
		if ( isset( $options['size'] ) ) {
			$class .= ' ' . DRTS_BS_PREFIX . 'btn-' . $options['size'];
		}
		if ( ! isset( $options['color'] ) ) {
			$color = $this->color( $application, $color, $primary );
		} else {
			$color = $options['color'];
		}
		$class .= ' ' . DRTS_BS_PREFIX . 'btn-' . $color;

		return $class;
	}

	/**
	 * Returns the Bootstrap button color for given options.
	 *
	 * @param Application $application
	 * @param string      $color
	 * @param bool        $primary
	 * @return string
	 */
	public function color( Application $application, $color = '', $primary = false ) {
		if ( $primary ) {
			switch ( $color ) {
				case 'primary':
					return 'outline-light';
				default:
					return 'outline-primary';
			}
		}
		switch ( $color ) {
			case 'primary':
			case 'secondary':
			case 'info':
			case 'success':
			case 'warning':
			case 'danger':
				return 'outline-light';
			default:
				return 'outline-secondary';
		}
	}
}
