<?php

namespace modules\tabs;

class main extends \moduleMain {

	private $tabs_present;

	use \modules\input\traits {
			\modules\input\traits::__construct as __ConstructInput;
		}
	use \modules\output\traits {
			\modules\output\traits::__construct as __ConstructOutput;
		}
	
	public function __construct() {
		parent::__construct(__DIR__);
		$this->__ConstructInput();
		$this->__ConstructOutput();
		$this->tabs_present = FALSE;
	}

	// class must be listed in a 'depends' setting to be activated
	public function Activate() {
		
		// add 'tabs' helper -- replaces macro with query-ui tab
		hook_add('html.prepare', [$this, '__add_helper']);

		// intercept handlebars output, looking for "{{tabs ...}}"
		hook_add('handlebars.add', [$this, '__intercept_fileobject']);
		
		// enumerate tabs to be displayed
		hook_add('output.data', [$this, '__intercept_pagedata']);
		
		// if the active template contains a tab
		//    then get content of first tab, include data in page json.
		//		this will be displayed by default, if a different fragment is specified, it will be loaded by the javascripts
		
	}

	// tab callback in two parts - enumerate (what tabs are to be displayed, and how is the tab to be displayed) - data (for the body of the active tab)

	// does the handlebars template use tabs?
	public function __intercept_fileobject(\FileObject $result) {
		if (preg_match('~\{\{tabs\s+(.*?)(|\s+.*?)\}\}~ms', $result->html(), $match)) {
			$hook = trim($match[1]);
			if (strlen($hook)) {
				$p = $hook[0];
				if (($p == '"' || $p == "'") && substr($hook, -1) == $p) {
					$hook = substr($hook, 1, -1);
				}
				$result->x_tabhook = $hook;
				$this->tabs_present = TRUE;
			}
		}
	}
	
	public function __add_helper(\moduleMain $theme) {
		$base = $this->StaticUriModule(__DIR__);
		$theme->IncludeFile("$base/tabs.js");
	}
	
	// does the active template have a TAB, if so, include:
	//   1. headers for all tabs
	//   2. the default tab - template and data
	//	 (data for other tabs are loaded by the javascript when a fragment is specified)
		
	//** TO DO:  must include ephemeral data
	public function __intercept_pagedata(&$data, $param) {
		if (isset($param['template'])) {
			$template = $param['template'];
			if (isset($template->x_tabhook)) {

// get all the data needed to be included in an ephemeral structure
// main page will generate a constant id (hookname:parameterhash)
				$tabdata = hook_execute($template->x_tabhook, [], $param['uri']);
				if (!array_key_exists('uri', $tabdata)) $tabdata['uri'] = $param['uri'];
				$fragment = $tabdata['default'] ?? '';
				if ($fragment == '' && isset($tabdata['_tab'])) {			// no default specified - so choose the first entry
					$idx = array_key_first($tabdata['_tab']);
					$fragment = $tabdata['_tab'][$idx]['fragment'] ?? '';
				}
				$tabdata['hook'] = $template->x_tabhook;
				$tabdata['action'] = 'tabs';
				$tabdata['default'] = $fragment;
				$id = $GLOBALS['loader']->CreateEphemeral($tabdata, $tabdata['guid'], 1800);	// normally 600 = 10min?
				$data['tabauth'] = $id;
//				$fragment = isset($tabdata['default']) ? $tabdata['default']  : '';
				if ($fragment != '') {		// get data for the default tab
					foreach($tabdata['_tab'] as &$tab) {
						if ($tab['fragment'] == $fragment) {
							$tab['data'] = hook_execute($template->x_tabhook . '.' . $fragment, [], $tabdata);
                            if (is_null($tab['data']) || !is_array($tab['data']) || !count($tab['data'])) {
                                $tab['data'] = [
                                    'result' => -1999,
                                    'message' => 'unable to retrieve data for tab "' . $template->x_tabhook . '.' . $fragment . '"',
                                ];
                            }
							break;
						}
					}
				}
				$data['_tab'] = $tabdata['_tab'];
				if (!empty($tabdata['default'])) {
					$data['_default'] = $tabdata['default'];
				}
			}
		}
	}
	
	final function select($tabauth, $fragment = '') {
		$payload = $GLOBALS['loader']->GetEphemeral($tabauth);
		$url = $this->param('url');
		if ($payload === FALSE) {
			return ['error' => -14120, 'message' => 'link has expired'];
		}
		if ($payload['action'] != 'tabs') {
			return ['error' => -14121, 'message' => 'invalid link'];
		}
		if ($url === NULL) {
			return ['error' => -14122, 'message' => 'missing url parameter'];
		}
		if (empty($fragment)) {
			return ['error' => -14123, 'message' => 'missing fragment element'];
		}
		$uri = parse_url($url, PHP_URL_PATH);
		
		$hook = $payload['hook'];
		$res = hook_execute($hook . '.' . $fragment, [], $payload);
		return hook_execute($hook . '.*', $res, $payload, $fragment);
	}

}