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

use SabaiApps\Directories\Component\Display;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Context;

abstract class AbstractEntitiesDisplayElement extends Display\Element\AbstractElement {

	protected $_defaultViewOnly = false;

	protected function _displayElementInfo( Bundle $bundle ) {
		return array(
			'type'             => 'content',
			'default_settings' => array(
				'view'       => null,
				'hide_empty' => true,
			),
			'icon'             => 'far fa-list-alt',
			'cacheable'        => true,
			'designable'       => array( 'margin', 'padding' ),
		);
	}

	protected function _getEntitiesBundleType( $entityOrBundle ) {
		return $entityOrBundle instanceof IEntity ? $entityOrBundle->getBundleType() : $entityOrBundle->type;
	}

	protected function _getEntitiesBundleGroup( $entityOrBundle ) {
		return $this->_application->Entity_Bundle( $entityOrBundle )->group;
	}

	protected function _getEntitiesBundle( $entityOrBundle, array $settings ) {
		return $this->_application->Entity_Bundle(
			$this->_getEntitiesBundleType( $entityOrBundle ),
			$this->_getEntitiesBundleGroup( $entityOrBundle )
		);
	}

	protected function _displayElementSupports( Bundle $bundle, Display\Model\Display $display ) {
		return $display->type === 'entity' && $display->name === 'detailed';
	}

	public function displayElementSettingsForm( Bundle $bundle, array $settings, Display\Model\Display $display, array $parents = array(), $tab = null, $isEdit = false, array $submitValues = array() ) {
		$form         = array();
		$view_options = $this->_getViewOptions( $bundle, $settings );
		if ( count( $view_options ) === 1 ) {
			$view_names   = array_keys( $view_options );
			$form['view'] = array(
				'#type'          => 'hidden',
				'#horizontal'    => true,
				'#default_value' => $view_names[0],
			);
		} else {
			$form['view'] = array(
				'#title'         => __( 'Select view', 'directories-pro' ),
				'#type'          => 'select',
				'#horizontal'    => true,
				'#options'       => $view_options,
				'#default_value' => $settings['view'],
				'#required'      => true,
			);
		}
		$form['hide_empty'] = array(
			'#title'         => __( 'Hide if no content to show', 'directories-pro' ),
			'#type'          => 'checkbox',
			'#horizontal'    => true,
			'#default_value' => ! empty( $settings['hide_empty'] ),
		);
		return $form;
	}

	protected function _getViewOptions( Bundle $bundle, array $settings ) {
		$views = array();
		foreach ( $this->_application->getModel( 'View', 'View' )->bundleName_is( $this->_getEntitiesBundle( $bundle, $settings )->name )->fetch() as $view ) {
			if ( $this->_defaultViewOnly && ! $view->isDefault() ) {
				continue;
			}
			$views[ $view->name ] = $view->getLabel();
		}
		return $views;
	}

	protected function _getListEntitiesSettings( Bundle $bundle, array $element, IEntity $entity ) {
		return array(
			'load_view'  => $element['settings']['view'],
			'hide_empty' => ! isset( $element['settings']['hide_empty'] ) // compat with <=1.2.84
				|| ! empty( $element['settings']['hide_empty'] ),
		);
	}

	protected function _getListEntitiesPath( Bundle $bundle, array $element, IEntity $entity ) {
		return $bundle->getPath();
	}

	protected function _getListEntitiesParams( Bundle $bundle, array $element, IEntity $entity ) {
		return array();
	}

	public function displayElementRender( Bundle $bundle, array $element, $var, ?array $context = null ) {
		// Get bundle of entities to list
		if ( ! $_bundle = $this->_getEntitiesBundle( $bundle, $element['settings'] ) ) {
			return;
		}

		if ( ! $this->_application->Filter( 'view_display_element_entities_render', true, array( $this->_name, $_bundle, $var ) ) ) {
			return;
		}

		if ( ( ! $list_entities_settings = $this->_getListEntitiesSettings( $_bundle, $element, $var ) )
			|| empty( $list_entities_settings['load_view'] )
		) {
			return;
		}

		if ( empty( $_bundle->info['parent'] )
			&& empty( $_bundle->info['parent_field'] )
			&& empty( $_bundle->info['is_taxonomy'] )
		) {
			// @todo: See why filter button does not work with top level bundles when shown in a display. Until then, disable it.
			// Seems to work? Commented out on 7/5/2023
			// $list_entities_settings['settings']['filter']['show'] = false;
		}

		return $this->_application->getPlatform()->render(
			array(
				'path'   => $this->_getListEntitiesPath( $_bundle, $element, $var ),
				'params' => $this->_getListEntitiesParams( $_bundle, $element, $var ),
			),
			array( 'settings' => array( 'hide_empty' => true ) + $list_entities_settings ),
			$this->_getRenderSettings( $bundle )
		);
	}

	protected function _getRenderSettings( Bundle $bundle ) {
		return array(
			'cache'         => false,
			'title'         => false,
			'container'     => null,
			'render_assets' => false,
		);
	}

	protected function _displayElementReadableInfo( Bundle $bundle, Display\Model\Element $element ) {
		$settings = $element->data['settings'];
		$ret      = array();
		if ( ! empty( $settings['view'] )
			&& ( $views = $this->_getViewOptions( $bundle, $settings ) )
			&& isset( $views[ $settings['view'] ] )
		) {
			$ret['view'] = array(
				'label' => __( 'Select view', 'directories-pro' ),
				'value' => $views[ $settings['view'] ],
			);
		}

		return array( 'settings' => array( 'value' => $ret ) );
	}
}
