<?php

namespace modules\cms;

class main extends \moduleMain {

	use \modules\config\traits {
			\modules\config\traits::__construct as __ConstructConfig;
		}
	use \modules\input\traits {
			\modules\input\traits::__construct as __ConstructInput;
		}
	use \modules\database\traits {
			\modules\database\traits::__construct as __ConstructDatabase;
		}
	use \modules\output\traits {
			\modules\output\traits::__construct as __ConstructOutput;
		}

	private $model_cms = NULL;
	private $editPage = FALSE;
	private $pagestatus = 0;
	private $notfound = FALSE;

	public function __construct() {
		parent::__construct(__DIR__);
		$this->__ConstructConfig();
		$this->__ConstructInput();
		$this->__ConstructDatabase();
		$this->__ConstructOutput($this->__INPUT, $this->__CONFIG);
	}

	public function Activate() {
		hook_add('output.errordetail', [$this, '__create']);
		hook_add('uri', [$this, '__checkcms'], 99);
		hook_add('email.transform', [$this, '__applyHandlebars']);		// is the email using a templating system?
		hook_add('menu.menu2', [$this, '__edit'], 2);					// can we edit this page?
		hook_add('menu.admin', [$this, '__admin_menu'], 20);	 		// admin menu
		hook_add('global.prepare', [$this, '__global_prepare']);
		hook_add('cms.dynamic.get', [$this, '__getDynamicPages']);	 	// list of dynamic pages
		hook_add('url.key.select', [$this, '__getDynamicPages2'], 89);	 	// list of dynamic pages -- for the store
		hook_add('cms.fields', [$this, '__prepare_header'], 58); 		// page header - eg carousel
		hook_add('cms.save', [$this, '__save_content']);
		hook_add('page.header', [$this, '__generate_header']);
//		$this->autoloadRegister('LightnCandy', __DIR__ . '/lightncandy');
		$this->Register_FormatHandler('__cms', [$this, '__cms_page'], 'a CMS page');
		$this->Register_FormatHandler('__cms_edit', [$this, '__cms_edit'], 'CMS page editor');
		$this->Register_FormatHandler('__cms_json', [$this, '__cms_json'], 'update CMS page status');
		
		hook_add('output.sitemap', [$this, '__sitemap']);
		$this->link('/home/sitemap-cms.xml', [$this, '__sitemap_cms']);	
	}
	
	public function __save_content($post, $sender) {
		$header = empty($post['header']) ? '' : trim($post['header']);
		$extra = $sender->Extra();
		$extra['header'] = $header;
		$sender->Extra($extra);
	}	
	
	public function __admin_menu(&$menu) {
		$menu[] = [
				'caption' => 'CMS Content', 
				'href' => '/admin/cms-pages', 
				'hint' => 'View/Edit CMS Content',
				'icon' => '<i class="fas fa-file-alt"></i>',
				's' => 0
			];
		$menu[] = [
				'caption' => 'Email Templates', 
				'href' => '/admin/email', 
				'hint' => 'Edit Email Templates',
				'icon' => '<i class="far fa-envelope"></i>',
				's' => 0
			];
	}

	private function _init() {
		if (empty($this->model_cms)) {
			$this->model_cms = $this->LoadModel('cms_model');
			$this->model_cms->SetPages($this->loadModel('pages'));
		}
	}

	public function __create(&$data, $http_status) {
		if ($this->notfound) {		// only for not-found pages
			$this->_init();
			$uri = $this->uri();					// without any query_string
			if ($uri != '/') $uri = rtrim($uri, '/');
			$this->editPage = $this->model_cms->ErrorPage($data, $uri);
		}
	}
	
	// only for email templates
	public function __applyHandlebars(&$mailobject) {
        $template = $mailobject->template();
		if (empty($result) && !empty($template)) {
			$this->_init();
			$this->model_cms->ApplyEmailTemplate($mailobject);
		}
	}
	
	// is the URL one from the cms system?
	//to do: intercept email links 
	public function __checkcms(&$uri) {
		$this->_init();
		$preview = $this->param('previewid', '');
		if ($preview) {
			$this->model_cms->SetPagesHistory($this->loadModel('pages_history'));
			$this->model_cms->RedirectToPreview($preview, $this->hostname(TRUE));
			return;
		}
		$edithash = $this->param('editpage', '');
//		$this->model_cms->SetPages($this->loadModel('pages'));
		$this_url = $uri;
		if ($this_url != '/') $this_url = rtrim($this_url, '/');
		$this->pagestatus = $this->model_cms->IsCmsPage($this_url, $edithash);
		switch($this->pagestatus) {
			case 1:			// view cms text
//				error_log('__checkcms: ' . $this->pagestatus);
				$this->OutputFormat('__cms');
				$this->notfound = TRUE;
				$uri = 200;
				return;
			case 2:			// edit text
				$this->model_cms->SetPagesHistory($this->loadModel('pages_history'));
				$this->_acceptcms('__cms_edit');
				$this->notfound = TRUE;
				if  ($this->__INPUT->isPost()) {
					$uri = 200;
				}
		// CASE 3: redirect to preview page
		}
	}
	
