<?php
/*****************************************************************************
 * AccountSettings.php
 * Contains the account settings controller.
 *
 * Kabuki CMS (C) 2013-2023, Aaron van Geffen
 *****************************************************************************/

class AccountSettings extends HTMLController
{
	public function __construct()
	{
		// Not logged in yet?
		if (!Registry::get('user')->isLoggedIn())
			throw new NotAllowedException('You need to be logged in to view this page.');

		parent::__construct('Account settings');
		$form_title = 'Account settings';

		// Session checking!
		if (empty($_POST))
			Session::resetSessionToken();
		else
			Session::validateSession();

		$fields = [
			'first_name' => [
				'type' => 'text',
				'label' => 'First name',
				'size' => 50,
				'maxlength' => 255,
			],
			'surname' => [
				'type' => 'text',
				'label' => 'Family name',
				'size' => 50,
				'maxlength' => 255,
			],
			'emailaddress' => [
				'type' => 'text',
				'label' => 'Email address',
				'size' => 50,
				'maxlength' => 255,
			],
			'password1' => [
				'before_html' => '<div class="offset-sm-2 mt-4"><p>To change your password, please fill out the fields below.</p></div>',
				'type' => 'password',
				'label' => 'Password',
				'size' => 50,
				'maxlength' => 255,
				'is_optional' => true,
			],
			'password2' => [
				'type' => 'password',
				'label' => 'Password (repeat)',
				'size' => 50,
				'maxlength' => 255,
				'is_optional' => true,
			],
		];

		$form = new Form([
			'request_url' => BASEURL . '/' . $_GET['action'] . '/',
			'fields' => $fields,
			'submit_caption' => 'Save details',
		]);

		$user = Registry::get('user');

		// Create the form, add in default values.
		$form->setData(empty($_POST) ? $user->getProps() : $_POST);
		$formview = new FormView($form, $form_title);
		$this->page->adopt($formview);

		// Fetch user tags
		$tags = Tag::getAllByOwner($user->getUserId());
		if (!empty($tags))
			$this->page->adopt(new MyTagsView($tags));

		// Left a message?
		if (isset($_SESSION['account_msg']))
		{
			$alert = $_SESSION['account_msg'];
			$formview->adopt(new Alert($alert[0], $alert[1], $alert[2]));
			unset($_SESSION['account_msg']);
		}

		// Just updating account settings?
		if (!empty($_POST))
		{
			$form->verify($_POST);

			// Anything missing?
			if (!empty($form->getMissing()))
			{
				$missingFields = array_intersect_key($fields, array_flip($form->getMissing()));
				$missingFields = array_map(function($field) { return strtolower($field['label']); }, $missingFields);
				return $formview->adopt(new Alert('Some data missing', 'Please fill out the following fields: ' . implode(', ', $missingFields), 'danger'));
			}

			$data = $form->getData();

			// Just to be on the safe side.
			$data['first_name'] = htmlspecialchars(trim($data['first_name']));
			$data['surname'] = htmlspecialchars(trim($data['surname']));
			$data['emailaddress'] = trim($data['emailaddress']);

			// If it looks like an e-mail address...
			if (!empty($data['emailaddress']) && !preg_match('~^[^ ]+@[^ ]+\.[a-z]+$~', $data['emailaddress']))
				return $formview->adopt(new Alert('Email addresses invalid', 'The email address you entered is not a valid email address.', 'danger'));
			// Check whether email address is already linked to an account in the database -- just not to the account we happen to be editing, of course.
			elseif (!empty($data['emailaddress']) && $user->getEmailAddress() !== $data['emailaddress'] && Member::exists($data['emailaddress']))
				return $formview->adopt(new Alert('Email address already in use', 'Another account is already using this e-mail address.', 'danger'));

			// Changing passwords?
			if (!empty($data['password1']) && !empty($data['password2']))
			{
				if (strlen($data['password1']) < 6 || !preg_match('~[^A-z]~', $data['password1']))
					return $formview->adopt(new Alert('Password not acceptable', 'Please use a password that is at least six characters long and contains at least one non-alphabetic character (e.g. a number or symbol).', 'danger'));
				elseif ($data['password1'] !== $data['password2'])
					return $formview->adopt(new Alert('Passwords do not match', 'The passwords you entered do not match. Please try again.', 'danger'));

				// Keep just the one.
				$data['password'] = $data['password1'];
				unset($data['password1'], $data['password2']);
				$formview->adopt(new Alert('Your password has been changed', 'Next time you log in, you can use your new password to authenticate yourself.', 'success'));
			}
			else
				$formview->adopt(new Alert('Your account settings have been saved', 'Thank you for keeping your information current.', 'success'));

			$user->update($data);
		}
	}
}