<?php
namespace SabaiApps\Directories\Component\Display\Element;

use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Display\Model\Display;
use SabaiApps\Directories\Component\Display\Model\Element;
use SabaiApps\Directories\Context;

class TemplateElement extends AbstractElement {

	private $_templates, $_cssLoaded = array();

	protected function _displayElementInfo( Bundle $bundle ) {
		return array(
			'type'             => 'content',
			'label'            => _x( 'Template', 'display element name', 'directories-pro' ),
			'description'      => __( 'Load and display template file', 'directories-pro' ),
			'default_settings' => array(
				'template' => null,
				'raw'      => false,
			),
			'icon'             => 'fab fa-php',
			'designable'       => array( 'margin', 'padding' ),
		);
	}

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

	protected function _getTemplates( Bundle $bundle ) {
		if ( ! isset( $this->_templates ) ) {
			$this->_templates = array();
			$file_name_prefix = $bundle->type . '-element_';
			foreach ( $this->_application->getPlatform()->getCustomAssetsDir( false ) as $assets_dir ) {
				if ( ! is_dir( $assets_dir ) ) {
					continue;
				}

				foreach ( new \DirectoryIterator( $assets_dir ) as $finfo ) {
					if ( ! $finfo->isFile()
						|| strpos( $finfo->getFilename(), $file_name_prefix ) !== 0
						|| substr( $finfo->getFilename(), -9 ) !== '.html.php'
					) {
						continue;
					}

					$file_name = substr( $finfo->getFilename(), 0, -9 ); // remove extension

					// Is this a group (directory) specific template file?
					if ( ( $file_name_arr = explode( '-', $file_name ) )
						&& count( $file_name_arr ) === 3
					) {
						if ( $file_name_arr[2] !== $bundle->group ) {
							continue;
						}

						$file_name = $file_name_arr[0] . '-' . $file_name_arr[1]; // remove the component name part
					}

					if ( isset( $this->_templates[ $file_name ] ) ) {
						continue;
					}

					$this->_templates[ $file_name ] = ucwords( str_replace( '_', ' ', substr( $file_name, strlen( $file_name_prefix ) ) ) );
				}
			}
		}

		return $this->_templates;
	}

	public function displayElementSettingsForm( Bundle $bundle, array $settings, Display $display, array $parents = array(), $tab = null, $isEdit = false, array $submitValues = array() ) {
		$templates = $this->_getTemplates( $bundle );
		$form      = array(
			'template' => array(
				'#title'                 => __( 'Template file', 'directories-pro' ),
				'#type'                  => 'select',
				'#options'               => array( '' => __( '— Select —', 'directories-pro' ) ) + $templates,
				'#horizontal'            => true,
				'#default_value'         => $settings['template'],
				'#required'              => true,
				'#empty_value'           => '',
				'#description'           => $desc = sprintf(
					$this->_application->H( __( 'See %s for details on creating template files.', 'directories-pro' ) ),
					'<a href="https://directoriespro.com/documentation/advanced-customization/template-files.html" target="_blank">https://directoriespro.com/documentation/advanced-customization/template-files.html</a>'
				),
				'#description_no_escape' => true,
			),
			'raw'      => array(
				'#title'         => __( 'Do not add default HTML tags', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#horizontal'    => true,
				'#default_value' => ! empty( $settings['raw'] ),
				'#description'   => __( 'Enable this setting to prevent the system from wrapping the template content with default HTML tags.', 'directories-pro' ),
			),
		);
		if ( empty( $templates ) ) {
			$form['#header'][] = array(
				'level'   => 'warning',
				'message' => implode(
					PHP_EOL,
					array(
						$this->_application->H( $this->_application->H( __( 'You must first create one or more template files.', 'directories-pro' ) ) ),
						$desc,
					)
				),
			);
			unset( $form['template']['#description'] );
		}
		return $form;
	}

	public function displayElementRender( Bundle $bundle, array $element, $var, ?array $context = null ) {
		$settings = $element['settings'];
		if ( empty( $settings['template'] )
			|| ( ! $template_path = $this->_templateExists( $bundle, $settings['template'] ) )
		) {
			return;
		}

		ob_start();
		$this->_application->getTemplate()->includeFile( $template_path, array( 'entity' => $var ) );
		$html = ob_get_clean();

		if ( ! empty( $settings['raw'] ) ) {
			return array( 'raw' => $html );
		}

		$css_class = $this->_getCssClass( $bundle, $settings );

		if ( ! isset( $this->_cssLoaded[ $settings['template'] ] ) ) {
			// Load CSS file if any
			if ( $css_url = $this->_cssExists( $bundle, $settings['template'], $template_path ) ) {
				$this->_application->getPlatform()->addCssFile( $css_url, $css_class, array( 'drts' ), false );
				$this->_cssLoaded[ $settings['template'] ] = true;
			} else {
				$this->_cssLoaded[ $settings['template'] ] = false;
			}
		}

		return array(
			'html'  => $html,
			'class' => $css_class,
		);
	}

	protected function _templateExists( Bundle $bundle, $templateName, $extension = '.html' ) {
		foreach ( array( $templateName . '-' . $bundle->group, $templateName ) as $_template_name ) {
			if ( $template_path = $this->_application->getTemplate()->exists( $_template_name, $extension ) ) {
				return $template_path;
			}
		}
		return false;
	}

	protected function _cssExists( Bundle $bundle, $templateName, $templatePath ) {
		$css_file = str_replace( '.html.php', '.css', $templatePath );
		if ( file_exists( $css_file ) ) {
			return $this->_application->System_Url_site( $css_file );
		}

		return false;
	}

	protected function _getCssClass( Bundle $bundle, array $settings ) {
		return 'drts-display-element-template-name-' . str_replace( $bundle->type . '-element_', '', $settings['template'] );
	}

	public function displayElementTitle( Bundle $bundle, array $data ) {
		if ( '' === $title = parent::displayElementTitle( $bundle, $data ) ) {
			$title = $this->_application->H( $this->_getTemplateLabel( $bundle, $data['settings'] ) );
		}
		return $title;
	}

	protected function _getTemplateLabel( Bundle $bundle, array $settings ) {
		$templates = $this->_getTemplates( $bundle );
		return isset( $templates[ $settings['template'] ] ) ? $templates[ $settings['template'] ] : '';
	}

	protected function _displayElementReadableInfo( Bundle $bundle, Element $element ) {
		$settings = $element->data['settings'];
		$ret      = array(
			'template' => array(
				'label' => __( 'Template file', 'directories-pro' ),
				'value' => $settings['template'],
			),
		);
		return array( 'settings' => array( 'value' => $ret ) );
	}
}
