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

use SabaiApps\Directories\Component\Field\Renderer\AbstractRenderer;
use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Entity\Model\Bundle;

class TermsFieldRenderer extends AbstractRenderer {

	protected function _fieldRendererInfo() {
		return array(
			'field_types'      => array( $this->_name ),
			'default_settings' => array(
				'icon'                 => false,
				'icon_size'            => 'sm',
				'no_link'              => false,
				'show_top_only'        => false,
				'show_parents'         => false,
				'show_top_parent_only' => false,
				'parent_sep'           => ' / ',
				'show_count'           => false,
				'_separator'           => ', ',
			),
			'inlineable'       => true,
		);
	}

	protected function _fieldRendererSettingsForm( IField $field, array $settings, array $parents = array() ) {
		if ( ! $taxonomy_bundle = $field->getTaxonomyBundle() ) {
			return;
		}

		$ret = array(
			'icon'       => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show icon', 'directories-pro' ),
				'#default_value' => ! empty( $settings['icon'] ),
				'#horizontal'    => true,
				'#weight'        => 1,
			),
			'icon_size'  => array(
				'#type'          => 'select',
				'#title'         => __( 'Icon size', 'directories-pro' ),
				'#default_value' => isset( $settings['icon_size'] ) ? $settings['icon_size'] : null,
				'#options'       => $this->_application->System_Icon_sizeOptions(),
				'#horizontal'    => true,
				'#weight'        => 2,
				'#states'        => array(
					'visible' => array(
						sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'icon' ) ) ) ) => array(
							'type'  => 'checked',
							'value' => true,
						),
					),
				),
			),
			'no_link'    => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Do not link', 'directories-pro' ),
				'#default_value' => ! empty( $settings['no_link'] ),
				'#horizontal'    => true,
				'#weight'        => 5,
			),
			'show_count' => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show post count', 'directories-pro' ),
				'#default_value' => ! empty( $settings['show_count'] ),
				'#weight'        => 16,
			),
		);
		if ( ! empty( $taxonomy_bundle->info['is_hierarchical'] ) ) {
			$ret += array(
				'show_top_only'        => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Show top level term only', 'directories-pro' ),
					'#default_value' => ! empty( $settings['show_top_only'] ),
					'#horizontal'    => true,
					'#weight'        => 10,
				),
				'show_parents'         => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Show parent terms', 'directories-pro' ),
					'#default_value' => ! empty( $settings['show_parents'] ),
					'#horizontal'    => true,
					'#weight'        => 10,
					'#states'        => array(
						'visible' => array(
							sprintf( 'input[name="%s"]', $show_top_only_selector = $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'show_top_only' ) ) ) ) => array(
								'type'  => 'checked',
								'value' => false,
							),
						),
					),
				),
				'show_top_parent_only' => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Show top level parent term only', 'directories-pro' ),
					'#default_value' => ! empty( $settings['show_top_parent_only'] ),
					'#horizontal'    => true,
					'#weight'        => 12,
					'#states'        => array(
						'visible' => array(
							sprintf( 'input[name="%s"]', $show_top_only_selector ) => array(
								'type'  => 'checked',
								'value' => false,
							),
							sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'show_parents' ) ) ) ) => array(
								'type'  => 'checked',
								'value' => true,
							),
						),
					),
				),
				'parent_sep'           => array(
					'#type'          => 'textfield',
					'#field_prefix'  => __( 'Separator', 'directories-pro' ),
					'#default_value' => $settings['parent_sep'],
					'#horizontal'    => true,
					'#no_trim'       => true,
					'#weight'        => 11,
					'#states'        => array(
						'visible' => array(
							sprintf( 'input[name="%s"]', $show_top_only_selector ) => array(
								'type'  => 'checked',
								'value' => false,
							),
							sprintf( 'input[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'show_parents' ) ) ) ) => array(
								'type'  => 'checked',
								'value' => true,
							),
						),
					),
				),
			);
		}

		return $this->_application->Filter( 'entity_terms_field_renderer_settings_form', $ret, array( $field, $settings, $parents ) );
	}

	protected function _fieldRendererRenderField( IField $field, array &$settings, IEntity $entity, array $values, ?array $context = null, $more = 0 ) {
		$ret     = $ids = array();
		$options = array( 'no_link' => ! empty( $settings['no_link'] ) );
		if ( ! empty( $settings['icon'] ) ) {
			$options['icon_size'] = $settings['icon_size'];
			foreach ( array_keys( $values ) as $i ) {
				$term = $values[ $i ];
				if ( ! is_object( $term ) ) {
					continue;
				}

				$options['icon'] = true;
				if ( $image_src = $term->getCustomProperty( 'image_src' ) ) {
					$options['icon']          = $image_src;
					$options['icon_is_value'] = $options['icon_is_image'] = true;
				} elseif ( $icon_src = $term->getCustomProperty( 'icon_src' ) ) {
					$options['icon']          = $icon_src;
					$options['icon_is_value'] = $options['icon_is_image'] = $options['icon_is_full'] = true;
				} else {
					if ( $icon = $term->getCustomProperty( 'icon' ) ) {
						$options['icon']          = $icon;
						$options['icon_is_value'] = true;
					}
					$options['icon_color'] = $term->getCustomProperty( 'color' );
				}
				if ( $link = $this->_getTermPermalink( $term, $settings, $options, $entity, $ids ) ) {
					$ret[ $term->getId() ] = $link;
				}
			}
		} else {
			foreach ( array_keys( $values ) as $i ) {
				$term = $values[ $i ];
				if ( ! is_object( $term ) ) {
					continue;
				}

				if ( $link = $this->_getTermPermalink( $term, $settings, $options, $entity, $ids ) ) {
					$ret[ $term->getId() ] = $link;
				}
			}
		}

		return implode( $settings['_separator'], $this->_application->Filter( 'entity_terms_field_rendered', $ret, array( $field, $settings, $entity ) ) );
	}

	protected function _getTermPermalink( IEntity $term, array $settings, array $permalinkOptions, IEntity $entity, array &$ids ) {
		if ( ! empty( $settings['show_top_only'] ) ) {
			if ( $term->getCustomProperty( 'parent_titles' ) ) {
				return;
			}
		} elseif ( ! empty( $settings['show_parents'] ) ) {
			if ( empty( $settings['show_top_parent_only'] ) ) {
				if ( $title = $this->_maybeFormatPermalinkTitle( $term, $settings ) ) {
					$permalinkOptions['atts']['title'] = $this->_application->Entity_Title( $term );
					$permalinkOptions['title']         = $title;
				}
			} elseif ( ( $parent_titles = $term->getCustomProperty( 'parent_titles' ) )
						&& isset( $parent_titles[0] )
						&& ( $parent_slugs = $term->getCustomProperty( 'parent_slugs' ) )
						&& isset( $parent_slugs[0] )
					) {

					$parent_slug = $parent_slugs[0];
				if ( in_array( $parent_slug, $ids ) ) {
					return; // prevent duplicate term
				}

					$ids[] = $parent_slug;
				if ( ! $term = $this->_application->Entity_Types_impl( $term->getType() )->entityTypeEntityBySlug( $term->getBundleName(), $parent_slug ) ) {
					return;
				}

					$permalinkOptions['title'] = $parent_titles[0];
			} else {
				if ( in_array( $term->getSlug(), $ids ) ) {
					return; // prevent duplicate term
				}

				$ids[] = $term->getSlug();
			}
		}

		// If using taxonomy alias, fetch pass original bundle to get the correct path for permalink.
		if ( ! $original_bundle = $this->_application->Entity_Bundle_isTaxonomyAliased( $term->getBundleName(), $entity ) ) {
			$original_bundle = null;
		}
		$link = $this->_application->Entity_Permalink( $term, $permalinkOptions, '', null, $original_bundle );
		if ( ! empty( $settings['show_count'] )
			&& ( null !== $count = $term->getCustomProperty( 'content_count' ) )
			&& is_array( $count )
			&& isset( $count[ '_' . $entity->getBundleName() ] )
		) {
			$link .= ' <span style="vertical-align:middle">(' . $count[ '_' . $entity->getBundleName() ] . ')</span>';
		}
		return $link;
	}

	protected function _maybeFormatPermalinkTitle( IEntity $term, array $settings ) {
		if ( null !== $title = $this->_application->Filter( 'entity_terms_field_render_permalink_title', null, array( $term, $settings ) ) ) {
			return $title;
		}

		if ( ! $parent_titles = $term->getCustomProperty( 'parent_titles' ) ) {
			return; // will be formatted by entity permalink helper
		}

		$parts = array();
		foreach ( $parent_titles as $term_title ) {
			$parts[] = $term_title;
		}
		$parts[] = $this->_application->Entity_Title( $term );
		return implode( $settings['parent_sep'], $parts );
	}

	public function fieldRendererSupportsAmp( Bundle $bundle ) {
		return true;
	}

	protected function _fieldRendererReadableSettings( IField $field, array $settings ) {
		$ret = array(
			'icon'         => array(
				'label'   => __( 'Show icon', 'directories-pro' ),
				'value'   => ! empty( $settings['icon'] ),
				'is_bool' => true,
				'weight'  => 1,
			),
			'no_link'      => array(
				'label'   => __( 'Do not link', 'directories-pro' ),
				'value'   => ! empty( $settings['no_link'] ),
				'is_bool' => true,
				'weight'  => 5,
			),
			'show_parents' => array(
				'label'   => __( 'Show parent terms', 'directories-pro' ),
				'value'   => ! empty( $settings['show_parents'] ),
				'is_bool' => true,
				'weight'  => 10,
			),
		);
		if ( ! empty( $settings['icon'] ) ) {
			if ( isset( $settings['icon_size'] ) ) {
				$icon_sizes = $this->_application->System_Icon_sizeOptions();
				if ( isset( $icon_sizes[ $settings['icon_size'] ] ) ) {
					$ret['icon_size'] = array(
						'label'  => __( 'Icon size', 'directories-pro' ),
						'value'  => $icon_sizes[ $settings['icon_size'] ],
						'weight' => 2,
					);
				}
			}
		}
		return $ret;
	}
}
