<?php
namespace SabaiApps\Directories\Component\WordPress\Block;

use SabaiApps\Directories\Application;

/**
 * AbstractBlock provides a base class for WordPress blocks.
 * Implements common logic for block info, rendering, caching, and placeholders.
 */
abstract class AbstractBlock implements IBlock {

	protected $_application, $_name, $_info;
	protected static $_defaultInfo = array(
		'json'          => false,
		'package'       => 'directories-pro',
		'editor_script' => null,
	);

	/**
	 * Constructor.
	 *
	 * @param Application $application
	 * @param string      $name
	 */
	public function __construct( Application $application, $name ) {
		$this->_application = $application;
		$this->_name        = $name;
	}

	/**
	 * Returns block information as an array, or a specific key if provided.
	 *
	 * @param string|null $key
	 * @return mixed
	 */
	public function wordpressBlockInfo( $key = null ) {
		if ( ! isset( $this->_info ) ) {
			$this->_info = (array) $this->_wordpressBlockInfo() + self::$_defaultInfo;
		}

		return isset( $key ) ? ( isset( $this->_info[ $key ] ) ? $this->_info[ $key ] : null ) : $this->_info;
	}

	/**
	 * Returns block information array (to be implemented by subclass).
	 *
	 * @return array
	 */
	abstract protected function _wordpressBlockInfo();

	/**
	 * Returns variables for the block editor.
	 *
	 * @return array
	 */
	public function wordpressBlockEditorVars() {
		return array();
	}

	/**
	 * Called when block editor assets are enqueued.
	 *
	 * @param string $editorScriptHandle
	 */
	public function wordpressBlockOnEnqueueEditorAssets( $editorScriptHandle ) {}

	/**
	 * Renders the block content.
	 *
	 * @param array       $attributes
	 * @param string|null $content
	 * @param bool        $isBlockEditorRequest
	 * @return string
	 */
	public function wordpressBlockRender( array $attributes, $content, $isBlockEditorRequest ) {
		return '';
	}

	/**
	 * Returns the placeholder HTML for the block.
	 *
	 * @param array       $attributes
	 * @param string|null $content
	 * @return string
	 */
	public function wordpressBlockPlaceholder( array $attributes, $content ) {
		$info = $this->wordpressBlockInfo();
		return sprintf(
			'<div class="components-placeholder">
    <div class="components-placeholder__label"><span class="dashicon dashicons dashicons-%3$s"></span>Directories: %4$s</div>
    <div class="drts" style="width:100%%;">
        <div class="%1$salert %1$salert-warning">%2$s</div>
        <p>%5$s</p>
    </div>
</div>',
			DRTS_BS_PREFIX,
			$this->_application->H( __( 'This block may not be displayed in the backend.', 'directories-pro' ) ),
			$this->_application->H( $info['icon'] ),
			$this->_application->H( $info['title'] ),
			$this->_application->H( $info['description'] )
		);
	}

	/**
	 * Returns cache options for the block.
	 *
	 * @return array
	 */
	protected function _getCacheOptions() {
		$cache_options = array(
			array(
				'value' => 0,
				'label' => __( 'No cache', 'directories-pro' ),
			),
			array(
				'value' => 3600,
				'label' => sprintf( _n( '%d hour', '%d hours', 1, 'directories-pro' ), 1 ),
			),
			array(
				'value' => 7200,
				'label' => sprintf( _n( '%d hour', '%d hours', 2, 'directories-pro' ), 2 ),
			),
			array(
				'value' => 18000,
				'label' => sprintf( _n( '%d hour', '%d hours', 3, 'directories-pro' ), 5 ),
			),
		);
		foreach ( array( 1, 2, 3, 5, 7, 10 ) as $day ) {
			$cache_options[] = array(
				'value' => 86400 * $day,
				'label' => sprintf( _n( '%d day', '%d days', $day, 'directories-pro' ), $day ),
			);
		}
		return $cache_options;
	}

	/**
	 * Converts an associative array to select control options.
	 *
	 * @param array $options
	 * @return array
	 */
	protected function _toSelectControlOptions( array $options ) {
		$ret = array();
		foreach ( $options as $value => $label ) {
			$ret[] = array(
				'value' => $value,
				'label' => $label,
			);
		}
		return $ret;
	}

	/**
	 * Renders a template with settings and optional cache.
	 *
	 * @param string        $path
	 * @param array         $settings
	 * @param int|bool|null $cache
	 * @return string
	 */
	protected function _render( $path, array $settings, $cache = null ) {
		$cache = $this->_application->Filter(
			'wordpress_block_render_cache_lifetime',
			$this->_application->getComponent( 'System' )->isDebugEnabled() && ! $this->_application->getUser()->isAdministrator() ? false : ( isset( $cache ) ? $cache : false ),
			array( $this->_name )
		);

		$args = $this->_application->Filter(
			'wordpress_block_render_args',
			array(
				'settings' => $settings,
				'cache'    => $cache,
			),
			array( $this->_name )
		);

		return $this->_application->getPlatform()->render(
			$path,
			array( 'settings' => $args['settings'] ),
			array( 'cache' => $args['cache'] )
		);
	}

	/**
	 * Returns the current directory name for the block, if available.
	 *
	 * @return string|false
	 */
	protected function _getCurrentDirectory() {
		$directory_name = false;
		if ( $obj = get_queried_object() ) {
			if ( is_tax() ) {
				if ( ! empty( $obj->taxonomy )
					&& ( $tax_bundle = $this->_application->Entity_Bundle( $obj->taxonomy ) )
				) {
					$directory_name = $tax_bundle->group;
				}
			} elseif ( is_page() ) {
				if ( ! empty( $obj->post_name ) ) {
					$page_slugs     = $this->_application->getPlatform()->getPageSlugs();
					$directory_name = array_search( $obj->post_name, $page_slugs[1]['Directory'] );
				}
			}
		}

		foreach ( $this->_application->getModel( 'Directory', 'Directory' )->type_is( 'directory' )->fetch() as $directory ) {
			if ( ! $this->_application->Directory_Types_impl( $directory->type, true ) ) {
				continue;
			}

			$directory_name = $directory->name;
			break;
		}

		return $directory_name;
	}
}
