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

use SabaiApps\Directories\Component\Field;
use SabaiApps\Directories\Component\Entity;

class PhotosFieldRenderer extends Field\Renderer\AbstractRenderer {

	protected static $_count = 0;

	protected function _fieldRendererInfo() {
		return array(
			'label'            => __( 'Photo Slider', 'directories-pro' ),
			'field_types'      => array( 'wp_image', 'file_image' ),
			'default_settings' => array(
				'size'               => 'large',
				'effect'             => 'slide',
				'show_thumbs'        => true,
				'thumbs_columns'     => 6,
				'columns'            => 4,
				'pager'              => false,
				'speed'              => 260,
				'auto'               => false,
				'controls'           => true,
				'link'               => false,
				'zoom'               => true,
				'show_videos'        => false,
				'video_field'        => null,
				'prepend_videos'     => false,
				'num_videos'         => 1,
				'height'             => 0,
				'show_other_images'  => false,
				'other_image_fields' => null,
			),
			'separatable'      => false,
			'emptiable'        => true, // for when there are only videos to show
		);
	}

	protected function _fieldRendererSettingsForm( Field\IField $field, array $settings, array $parents = array() ) {
		$form = array(
			'size'           => array(
				'#title'         => __( 'Image size', 'directories-pro' ),
				'#type'          => 'select',
				'#options'       => $this->_getImageSizeOptions(),
				'#default_value' => $settings['size'],
			),
			'height'         => array(
				'#type'          => 'slider',
				'#title'         => __( 'Slider height', 'directories-pro' ),
				'#default_value' => $settings['height'],
				'#min_value'     => 0,
				'#min_text'      => __( 'Auto', 'directories-pro' ),
				'#max_value'     => 800,
				'#step'          => 20,
				'#integer'       => true,
			),
			'columns'        => array(
				'#title'         => __( 'Number of columns', 'directories-pro' ),
				'#type'          => 'slider',
				'#min_value'     => 2,
				'#max_value'     => 12,
				'#default_value' => $settings['columns'],
				'#states'        => array(
					'visible' => array(
						sprintf( 'select[name="%s[size]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'one',
							'value' => array( 'thumbnail', 'thumbnail_scaled' ),
						),
					),
				),
			),
			'show_thumbs'    => array(
				'#title'         => __( 'Show thumbnails', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['show_thumbs'] ),
				'#states'        => array(
					'invisible' => array(
						sprintf( 'select[name="%s[size]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'one',
							'value' => array( 'thumbnail', 'thumbnail_scaled' ),
						),
					),
				),
			),
			'thumbs_columns' => array(
				'#title'         => __( 'Number of thumbnail columns', 'directories-pro' ),
				'#type'          => 'slider',
				'#min_value'     => 2,
				'#max_value'     => 12,
				'#default_value' => $settings['thumbs_columns'],
				'#states'        => array(
					'invisible_or' => array(
						sprintf( 'select[name="%s[size]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'one',
							'value' => array( 'thumbnail', 'thumbnail_scaled' ),
						),
						sprintf( 'input[name="%s[show_thumbs]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'checked',
							'value' => false,
						),
					),
				),
			),
			'effect'         => array(
				'#title'         => __( 'Slider effect', 'directories-pro' ),
				'#type'          => 'select',
				'#options'       => $this->_getPhotoSliderEffectOptions(),
				'#default_value' => $settings['effect'],
			),
			'speed'          => array(
				'#title'         => __( 'Slide/Fade animation speed in milliseconds', 'directories-pro' ),
				'#type'          => 'slider',
				'#integer'       => true,
				'#min_value'     => 50,
				'#max_value'     => 1000,
				'#default_value' => $settings['speed'],
				'#step'          => 10,
			),
			'pager'          => array(
				'#title'         => __( 'Show slide indicators', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['pager'] ),
			),
			'auto'           => array(
				'#title'         => __( 'Autoplay slides', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['auto'] ),
			),
			'link'           => array(
				'#title'         => __( 'Link to post', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['link'] ),
				'#states'        => array(
					'invisible' => array(
						sprintf( 'select[name="%s[size]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'one',
							'value' => array( 'thumbnail', 'thumbnail_scaled' ),
						),
					),
				),
			),
			'zoom'           => array(
				'#title'         => __( 'Zoom on click image', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['zoom'] ),
				'#states'        => array(
					'invisible_or' => array(
						sprintf( 'select[name="%s[size]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'one',
							'value' => array( 'thumbnail', 'thumbnail_scaled' ),
						),
						sprintf( 'input[name="%s[link]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'checked',
							'value' => true,
						),
					),
				),
			),
			'controls'       => array(
				'#title'         => __( 'Show prev/next arrows', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['controls'] ),
			),
		);
		// Video field
		$video_fields = $this->_application->Entity_Field_options(
			$field->Bundle,
			array(
				'interface'       => 'Field\Type\IVideo',
				'return_disabled' => true,
			)
		);
		if ( ! empty( $video_fields[0] ) ) {
			$show_videos_states = array(
				'visible' => array(
					sprintf( '[name="%s"]', $this->_application->Form_Form_fieldName( array( $parents, 'show_videos' ) ) ) => array(
						'type'  => 'checked',
						'value' => 1,
					),
				),
			);
			$form              += array(
				'show_videos'        => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Include videos', 'directories-pro' ),
					'#default_value' => ! empty( $settings['show_videos'] ),
				),
				'video_field'        => array(
					'#type'             => 'select',
					'#title'            => __( 'Video field', 'directories-pro' ),
					'#options'          => $video_fields[0],
					'#options_disabled' => array_keys( $video_fields[1] ),
					'#default_value'    => $settings['video_field'] ?? null,
					'#states'           => $show_videos_states,
				),
				'prepend_videos'     => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Show videos first', 'directories-pro' ),
					'#default_value' => ! empty( $settings['prepend_videos'] ),
					'#states'        => $show_videos_states,
				),
				'video_privacy_mode' => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Embed videos in privacy mode', 'directories-pro' ),
					'#default_value' => ! empty( $settings['video_privacy_mode'] ),
					'#states'        => $show_videos_states,
				),
				'num_videos'         => array(
					'#type'          => 'slider',
					'#title'         => __( 'Max number of videos', 'directories-pro' ),
					'#default_value' => $settings['num_videos'],
					'#min_value'     => 0,
					'#max_value'     => 10,
					'#min_text'      => __( 'Unlimited', 'directories-pro' ),
					'#states'        => $show_videos_states,
				),
			);
		}
		// Other image fields
		$other_image_fields = $this->_application->Entity_Field_options(
			$field->Bundle,
			array(
				'interface'       => 'Field\Type\IImage',
				'return_disabled' => true,
				'exclude'         => array( $field->getFieldName() ),
			)
		);
		if ( ! empty( $other_image_fields[0] ) ) {
			$show_other_image_states = array(
				'visible' => array(
					sprintf( '[name="%s"]', $this->_application->Form_Form_fieldName( array( $parents, 'show_other_images' ) ) ) => array(
						'type'  => 'checked',
						'value' => 1,
					),
				),
			);
			$form                   += array(
				'show_other_images'  => array(
					'#type'          => 'checkbox',
					'#title'         => __( 'Include other images', 'directories-pro' ),
					'#default_value' => ! empty( $settings['show_other_images'] ),
				),
				'other_image_fields' => array(
					'#type'             => 'sortablecheckboxes',
					'#title'            => __( 'Other image fields', 'directories-pro' ),
					'#options'          => $other_image_fields[0],
					'#options_disabled' => array_keys( $other_image_fields[1] ),
					'#default_value'    => $settings['other_image_fields'] ?? null,
					'#states'           => $show_other_image_states,
					'#multiple'         => true,
				),
			);
		}

		return $form;
	}

	protected function _getPhotoSliderEffectOptions() {
		return array(
			'slide' => __( 'Slide', 'directories-pro' ),
			'fade'  => __( 'Fade', 'directories-pro' ),
		);
	}

	protected function _fieldRendererRenderField( Field\IField $field, array &$settings, Entity\Type\IEntity $entity, array $values, ?array $context = null, $more = 0 ) {
		if ( ! $field_type_impl = $this->_application->Field_Type( $field->getFieldType(), true ) ) {
			return;
		}

		$videos = $this->_getVideos( $settings, $entity );

		if ( ! empty( $settings['show_other_images'] )
			&& ! empty( $settings['other_image_fields'] )
			&& is_array( $settings['other_image_fields'] )
		) {
			foreach ( $settings['other_image_fields'] as $other_image_field ) {
				if ( ! $other_values = $entity->getFieldValue( $other_image_field ) ) {
					continue;
				}

				foreach ( array_keys( $other_values ) as $k ) {
					$values[] = $other_values[ $k ];
				}
			}
		}

		if ( empty( $values ) && ! $videos ) {
			return;
		}

		$images       = array();
		$has_main     = ! in_array( $settings['size'], array( 'thumbnail', 'thumbnail_scaled' ) );
		$zoom_enabled = ( ! $has_main || empty( $settings['link'] ) ) && ! empty( $settings['zoom'] );
		if ( ! $zoom_enabled ) { // enable link?
			$link = $this->_application->Entity_PermalinkUrl( $entity );
		}
		foreach ( array_keys( $values ) as $k ) {
			if ( ! $img = $field_type_impl->fieldImageGetUrl( $values[ $k ], $settings['size'] ) ) {
				unset( $values[ $k ] );
				continue;
			}

			$images[] = array(
				'alt'      => $field_type_impl->fieldImageGetAlt( $values[ $k ] ),
				'img'      => $img,
				'url'      => $zoom_enabled
					? null
					: ( isset( $link ) ? $link : $field_type_impl->fieldImageGetUrl( $values[ $k ], 'full' ) ),
				'img_zoom' => $zoom_enabled && ! $has_main ? $field_type_impl->fieldImageGetUrl( $values[ $k ], 'full' ) : null,
			);
		}
		if ( $videos ) {
			$images = empty( $settings['prepend_videos'] ) ? array_merge( $images, $videos ) : array_merge( $videos, $images );
		}
		if ( empty( $images ) ) {
			return;
		}

		$options = array(
			'photoslider_class'              => 'drts-field-photoslider',
			'photoslider_fade'               => $settings['effect'] === 'fade',
			'photoslider_pager'              => ! empty( $settings['pager'] ),
			'photoslider_speed'              => empty( $settings['speed'] ) ? 260 : $settings['speed'],
			'photoslider_auto'               => ! empty( $settings['auto'] ),
			'photoslider_controls'           => ! empty( $settings['controls'] ),
			'photoslider_columns'            => ! $has_main && ! empty( $settings['columns'] ) ? $settings['columns'] : 1,
			'photoslider_center'             => false,
			'photoslider_infinite'           => ! $has_main,
			'photoslider_zoom'               => $zoom_enabled,
			'photoslider_video_privacy_mode' => ! empty( $settings['video_privacy_mode'] ),
			'photoslider_height'             => $settings['height'],
		);
		if ( ! empty( $settings['show_thumbs'] )
			&& $settings['size'] !== 'thumbnail'
			&& $settings['size'] !== 'thumbnail_scaled'
		) {
			$options['photoslider_thumbs']         = array();
			$options['photoslider_thumbs_columns'] = $settings['thumbs_columns'];
			foreach ( array_keys( $values ) as $k ) {
				if ( ! $thumb = $field_type_impl->fieldImageGetUrl( $values[ $k ], 'thumbnail' ) ) {
					unset( $options['photoslider_thumbs'] );
					break;
				}

				$options['photoslider_thumbs'][] = array(
					'img' => $thumb,
				);
			}
			if ( $videos ) {
				$video_thumbs = array();
				foreach ( array_keys( $videos ) as $k ) {
					$video_thumbs[] = array(
						'img' => $videos[ $k ]['thumbnail_url'],
					);
				}
				if ( ! empty( $settings['prepend_videos'] ) ) {
					$options['photoslider_thumbs'] = array_merge( $video_thumbs, $options['photoslider_thumbs'] );
				} else {
					$options['photoslider_thumbs'] = array_merge( $options['photoslider_thumbs'], $video_thumbs );
				}
			}

			// Do not show if single photo
			if ( count( $options['photoslider_thumbs'] ) <= 1 ) {
				unset( $options['photoslider_thumbs'] );
			}
		}

		return $this->_application->Slider_Photos( $images, $options, $entity );
	}

	protected function _getVideos( array $settings, Entity\Type\IEntity $entity ) {
		if ( empty( $settings['show_videos'] )
			|| empty( $settings['video_field'] )
			|| ( ! $values = $entity->getFieldValue( $settings['video_field'] ) )
		) {
			return;
		}

		$videos = array();
		$num    = 0;
		foreach ( array_keys( $values ) as $i ) {
			if ( empty( $values[ $i ]['thumbnail_url'] ) ) {
				continue;
			}

			$videos[] = array(
				'type'          => $values[ $i ]['provider'],
				'video_id'      => $values[ $i ]['id'],
				'thumbnail_url' => $values[ $i ]['thumbnail_url'],
				'title'         => isset( $values[ $i ]['title'] ) ? $values[ $i ]['title'] : null,
			);
			if ( ! empty( $settings['num_videos'] )
				&& $num >= $settings['num_videos']
			) {
				break;
			}
		}
		return $videos;
	}

	protected function _fieldRendererReadableSettings( Field\IField $field, array $settings ) {
		$ret = array(
			'size' => array(
				'label' => __( 'Image size', 'directories-pro' ),
				'value' => $this->_getImageSizeOptions()[ $settings['size'] ],
			),
		);
		if ( ! in_array( $settings['size'], array( 'thumbnail', 'thumbnail_scaled' ) ) ) {
			$ret['show_thumbs'] = array(
				'label'   => __( 'Show thumbnails', 'directories-pro' ),
				'value'   => ! empty( $settings['show_thumbs'] ),
				'is_bool' => true,
			);
			if ( ! empty( $settings['show_thumbs'] ) ) {
				$ret['thumbs_columns'] = array(
					'label' => __( 'Number of thumbnail columns', 'directories-pro' ),
					'value' => $settings['thumbs_columns'],
				);
			}
		}
		$ret += array(
			'effect'         => array(
				'label' => __( 'Slider effect', 'directories-pro' ),
				'value' => $this->_getPhotoSliderEffectOptions()[ $settings['effect'] ],
			),
			'pager'          => array(
				'label'   => __( 'Show slide indicators', 'directories-pro' ),
				'value'   => ! empty( $settings['pager'] ),
				'is_bool' => true,
			),
			'auto'           => array(
				'label'   => __( 'Autoplay slides', 'directories-pro' ),
				'value'   => ! empty( $settings['auto'] ),
				'is_bool' => true,
			),
			'controls'       => array(
				'label'   => __( 'Show prev/next arrows', 'directories-pro' ),
				'value'   => ! empty( $settings['controls'] ),
				'is_bool' => true,
			),
			'show_videos'    => array(
				'label'   => __( 'Show videos', 'directories-pro' ),
				'value'   => ! empty( $settings['show_videos'] ),
				'is_bool' => true,
			),
			'video_field'    => array(
				'label' => __( 'Video field', 'directories-pro' ),
				'value' => isset( $settings['video_field'] ) ? $settings['video_field'] : null,
			),
			'prepend_videos' => array(
				'label'   => __( 'Prepend videos', 'directories-pro' ),
				'value'   => ! empty( $settings['prepend_videos'] ),
				'is_bool' => true,
			),
			'num_videos'     => array(
				'label' => __( 'Max number of videos', 'directories-pro' ),
				'value' => isset( $settings['num_videos'] ) ? $settings['num_videos'] : null,
			),
		);

		return $ret;
	}
}