	// a cms page has been requested.
	// if we are doing a preview, at the same time the page is saved here, the homepage
	//  is loaded from another tab.  We pause a second to allow this update to saved
	//  then the other tab redirects to the preview page
	private function _acceptcms($param) {
		// set cms text
		
		if ($this->method() == 'POST') {
			$this->model_cms->SetPagesHistory($this->loadModel('pages_history'));
			// {"error":false,"message":null,"body":null,"result":null}

			$post = $_POST;
			$post['s'] = strtolower(trim($this->post('s', '')));
			$result = $this->model_cms->PageSave($post);
			$this->OutputSet('result', $result['result']);			// 2026.05.20 this doesn't work
			$this->OutputSet('message', $result['message']);
			$this->OutputFormat('__cms_json');
			//to do: update data json to display page-saved noty.
		} else {
			$this->OutputFormat($param);
		}
	}
	
	public function __edit(&$menu) {
		$this->_init();
		$editable = $this->model_cms->isEditable();
		if ($editable) {		// page not found - allow it to be created or edited
// does the page exist?
			$hint = $this->pagestatus ? 'Edit Content' : 'Create Content';
			$menu[] = [
				'caption' => $hint, 
				'href' => $editable, 
				'hint' => $hint,
				'icon' => '<i class="fax-green largeicon fas fa-pen-square"></i>',
				's' => 0
			];
		}
	}
	
	public function __cms_page($data) {
		unset($data['result'], $data['message']);
		$data['className'] = 'cms';
		$this->model_cms->ViewPage();
		$data = hook_execute('output.filter', $data, $this);
		$this->__OUTPUT->ExportHandler($data, 'html');
	}

	public function __cms_edit($data) {
		unset($data['result'], $data['message'], $data['template']);
		$GLOBALS['loader']->IncludeView('cms', 'cms_admin_view', 'cms_selectpage');
		$this->model_cms->EditPage();
		$this->__OUTPUT->ExportHandler($data, 'html');
	}
	
	public function __cms_json($data) {
		$data['result'] = $this->OutputGet('result');
		$data['message'] = $this->OutputGet('message');
		$this->__OUTPUT->ExportHandler($data, 'json');
	}

	public function __global_prepare(&$object_list) {
		foreach($object_list as $key => $item) {
			if ($item['type'] == 'table' && $item['name'] == 'pages_history') {
				unset($object_list[$key]);
			}
		}
	}

	public function __getDynamicPages(&$data, $full = FALSE) {
		$page = $this->LoadModel('pages');
		$data = $page->LoadDynamicPages($full);
	}
	public function __getDynamicPages2(&$data) {
		$page = $this->LoadModel('pages');
		$list = $page->LoadDynamicPages(FALSE);
		foreach($list as $item) {
			$data[] = [ 'key' =>  $item['l'], 'value' => "CMS: {$item['c']} [{$item['l']}]" ];
		}
	}

	public function __sitemap(&$maps) {
		$maps[] = '/home/sitemap-cms.xml';
	}
	
	public function __sitemap_cms() {
        // get all cms entries
		$page = $this->LoadModel('pages');
		$pages = $page->LoadDynamicPages(TRUE);
		$url = $this->Hostname(TRUE);

        $text = '';
        // keep only those where sitemap has been enabled
        foreach($pages as $page) {
            if (!empty($page['x']['sitemap'])) {
                $mdt = strtotime($page['mod'] . 'Z');
                $dt = date('c', $mdt);
                $text .= <<<BLOCK
<url>
    <loc>{$url}{$page['l']}</loc>
    <lastmod>$dt</lastmod>
</url>

BLOCK;
            }
        }

		header('Content-type: application/xml; charset=UTF-8');
        echo <<<BLOCK
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
{$text}</urlset>
BLOCK;
		exit;
    }

	public function __prepare_header($model_cms) {
		$model_cms->AddTab('Header',
			$model_cms->AddField_TextArea('header', 'Header HTML', 'htmledit textarea-header')
		);
	}
	
	public function __generate_header(&$html) {
		if (is_object($this->model_cms)) {
			$extra = $this->model_cms->Extra();
			$header = trim($extra['header'] ?? '');
			if ($header != '' && $this->pagestatus != 2) $html .= ExpandMacro($header);
		}
	}
	
	final function page_list() {
		$level = isset($_SESSION['current_user']) ? $_SESSION['current_user']['u_level'] : 0;
		if ($level > 3) {
			$this->model_cms = $this->LoadModel('cms_model');
			$order = explode(':', $_POST['order']);
			$page = trim($_POST['page']);
			$data = $this->model_cms->GeneratePageList($order, $page);
			$this->__cms_json($data);
			exit;
		} else {
			$this->Error(-5);
		}
		
	}

}