<?php

namespace modules\formEdit;

class main extends \moduleMain {

	use \modules\output\traits {
		\modules\output\traits::__construct as __ConstructOutput;
	}
	use \modules\input\traits {
			\modules\input\traits::__construct as __ConstructInput;
		}

	private $active = FALSE;

	public function __construct() {
		parent::__construct(__DIR__);
		$this->__ConstructOutput();
		$this->__ConstructInput();
	}

	public function Activate() {
		hook_add('component.add', [$this, '__componentFE']);
		hook_add('formedit.validate', [$this, '__validate']);
		hook_add('fieldlist.filter', [ $this, '__custom_fields' ]);		// you should not need to add a hook to this chain.  add to "fieldlist.{fieldtype}.html" instead
		hook_add('menu.admin', [$this, '__admin_menu'], 59);	 		// admin menu
		// Since formEdit is a used by many core modules, it can't load any modules here
		
		hook_add('formedit.tab', [$this, '__formedit_tabs'], 1);			// must be first; always enabled
		hook_add('formedit.tab.general', [$this, '__formedit_tabs_general']);
		hook_add('formedit.tab.fields', [$this, '__formedit_tabs_fields']);
		hook_add('formedit.tab.preview', [$this, '__formedit_tabs_preview']);
		hook_add('formedit.tab.notification', [$this, '__formedit_tabs_notification']);
		hook_add('formedit.tab.responses', [$this, '__formedit_tabs_responses']);
		hook_add('formedit', [$this, '__formedit']);

	}
	
	public function __formedit_tabs(&$tabs, $uri) {
		if (($p = strpos($uri, '?')) !== FALSE) $uri = substr($uri, 0, $p);
		$elements = explode('/', $uri);
		$identifier = $elements[3] ?? '';
		
		$tabs['_tab'][] = [
			'name' => 'General',
			'icon' => '<i class="far fa-edit"></i>',
			'fragment' => 'general',
			'className' => '',
		];
		if ($identifier != 'new') {
			$tabs['_tab'][] = [
				'name' => 'Fields',
				'icon' => '<i class="fas fa-highlighter"></i>',
				'fragment' => 'fields',
				'className' => '',
			];
			$tabs['_tab'][] = [
				'name' => 'Preview',
				'icon' => '<i class="fas fa-columns"></i>',
				'fragment' => 'preview',
				'className' => '',
			];
			$tabs['_tab'][] = [
				'name' => 'Notification',
				'icon' => '<i class="fas fa-paperclip"></i>',
				'fragment' => 'notification',
				'className' => '',
			];
			$tabs['_tab'][] = [
				'name' => 'Responses',
				'icon' => '<i class="fas fa-envelope"></i>',
				'fragment' => 'responses',
				'className' => '',
			];
		}
		
		$tabs['uri'] = $uri;
		$tabs['form_id'] = $identifier;
	}

	public function __formedit_tabs_general(&$data, $ephemeral) {
		$form_id = $ephemeral['form_id'];
		$data = hook_execute('execute.internal', NULL, '/admin/forms/general/' . $form_id);
	}

	public function __formedit_tabs_fields(&$data, $ephemeral) {
		$form_id = $ephemeral['form_id'];
		$data = hook_execute('execute.internal', NULL, '/admin/forms/fields/' . $form_id);
	}
	public function __formedit_tabs_preview(&$data, $ephemeral) {
		$form_id = $ephemeral['form_id'];
		$data = hook_execute('execute.internal', NULL, '/admin/forms/preview/' . $form_id);
	}
	public function __formedit_tabs_notification(&$data, $ephemeral) {
		$form_id = $ephemeral['form_id'];
		$data = hook_execute('execute.internal', NULL, '/admin/forms/notification/' . $form_id);
	}
	public function __formedit_tabs_responses(&$data, $ephemeral) {
		$form_id = $ephemeral['form_id'];
		$data = hook_execute('execute.internal', NULL, '/admin/forms/responses/' . $form_id);
	}


	public function __componentFE(&$status, $requested) {
		if ($requested == 'formedit') {
			$this->active = TRUE;
			// load view
			$view = $this->__loadView('formedit_view');
			$view->handlebars_template();
//			$status = '{{> fields fieldlist=fieldlist}}';
			$status = '{{> formedit}}';
		}
	}
	
