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

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

class RatingFieldRenderer extends AbstractRenderer {

	protected function _fieldRendererInfo() {
		return array(
			'field_types'      => array( $this->_name ),
			'default_settings' => array(
				'format'     => 'stars',
				'color'      => array(
					'type'  => '',
					'value' => null,
				),
				'bar_height' => 12,
				'decimals'   => 1,
				'inline'     => false,
			),
			'accept_multiple'  => true,
			'inlineable'       => true,
		);
	}

	protected function _fieldRendererSettingsForm( IField $field, array $settings, array $parents = array() ) {
		return array(
			'format'     => array(
				'#type'          => 'select',
				'#title'         => __( 'Display format', 'directories-pro' ),
				'#default_value' => $settings['format'],
				'#horizontal'    => true,
				'#options'       => $this->_getFormatOptions(),
			),
			'color'      => $this->_application->System_Color_settingsForm( $settings['color'], array_merge( $parents, array( 'color' ) ) ),
			'decimals'   => array(
				'#type'          => 'select',
				'#title'         => __( 'Decimals', 'directories-pro' ),
				'#options'       => array(
					0 => __( '0 (no decimals)', 'directories-pro' ),
					1 => 1,
					2 => 2,
				),
				'#default_value' => $settings['decimals'],
				'#horizontal'    => true,
			),
			'inline'     => array(
				'#title'         => __( 'Render bar labels inline', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#default_value' => ! empty( $settings['inline'] ),
				'#states'        => array(
					'invisible' => array(
						sprintf( 'select[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'format' ) ) ) ) => array( 'value' => 'stars' ),
					),
				),
				'#horizontal'    => true,
			),
			'bar_height' => $this->_application->Voting_RenderRating_barHeightForm( $settings['bar_height'] ) + array(
				'#states' => array(
					'invisible' => array(
						sprintf( 'select[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( 'format' ) ) ) ) => array( 'value' => 'stars' ),
					),
				),
			),
		);
	}

	protected function _fieldRendererRenderField( IField $field, array &$settings, IEntity $entity, array $values, ?array $context = null, $more = 0 ) {
		switch ( $settings['format'] ) {
			case 'stars':
				return $this->_renderRatingStars( $field, $settings, $values );
			case 'bars':
				return $this->_renderRatingBars( $field, $settings, $values );
		}
	}

	protected function _renderRatingStars( IField $field, array $settings, array $values ) {
		if ( null === $value = $this->_getRatingValue( $field, $settings, $values ) ) {
			return;
		}

		return $this->_application->Voting_RenderRating(
			$value,
			array(
				'color'    => $settings['color'],
				'decimals' => $settings['decimals'],
				'count'    => $this->_getRatingCount( $field, $settings, $values ),
			)
		);
	}

	protected function _renderRatingBars( IField $field, array $settings, array $values ) {
		if ( ! $review_bundle = $this->_getReviewBundle( $field ) ) {
			return;
		}

		if ( null === $this->_getRatingValue( $field, $settings, $values ) ) {
			return;
		}

		$options          = array(
			'color'    => $settings['color'],
			'height'   => $settings['bar_height'],
			'decimals' => $settings['decimals'],
			'inline'   => $settings['inline'],
		);
		$html             = array();
		$criteria         = $this->_application->Review_Criteria( $review_bundle );
		$responsive_class = 'drts-col-12';
		foreach ( $this->_application->Filter(
			'review_criteria_rating_bar_responsiveness',
			array(
				'md' => 6,
				'xl' => 4,
			),
			array( $review_bundle )
		) as $size => $columns ) {
			$responsive_class .= ' drts-col-' . $size . '-' . $columns;
		}
		foreach ( array_keys( $criteria ) as $slug ) {
			$value = $this->_getRatingValue( $field, $settings, $values, $slug );

			$html[] = '<div class="' . $responsive_class . '">'
				. $this->_application->Voting_RenderRating_bar( $value, $criteria[ $slug ], $options )
				. '</div>';
		}
		return empty( $html ) ? '' : '<div class="drts-row drts-gutter-md">' . implode( PHP_EOL, $html ) . '</div>';
	}

	protected function _getReviewBundle( IField $field ) {
		return $field->Bundle;
	}

	protected function _getRatingValue( IField $field, array $settings, array $values, $slug = null ) {
		if ( ! isset( $slug ) ) {
			$slug = '_all';
		}
		return isset( $values[0][ $slug ]['value'] ) ? $values[0][ $slug ]['value'] : null;
	}

	protected function _getRatingCount( IField $field, array $settings, array $values, $slug = null ) {
		return; // do not show count
	}

	protected function _getFormatOptions() {
		return array(
			'stars' => __( 'Rating stars', 'directories-pro' ),
			'bars'  => __( 'Rating bars', 'directories-pro' ),
		);
	}

	protected function _fieldRendererReadableSettings( IField $field, array $settings ) {
		$ret = array(
			'format'   => array(
				'label' => __( 'Display format', 'directories-pro' ),
				'value' => $this->_getFormatOptions()[ $settings['format'] ],
			),
			'color'    => array(
				'label' => __( 'Color', 'directories-pro' ),
				'value' => empty( $settings['color']['type'] ) ? __( 'Default', 'directories-pro' ) : $settings['color']['value'],
			),
			'decimals' => array(
				'label' => __( 'Decimals', 'directories-pro' ),
				'value' => $settings['decimals'],
			),
		);
		if ( strpos( $settings['format'], 'bar' ) === 0 ) {
			$ret['inline']     = array(
				'label'   => __( 'Render bar labels inline', 'directories-pro' ),
				'value'   => ! empty( $settings['inline'] ),
				'is_bool' => true,
			);
			$ret['bar_height'] = array(
				'label' => __( 'Bar height', 'directories-pro' ),
				'value' => $settings['bar_height'] . 'px',
			);
		}
		return $ret;
	}
}
