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

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Exception;

/**
 * WidgetsHelper provides methods to retrieve, render, and manage widgets from all components.
 */
class WidgetsHelper {

	protected static $_widgetCount = 0, $_cssLoaded = false;

	/**
	 * Returns all available widgets from components implementing System\IWidgets.
	 *
	 * @param Application $application
	 * @param bool        $useCache Whether to use cached widget data.
	 * @return array
	 */
	public function help( Application $application, $useCache = true ) {
		if ( ! $useCache
			|| ( ! $widgets = $application->getPlatform()->getCache( 'system_widgets' ) )
		) {
			$widgets = array();
			foreach ( $application->InstalledComponentsByInterface( 'System\IWidgets' ) as $component_name ) {
				if ( ! $application->isComponentLoaded( $component_name ) ) {
					continue;
				}

				foreach ( $application->getComponent( $component_name )->systemGetWidgetNames() as $widget_name ) {
					if ( ! $widget = $application->getComponent( $component_name )->systemGetWidget( $widget_name ) ) {
						continue;
					}
					try {
						$info = $widget->systemWidgetInfo();
					} catch ( Exception\IException $e ) {
						continue;
					}
					$widgets[ $widget_name ] = array(
						'component' => $component_name,
						'title'     => isset( $info['title'] ) ? (string) $widget->systemWidgetInfo( 'title' ) : '',
						'summary'   => isset( $info['summary'] ) ? (string) $widget->systemWidgetInfo( 'summary' ) : '',
						'load_js'   => ! empty( $info['load_js'] ),
					);
				}
			}
			$application->getPlatform()->setCache( $widgets, 'system_widgets', 0 );
		}

		return $widgets;
	}

	/**
	 * Returns the widget object for a given widget name.
	 *
	 * @param Application $application
	 * @param string      $widgetName
	 * @param bool        $loadModel
	 * @return object|null
	 */
	public function widget( Application $application, $widgetName, $loadModel = false ) {
		$widgets = $this->help( $application );
		if ( ! isset( $widgets[ $widgetName ] )
			|| ! $application->isComponentLoaded( $widgets[ $widgetName ]['component'] )
		) {
			return;
		}

		return $application->getComponent( $widgets[ $widgetName ]['component'] )->systemGetWidget( $widgetName );
	}

	/**
	 * Renders the widget HTML for a given widget name and settings.
	 *
	 * @param Application $application
	 * @param string      $widgetName
	 * @param array       $settings
	 * @return string|null
	 */
	public function renderWidget( Application $application, $widgetName, array $settings ) {
		if ( ! $widget = $this->widget( $application, $widgetName, true ) ) {
			return;
		}

		if ( ! $content = $widget->systemWidgetContent( $settings ) ) {
			return;
		}

		$class = 'drts drts-system-widget drts-system-widget-' . str_replace( '_', '-', $widgetName ) . ' ' . DRTS_BS_PREFIX . 'clearfix';
		$id    = 'drts-system-widget-' . ++self::$_widgetCount;
		$div   = '<div class="' . $class . '" id="' . $id . '">';
		$ret   = array( $div );
		if ( is_array( $content['content'] ) ) {
			$ret[] = $application->getTemplate()->render( array( 'system_widget_' . $widgetName, 'system_widget_list' ), $content );
		} else {
			$ret[] = $content['content'];
		}
		$ret[] = '</div>';

		if ( $widget->systemWidgetInfo( 'load_js' ) ) {
			$application->getPlatform()->loadDefaultAssets( true, false ) // CSS will be loaded
				->addJs( 'DRTS.init($("#' . $id . '"));', true, -99 );
		}

		if ( ! self::$_cssLoaded ) {
			$application->getPlatform()->loadDefaultAssets( false ); // load CSS
			self::$_cssLoaded = true;
		}

		return implode( PHP_EOL, $ret );
	}
}
