<?php
namespace SabaiApps\Directories\Component\Entity\DisplayElement;

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

class ChildTermsDisplayElement extends Display\Element\AbstractElement {

	protected function _displayElementInfo( Bundle $bundle ) {
		return array(
			'type'             => 'content',
			'label'            => _x( 'Child Terms', 'display element name', 'directories-pro' ),
			'description'      => __( 'Display child terms of current taxonomy term', 'directories-pro' ),
			'default_settings' => array(
				'hide_empty'          => false,
				'show_count'          => true,
				'show_count_as_badge' => true,
				'content_bundle_type' => null,
				'child_count'         => 0,
				'columns'             => 1,
				'inline'              => true,
				'dropdown'            => false,
				'separator'           => ', ',
			),
			'icon'             => 'fas fa-list',
			'cacheable'        => true,
			'designable'       => array( 'margin', 'padding' ),
		);
	}

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

	public function displayElementSettingsForm( Bundle $bundle, array $settings, Display\Model\Display $display, array $parents = array(), $tab = null, $isEdit = false, array $submitValues = array() ) {
		$form = array(
			'child_count' => array(
				'#type'          => 'slider',
				'#title'         => __( 'Number of child terms to display', 'directories-pro' ),
				'#default_value' => $settings['child_count'],
				'#min_text'      => __( 'Unlimited', 'directories-pro' ),
				'#min_value'     => 0,
				'#max_value'     => 10,
				'#horizontal'    => true,
			),
			'inline'      => array(
				'#title'         => __( 'Display inline', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['inline'] ),
				'#horizontal'    => true,
			),
			'dropdown'    => array(
				'#title'         => __( 'Display dropdown', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['dropdown'] ),
				'#horizontal'    => true,
				'#states'        => array(
					'visible' => array(
						$inline_selector = sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'inline' ) ) ) ) => array(
							'type'  => 'checked',
							'value' => false,
						),
					),
				),
			),
			'columns'     => array(
				'#type'          => 'select',
				'#options'       => array(
					1  => 1,
					2  => 2,
					3  => 3,
					4  => 4,
					6  => 6,
					12 => 12,
				),
				'#title'         => __( 'Number of columns', 'directories-pro' ),
				'#default_value' => $settings['columns'],
				'#horizontal'    => true,
				'#states'        => array(
					'visible' => array(
						sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'dropdown' ) ) ) ) => array(
							'type'  => 'checked',
							'value' => false,
						),
					),
				),
			),
			'separator'   => array(
				'#title'         => __( 'Separator', 'directories-pro' ),
				'#type'          => 'textfield',
				'#default_value' => $settings['separator'],
				'#horizontal'    => true,
				'#states'        => array(
					'visible' => array(
						$inline_selector => array(
							'type'  => 'checked',
							'value' => true,
						),
					),
				),
				'#no_trim'       => true,
			),
			'hide_empty'  => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Hide empty terms', 'directories-pro' ),
				'#default_value' => ! empty( $settings['hide_empty'] ),
				'#horizontal'    => true,
			),
		);
		if ( ( $content_bundle_name = $this->_application->Entity_TaxonomyContentBundleTypes( $bundle->type, $bundle->group ) )
			&& ( $content_bundle = $this->_application->Entity_Bundle( $content_bundle_name ) )
		) {
			$form['show_count']          = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show post count', 'directories-pro' ),
				'#default_value' => ! empty( $settings['show_count'] ),
				'#horizontal'    => true,
			);
			$form['content_bundle_type'] = array(
				'#type'  => 'hidden',
				'#value' => $content_bundle->type,
			);
			$form['show_count_as_badge'] = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show post count as badge', 'directories-pro' ),
				'#default_value' => ! isset( $settings['show_count_as_badge'] ) || ! empty( $settings['show_count_as_badge'] ),
				'#horizontal'    => true,
				'#states'        => array(
					'visible' => array(
						sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'show_count' ) ) ) ) => array(
							'type'  => 'checked',
							'value' => true,
						),
						sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'dropdown' ) ) ) ) => array(
							'type'  => 'checked',
							'value' => false,
						),
					),
				),
			);
		}
		$form += $this->_application->System_Icon_settingsForm( $bundle, $settings, $parents );

		return $form;
	}

	public function displayElementRender( Bundle $bundle, array $element, $var, ?array $context = null ) {
		$html = array();
		if ( ! isset( $var->data['child_terms'] )
			|| ( ! $count = count( $var->data['child_terms'] ) )
		) {
			return '';
		}

		$settings    = $element['settings'];
		$child_terms = $var->data['child_terms'];
		// Hide empty terms?
		if ( ! empty( $settings['hide_empty'] ) ) {
			foreach ( array_keys( $child_terms ) as $key ) {
				if ( ! $child_terms[ $key ]->getSingleFieldValue( 'entity_term_content_count', '_all' ) ) {
					unset( $child_terms[ $key ] );
				}
			}
		}

		if ( ! empty( $settings['child_count'] ) ) {
			if ( count( $child_terms ) > $settings['child_count'] ) {
				$child_terms = array_slice( $child_terms, 0, $settings['child_count'] );
				$has_more    = true;
			}
		}
		$span                     = intval( 12 / $settings['columns'] );
		$div_class                = DRTS_BS_PREFIX . 'row';
		$original_taxonomy_bundle = isset( $context['original_taxonomy_bundle'] ) ? $context['original_taxonomy_bundle'] : null;
		if ( empty( $settings['inline'] ) ) {
			if ( empty( $settings['dropdown'] ) ) {
				$permalink_options = $this->_application->System_Icon_settingsToPermalinkOptions( $bundle, $settings );
				foreach ( $this->_application->System_Util_sliceArray( $child_terms, $settings['columns'] ) as $columns ) {
					$li = array();
					foreach ( $columns as $term ) {
						$li[] = '<li>' . $this->_getTermTitle( $bundle, $term, $settings, $permalink_options, $original_taxonomy_bundle ) . '</li>';
					}
					if ( ! empty( $li ) ) {
						$html[] = '<div class="' . DRTS_BS_PREFIX . 'col-sm-' . $span . '"><ul class="drts-display-list">';
						$html[] = implode( PHP_EOL, $li );
						$html[] = '</ul></div>';
					}
				}
			} else {
				$div_class      = 'drts-row';
				$options        = array();
				$content_bundle = $this->_application->Entity_Bundle( $settings['content_bundle_type'], $original_taxonomy_bundle ? $original_taxonomy_bundle->group : $taxonomy_bundle->group );
				foreach ( $child_terms as $term ) {
					$title = $term->getTitle();
					if ( ! empty( $settings['show_count'] )
						&& $content_bundle
					) {
						$count = (int) $term->getSingleFieldValue( 'entity_term_content_count', '_' . $content_bundle->name );
						$title = sprintf( '%s (%s)', $title, $count );
					}
					$options[] = '<option value="' . $this->_application->H( $this->_application->Entity_PermalinkUrl( $term, '', null, array(), $original_taxonomy_bundle ) ) . '">' . $this->_application->H( $title ) . '</option>';
				}
				if ( ! empty( $options ) ) {
					$html[] = '<div class="drts-col-lg-6"><select class="' . DRTS_BS_PREFIX . 'form-select" onchange="location.href=this.value">';
					$html[] = '<option value="">' . $this->_application->H( __( '— Select —', 'directories-pro' ) ) . '</option>';
					$html[] = implode( PHP_EOL, $options );
					$html[] = '</select></div>';
				}
			}
		} else {
			$permalink_options = $this->_application->System_Icon_settingsToPermalinkOptions( $bundle, $settings );
			foreach ( $this->_application->System_Util_sliceArray( $child_terms, $settings['columns'] ) as $columns ) {
				$li = array();
				foreach ( $columns as $term ) {
					$li[] = '<span>' . $this->_getTermTitle( $bundle, $term, $settings, $permalink_options, $original_taxonomy_bundle ) . '</span>';
				}
				if ( ! empty( $li ) ) {
					if ( ! empty( $has_more ) ) {
						$li[] = '...';
					}
					$html[] = '<div class="' . DRTS_BS_PREFIX . 'col-sm-' . $span . '"><span>';
					$html[] = implode( $settings['separator'], $li );
					$html[] = '</span></div>';
				}
			}
		}

		return empty( $html ) ? '' : '<div class="' . $div_class . '">' . implode( PHP_EOL, $html ) . '</div>';
	}

	protected function _getTermTitle( Bundle $bundle, Entity\Type\IEntity $term, array $settings, array $permalinkOptions, $originalTaxonomyBundle = null ) {
		$title = $this->_application->Entity_Permalink( $term, $permalinkOptions, '', null, $originalTaxonomyBundle );
		if ( empty( $settings['show_count'] )
			|| empty( $settings['content_bundle_type'] )
			|| ( ! $content_bundle = $this->_application->Entity_Bundle( $settings['content_bundle_type'], $originalTaxonomyBundle ? $originalTaxonomyBundle->group : $bundle->group ) )
		) {
			return $title;
		}

		$count = (int) $term->getSingleFieldValue( 'entity_term_content_count', '_' . $content_bundle->name );
		if ( isset( $settings['show_count_as_badge'] )
			&& empty( $settings['show_count_as_badge'] )
		) {
			return $title . ' <span style="vertical-align:middle">(' . $count . ')</span>';
		}
		return sprintf(
			'%1$s <span class="drts-display-list-badge %2$sbadge %2$sbadge-pill %2$stext-bg-light">%3$d</span>',
			$title,
			DRTS_BS_PREFIX,
			$count
		);
	}

	public function displayElementIsPreRenderable( Bundle $bundle, array &$element ) {
		return true;
	}

	public function displayElementPreRender( Bundle $bundle, array $element, &$var ) {
		if ( empty( $var['entities'] ) ) {
			return;
		}

		$entity_ids = array_keys( $var['entities'] );
		// Get child terms
		$child_terms = $child_terms_by_parent = array();
		$load_fields = ! empty( $element['settings']['icon'] )
			|| ( ! empty( $element['settings']['show_count'] ) && ! empty( $element['settings']['content_bundle_name'] ) );
		$terms       = $this->_application->Entity_Query( $bundle->entitytype_name )->fieldIsIn( 'parent', $entity_ids );
		$this->_application->Entity_TaxonomyTerms_sort( $terms, $bundle );
		foreach ( $terms->fetch( 0, 0, $load_fields ) as $child_term ) {
			$child_terms[ $child_term->getParentId() ][ $child_term->getId() ] = $child_term;
		}
		if ( empty( $child_terms ) ) {
			return;
		}

		foreach ( array_keys( $var['entities'] ) as $entity_id ) {
			if ( ! empty( $child_terms[ $entity_id ] ) ) {
				usort(
					$child_terms[ $entity_id ],
					function ( $a, $b ) {
						return strcasecmp( $a->getTitle(), $b->getTitle() );
					}
				);
				$var['entities'][ $entity_id ]->data['child_terms'] = $child_terms[ $entity_id ];
			} else {
				$var['entities'][ $entity_id ]->data['child_terms'] = array();
			}
		}
	}

	protected function _displayElementReadableInfo( Entity\Model\Bundle $bundle, Display\Model\Element $element ) {
		$settings = $element->data['settings'];
		$ret      = array(
			'child_count' => array(
				'label' => __( 'Number of child terms to display', 'directories-pro' ),
				'value' => empty( $settings['child_count'] ) ? __( 'Unlimited', 'directories-pro' ) : $settings['child_count'],
			),
			'icon'        => array(
				'label'   => __( 'Show icon', 'directories-pro' ),
				'value'   => ! empty( $settings['icon'] ),
				'is_bool' => true,
			),
			'inline'      => array(
				'label'   => __( 'Display inline', 'directories-pro' ),
				'value'   => ! empty( $settings['inline'] ),
				'is_bool' => true,
			),
		);
		if ( ! empty( $settings['dropdown'] ) ) {
			$ret['dropdown'] = array(
				'label'   => __( 'Display dropdown', 'directories-pro' ),
				'value'   => ! empty( $settings['dropdown'] ),
				'is_bool' => true,
			);
		} else {
			if ( ! empty( $settings['inline'] ) ) {
				$ret['inline'] = array(
					'label'   => __( 'Display inline', 'directories-pro' ),
					'value'   => ! empty( $settings['inline'] ),
					'is_bool' => true,
				);
			}
			$ret['columns'] = array(
				'label' => __( 'Number of columns', 'directories-pro' ),
				'value' => $settings['columns'],
			);
			if ( strlen( $settings['separator'] ) ) {
				$ret['separator'] = array(
					'label' => __( 'Separator', 'directories-pro' ),
					'value' => $settings['separator'],
				);
			}
		}
		$ret['hide_empty'] = array(
			'label'   => __( 'Hide empty terms', 'directories-pro' ),
			'value'   => ! empty( $settings['hide_empty'] ),
			'is_bool' => true,
		);
		$ret['show_count'] = array(
			'label'   => __( 'Show post count', 'directories-pro' ),
			'value'   => ! empty( $settings['show_count'] ),
			'is_bool' => true,
		);

		return array( 'settings' => array( 'value' => $ret ) );
	}
}