	public function __custom_fields(&$result, $active) {			// $result is the handlebars data structure that will be returned to the frontend
		if (isset($result['fieldlist'])) {
			foreach($result['fieldlist'] as &$field) {
				$module_name = preg_match('~^(.*?)\[~', $field['name'], $value) ? $value[1] : '';
				$fieldname = preg_match('~\[(.*?)\]~', $field['name'], $value) ? $value[1] : '';
				$settings = $active[$module_name];
				$field['value'] = $settings[$fieldname] ?? '';			// get the current value
				$hookname = 'fieldlist.' . strtolower($field['type']) . '.html';
				$field = hook_execute($hookname, $field);			// the custom html for this control should be in $field['custom']
				$result[$fieldname] = $field['value'];
			}
		}
	}
	
	// process the fields - get values and any error messages
	public function __validate(&$result, $definitions) {
		$post = $this->post();
		$errors = [];
		$data = [];
		foreach($definitions as $def) {
			$name = $def['name'] ?? '';
			$required = $def['required'] ?? FALSE;		// not for checkboxes
			switch($def['type']) {
				case 'string':
				case 'tel':
					$value = trim($post[$name] ?? '');	// not for multiselect
					if ($value == '' && $required) {
						$errors[$name] = ['message' => '?'];		// must have a value
						break;
					}
					$data[$name] = $value;
					break;

				case 'email':
					$value = trim($post[$name] ?? '');	// not for multiselect
					if ($value == '' && $required) {
						$errors[$name] = ['message' => '?'];		// must have a value
						break;
					}
					// validate email
					if (($p = strrpos($value, '@')) !== FALSE) {
						$domain = strtolower(substr($value, $p + 1));
						if (strlen($domain) < 4 || strpos($domain, '.') === FALSE) {
							$errors[$name] = ['message' => 'This does not look like a valid email address'];
							break;
						}
						$disposable = hook_execute('email.check', NULL, $domain);
						if ($disposable) {
							$errors[$name] = ['message' => 'Temporary email addresses are not acceptable'];
						} else {
							$data[$name] = $value;
						}
					} else {
						$errors[$name] = ['message' => 'This does not look like a valid email address'];
					}
					break;

				case 'select':
					break;

				case 'text':
					$value = trim($post[$name] ?? '');	// not for multiselect
					if ($value == '' && $required) {
						$errors[$name] = ['message' => 'This field is required'];		// must have a value
						break;
					}
					$data[$name] = $value;
					break;
				// case checkbox
			}
		}
		if (count($errors)) {
			$result = ['field' => $errors];
		} else {
			$result = ['data' => $data ];
		}
	}
	
	public function __admin_menu(&$menu) {
		$menu[] = [
				'caption' => 'Forms', 
				'href' => '/admin/forms', 
				'hint' => 'View/Edit Custom Forms',
				'icon' => '<i class="far fa-keyboard"></i>',
				's' => 0
			];
	}
	
	public function __formedit(&$html, $unused, $param) {
		$param =  trim(preg_replace('/\s+/', ' ',$param));
		[$action, $id] = explode(' ', $param);
		$model_formedit = $this->LoadModel('formedit_model');
	
		$model_formedit->FormId($id);
		// give error if missing
		
		// add the code to the page - post directly to /~/formedit...
		$html .= $model_formedit->AsHtml();
	}
	
	final function submission() {
		$form_id = hook_execute( 'nonce.verify', FALSE, 'response', FALSE, $this->post('auth', '') );
		if ($form_id === FALSE) {
			return [
				'result' => 5,
				'message' => 'You are not authorized to access this page. Please refresh this page and try again',
			];
		}
		$model_formedit = $this->LoadModel('formedit_model');
		// check required fields
		$ip_address = $this->getClientIP();
		$language   = $this->__INPUT->getPreferedLanguage();
		$result = $model_formedit->FormId($form_id)
					->processSubmission($_POST, $ip_address, $language);
		if (is_string($result)) {
			$this->Redirect($result);
		}
	}
	
}

/*
form designer - drag and drop - name, email, phone, address, state, zip, country
					-- select boxes
{{formedit abcdef012}}
create placeholder "contact us"
allow reCapchta 2x or 3x

generate form html using handlebars from an array
load existing data
save data
error checking
to do: use by single-module settings (system page, and google mail page)
also generate buttons

*/