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

use SabaiApps\Directories\Component\System\Widget\AbstractWidget;
use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Entity\Type\IEntity;

abstract class AbstractEntitiesSystemWidget extends AbstractWidget {

	protected $_bundleType;

	public function __construct( Application $application, $name, $bundleType ) {
		parent::__construct( $application, $name );
		$this->_bundleType = $bundleType;
	}

	abstract protected function _getBundle( array $settings );

	protected function _getDefaultSettings() {
		return array(
			'limit'             => 5,
			'sort'              => 'random',
			'hide_title'        => false,
			'show_summary'      => true,
			'summary_num_chars' => 50,
			'show_published'    => true,
			'show_thumbnail'    => true,
			'thumbnail_size'    => 64,
			'thumbnail_style'   => 'rounded',
			'featured_only'     => false,
		);
	}

	protected function _systemWidgetInfo() {
		return array(
			'title'   => $bundle_type_label = $this->_application->Entity_BundleTypeInfo( $this->_bundleType, 'label' ),
			'summary' => sprintf( __( "A list of your site's %s.", 'directories-pro' ), $bundle_type_label ),
		);
	}

	protected function _getWidgetSettings( array $settings ) {
		if ( ! $bundle = $this->_getBundle( $settings ) ) {
			return;
		}

		$default_settings = $this->_getDefaultSettings();
		$form             = array(
			'limit'             => array(
				'#type'          => 'textfield',
				'#title'         => __( 'Number of items to show (0 for unlimited)', 'directories-pro' ),
				'#integer'       => true,
				'#default_value' => $default_settings['limit'],
				'#size'          => 3,
				'#weight'        => 5,
			),
			'sort'              => array(
				'#type'          => 'select',
				'#title'         => __( 'Sort by', 'directories-pro' ),
				'#options'       => $this->_application->Entity_Sorts_options( $bundle ),
				'#default_value' => $default_settings['sort'],
				'#weight'        => 10,
			),
			'hide_title'        => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Hide title', 'directories-pro' ),
				'#default_value' => ! empty( $default_settings['hide_title'] ),
				'#weight'        => 15,
			),
			'show_summary'      => array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show summary', 'directories-pro' ),
				'#default_value' => ! empty( $default_settings['show_summary'] ),
				'#weight'        => 20,
			),
			'summary_num_chars' => array(
				'#type'          => 'textfield',
				'#title'         => __( 'Number of summary characters', 'directories-pro' ),
				'#integer'       => true,
				'#default_value' => $default_settings['summary_num_chars'],
				'#size'          => 6,
				'#weight'        => 21,
			),
		);
		$props            = $this->_application->Entity_Types_impl( $bundle->entitytype_name )->entityTypeInfo( 'properties' );
		if ( ! empty( $props['published'] ) ) {
			$form['show_published'] = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show published date', 'directories-pro' ),
				'#default_value' => ! empty( $default_settings['show_published'] ),
				'#weight'        => 25,
			);
		}
		if ( $this->_application->Entity_BundleTypeInfo( $this->_bundleType, 'entity_image' ) ) {
			$form['show_thumbnail']         = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show thumbnail', 'directories-pro' ),
				'#default_value' => ! empty( $default_settings['show_thubmanil'] ),
				'#weight'        => 30,
			);
			$form['thumbnail_size']         = array(
				'#type'          => 'textfield',
				'#title'         => __( 'Thumbnail size in pixels', 'directories-pro' ),
				'#default_value' => $default_settings['thumbnail_size'],
				'#min_value'     => 10,
				'#max_value'     => 100,
				'#integer'       => true,
				'#weight'        => 31,
			);
			$form['thumbnail_style']        = array(
				'#type'          => 'select',
				'#title'         => __( 'Thumbnail style', 'directories-pro' ),
				'#options'       => array(
					'rounded-0'      => __( 'Square', 'directories-pro' ),
					'rounded'        => __( 'Rounded square', 'directories-pro' ),
					'rounded-circle' => __( 'Circle', 'directories-pro' ),
				),
				'#default_value' => $default_settings['thumbnail_style'],
				'#min_value'     => 10,
				'#max_value'     => 100,
				'#integer'       => true,
				'#weight'        => 32,
			);
			$form['show_default_thumbnail'] = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show "No Image" image if no thumbnail', 'directories-pro' ),
				'#default_value' => true,
				'#weight'        => 33,
			);
		}
		if ( $this->_application->Entity_BundleTypeInfo( $this->_bundleType, 'featurable' ) ) {
			$form['featured_only'] = array(
				'#type'          => 'checkbox',
				'#title'         => __( 'Show featured items only', 'directories-pro' ),
				'#default_value' => ! empty( $default_settings['featured_only'] ),
				'#weight'        => 50,
			);
		}

		return $form;
	}

	protected function _getWidgetContent( array $settings ) {
		if ( ! $query = $this->_getQuery( $settings ) ) {
			return;
		}

		$query    = $this->_application->Filter( 'entity_widget_list_query', $query, array( $this->_bundleType, $settings, $this->_name ) );
		$entities = $query->fetch( $settings['limit'] );
		if ( empty( $entities ) ) {
			return;
		}

		$ret         = array();
		$image_class = isset( $settings['thumbnail_style'] ) ? DRTS_BS_PREFIX . $settings['thumbnail_style'] : null;
		$image_style = 'width:' . $settings['thumbnail_size'] . 'px;';
		if ( isset( $settings['thumbnail_style'] )
			&& $settings['thumbnail_style'] === 'rounded-circle'
		) {
			$image_size   = 'icon_xl';
			$image_style .= 'height:' . $settings['thumbnail_size'] . 'px;';
		} else {
			$image_size = 'thumbnail_scaled';
		}
		foreach ( $entities as $entity ) {
			if ( ! empty( $settings['show_thumbnail'] )
				&& ( $src = $this->_application->Entity_Image( $entity, $image_size ) )
			) {
				$image = array(
					'src'   => $src,
					'alt'   => $this->_application->Entity_Title( $entity ),
					'style' => $image_style,
					'class' => $image_class,
				);
			} elseif ( ! empty( $settings['show_default_thumbnail'] ) ) {
					$image = array(
						'src'   => $this->_application->System_NoImage( 'thumbnail', true, $entity ),
						'alt'   => $this->_application->Entity_Title( $entity ),
						'style' => $image_style,
						'class' => $image_class . ' drts-system-widget-no-image',
					);
			} else {
				$image = null;
			}
			$meta = array();
			if ( ! empty( $settings['show_published'] ) ) {
				$meta[] = '<i class="far fa-fw fa-calendar"></i> ' . $this->_application->System_Date( $entity->getTimestamp(), true );
			}
			$content = array(
				'summary'    => ! empty( $settings['show_summary'] ) ? $this->_application->System_Text_summarize( $entity->getContent(), $settings['summary_num_chars'] ) : null,
				'title_link' => ! isset( $settings['hide_title'] ) || ! $settings['hide_title']
					? $this->_application->Entity_Permalink(
						$entity,
						array(
							'skip_entity_title_filter' => true, // prevent conflict with wordpress filters
						)
					)
					: null,
				'meta'       => $meta,
				'image'      => $image,
				'url'        => $image ? $this->_application->Entity_PermalinkUrl( $entity ) : null,
			);
			$ret[]   = $this->_application->Filter( 'entity_system_widget_entity_content', $content, array( $this->_name, $entity, $settings ) );
		}
		return $ret;
	}

	protected function _getQuery( array $settings ) {
		if ( ! $bundle = $this->_getBundle( $settings ) ) {
			return;
		}

		$query = $this->_application->Entity_Query( $bundle->entitytype_name, $bundle->name )
			->fieldIs( 'status', $this->_application->Entity_Status( $bundle->entitytype_name, 'publish' ) )
			->sort( $settings['sort'], $this->_application->Entity_Sorts( $bundle ), $this->_getCacheId( $settings ) );
		if ( ! empty( $settings['featured_only'] ) ) {
			$query->fieldIsNotNull( 'entity_featured' );
		}
		if ( ! empty( $bundle->info['taxonomies'] )
			&& ( $term = $this->_isOnTaxonomyTermPage() )
			&& in_array( $term->getBundleName(), $bundle->info['taxonomies'] )
		) {
			$query->fieldIs( $term->getBundleType(), $term->getId() );
		}

		return $query;
	}

	protected function _isOnTaxonomyTermPage() {
		if ( isset( $GLOBALS['drts_entity'] ) ) {
			$entity = $GLOBALS['drts_entity'];
			if ( $entity instanceof IEntity
				&& $entity->isTaxonomyTerm()
			) {
				return $entity;
			}
		}
	}

	protected function _getCacheId( array $settings ) {
		if ( ( $term = $this->_isOnTaxonomyTermPage() )
			&& ( $bundle = $this->_getBundle( $settings ) )
			&& ! empty( $bundle->info['taxonomies'] )
			&& in_array( $term->getBundleName(), $bundle->info['taxonomies'] )
		) {
			$settings['_term_id'] = $term->getId();
		}
		return 'widgets_widget_' . $this->_name . '_' . md5( serialize( $settings ) );
	}
}
