<?php
namespace SabaiApps\Directories\Component\View\Helper;

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Display\Controller\Admin\AddDisplay;
use SabaiApps\Directories\Exception;
use SabaiApps\Directories\Component\Entity;
use SabaiApps\Directories\Component\View\Mode\IMode;

class ModesHelper {

	public function help( Application $application, $excludeSystem = true, $useCache = true ) {
		if ( ! $useCache
			|| ( ! $view_modes = $application->getPlatform()->getCache( 'view_modes' ) )
		) {
			$view_modes = array(
				0 => array(),
				1 => array(),
			);
			foreach ( $application->InstalledComponentsByInterface( 'View\IModes' ) as $component_name ) {
				if ( ! $application->isComponentLoaded( $component_name )
					|| ( ! $mode_names = $application->getComponent( $component_name )->viewGetModeNames() )
				) {
					continue;
				}

				foreach ( $mode_names as $mode_name ) {
					if ( ! $view_mode = $application->getComponent( $component_name )->viewGetMode( $mode_name ) ) {
						continue;
					}

					$view_modes[ (int) $view_mode->viewModeInfo( 'system' ) ][ $mode_name ] = $component_name;
				}
			}
			$application->getPlatform()->setCache( $view_modes, 'view_modes', 0 );
		}

		return $excludeSystem ? $view_modes[0] : $view_modes[0] + $view_modes[1];
	}

	private $_impls = array();

	/**
	 * Gets an implementation of SabaiApps\Directories\Component\View\IMode interface for a given view name
	 *
	 * @param Application                    $application
	 * @param string                         $mode
	 * @param array|Entity\Model\Bundle|null $bundles
	 * @param bool                           $returnFalse
	 */
	public function impl( Application $application, $mode, $bundles = null, $returnFalse = false ) {
		if ( ! isset( $this->_impls[ $mode ] ) ) {
			// Compat for <1.2.42
			if ( $mode === 'photoslider' ) {
				$mode = 'slider_photos';
			}

			if ( ( ! $view_modes = $this->help( $application, false ) )
				|| ! isset( $view_modes[ $mode ] )
				|| ( ! $application->isComponentLoaded( $view_modes[ $mode ] ) )
				|| ( ! $this->_impls[ $mode ] = $application->getComponent( $view_modes[ $mode ] )->viewGetMode( $mode ) )
			) {
				unset( $this->_impls[ $mode ] );
				if ( $returnFalse ) {
					return false;
				}
				throw new Exception\UnexpectedValueException( sprintf( 'Invalid view mode: %s', $mode ) );
			}
		}
		if ( isset( $bundles ) ) {
			if ( ! is_array( $bundles ) ) {
				$bundles = array( $bundles );
			}
			foreach ( (array) $bundles as $_bundle ) {
				if ( ! $bundle = $application->Entity_Bundle( $_bundle ) ) {
					if ( $returnFalse ) {
						return false;
					}
					throw new Exception\RuntimeException( sprintf( 'Invalid bundle: ' . $_bundle ) );
				}
				if ( ! $this->_impls[ $mode ]->viewModeSupports( $bundle ) ) {
					if ( $returnFalse ) {
						return false;
					}
					throw new Exception\RuntimeException( sprintf( 'View mode %s is not supported by %s.', $mode, $bundle->getLabel() ) );
				}
			}
		}

		return $this->_impls[ $mode ];
	}

	public function settingsForm( Application $application, IMode $mode, Entity\Model\Bundle $bundle, array $settings = array(), array $parents = array(), ?array $submitValues = null ) {
		$settings += (array) $mode->viewModeInfo( 'default_settings' );
		$form      = (array) $mode->viewModeSettingsForm( $bundle, $settings, $parents );
		if ( $default_display = $mode->viewModeInfo( 'default_display' ) ) {
			$displays  = array();
			$displays += AddDisplay::existingDisplays( $application, $bundle->name, $default_display );
			if ( count( $displays ) > 1 ) {
				if ( false === $mode->viewModeInfo( 'display_required' ) ) { // allows empty display
					$displays = array( '' => __( '— Select —', 'directories-pro' ) ) + $displays;
				}
				$form['display'] = array(
					'#type'          => 'select',
					'#title'         => __( 'Select display', 'directories-pro' ),
					'#options'       => $displays,
					'#horizontal'    => true,
					'#default_value' => isset( $settings['display'] ) && isset( $displays[ $settings['display'] ] ) ? $settings['display'] : null,
				);
			} else {
				$form['display'] = array(
					'#type'  => 'hidden',
					'#value' => key( $displays ),
				);
			}
			$form['display_cache'] = array(
				'#type'  => 'hidden',
				'#value' => false,
			);
			/*
			$form['display_cache'] = $application->System_Util_cacheSettingsForm(
				isset($settings['display_cache']) ? $settings['display_cache'] : '',
				null,
				[60, 120],
				__('Cache content rendered by display', 'directories-pro')
			);
			$form['display_cache_guest_only'] = [
				'#type' => 'checkbox',
				'#title' => __('Cache display for guest users only', 'directories-pro'),
				'#default_value' => !isset($settings['display_cache_guest_only']) || $settings['display_cache_guest_only'],
				'#horizontal' => true,
				'#states' => [
					'invisible' => [
						sprintf('select[name="%s"]', $application->Form_Form_fieldName(array_merge($parents, ['display_cache']))) => ['value' => ''],
					],
				],
			];
			*/
		}

		return $application->Filter( 'view_mode_settings_form', $form, array( $mode, $bundle, $settings, $parents, $submitValues ) );
	}
}
