<?php

/**
 * @package    JBusinessDirectory
 *
 * @author CMSJunkie http://www.cmsjunkie.com
 * @copyright  Copyright (C) 2007 - 2021 CMSJunkie. All rights reserved.
 * @license   https://www.gnu.org/licenses/agpl-3.0.en.html
 */
defined('_JEXEC') or die('Restricted access');

use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Factory;

class UserService
{

	/**
	 * Add new user if it does not existings on database
	 * @param unknown_type $data
	 * @return unknown
	 */
	public static function addUser($data)
	{
		$user = JBusinessUtil::getUser();
		if (!$user->id || $user->guest == 1) {
			$userObj = self::getUserByEmail($data["email"]);
			if (!empty($userObj->id)) {
				$userId = $userObj->id;
			} else {
				$userId = self::addJoomlaUser($data);
			}
		} else {
			$userId = $user->id;
		}

		return $userId;
	}

	/**
	 * Get user by its email address
	 *
	 * @param $email
	 * @return mixed
	 */
	public static function getUserByEmail($email)
	{
		$db		= JFactory::getDBO();
		$query = " SELECT * FROM #__users WHERE username = 	'" . trim($email) . "' OR email = '" . trim($email) . "'";
		$db->setQuery($query);
		$user =  $db->loadObject();

		return $user;
	}

	/**
	 * Returns the super user
	 *
	 * @param $userId
	 * @return mixed
	 */
	public static function isSuperUser($userId)
	{
		$user	= JBusinessUtil::getUser();
		$isroot	= $user->get('isRoot');
		return $isroot;
	}

	/**
	 * Generate a random password.
	 *
	 * @param $text
	 * @param bool $is_cripted
	 * @return mixed
	 */
	public static function generatePassword($text, $is_cripted = false)
	{
		$password 	=  $text;
		if ($is_cripted == false) {
			return $password;
		}
		jimport('joomla.user.helper');
		$password = JUserHelper::genRandomPassword(8);

		return $password;
	}

	/**
	 * Add user details and create a Joomla User
	 *
	 * @param $data
	 * @return mixed
	 */
	public static function addJoomlaUser($data)
	{

		//prepare user object
		$userdata = array(); // place user data in an array for storing.
		$name = explode('@', $data['email']);
		$userdata['name']  = $name[0];

		if (!empty($data["name"])) {
			$userdata['name'] = $data["name"];
		}

		$userdata['email'] = $data["email"];

		$userdata['username'] = $data["username"];
		if (empty($data["username"])) {
			$userdata['username'] = $data["email"];
		}

		//set password
		if (!empty($data["password"])) {
			$userdata['password'] = $data["password"];
		} else {
			$userdata['password'] = UserService::generatePassword($data["email"], true);
		}

		$userdata['password2'] = $userdata['password'];

		//create the user
		$userId = UserService::createUser($userdata);

		if (!is_numeric($userId)) {
			JFactory::getApplication()->enqueueMessage("Could not create user", 'error');
		} // something went wrong!!

		return $userId;
	}

	/**
	 *   Get any component's model
	 **/
	public static function getModel($name, $path = JPATH_COMPONENT_ADMINISTRATOR, $component = 'com_jbusinessdirectory')
	{
		// load some joomla helpers
		JLoader::import('joomla.application.component.model');
		// load the model file
		JLoader::import($name, $path . '/models');
		// return instance
		return JModelLegacy::getInstance($name, $component . 'Model');
	}

	/**
	 * Utility function creating an user
	 *
	 * @return void
	 */
	public static function createUser($user)
	{
		$appSetings = JBusinessUtil::getApplicationSettings();
		if ($appSetings->custom_registration) {
			return self::createCustomJoomlaUser($user);
		} else {
			return self::createDefaultJoomlaUser($user);
		}
	}

	/**
	 * Create an user based on the Joomla user registration mechanism
	 */
	public static function createDefaultJoomlaUser($user)
	{
		// load the user registration model
		$model = self::getModel('registration', JPATH_ROOT . '/components/com_users', 'Users');
		JForm::addFormPath(JPATH_ROOT . '/components/com_users' . '/forms');
		JForm::addFormPath(JPATH_ROOT . '/components/com_users' .  '/models/forms');
		JForm::addFieldPath(JPATH_ROOT . '/components/com_users' . '/models/fields');
		JForm::addFormPath(JPATH_ROOT . '/components/com_users' . '/model/form');
		JForm::addFieldPath(JPATH_ROOT . '/components/com_users' . '/model/field');

		// lineup new user data
		$data = array(
			'username' => $user['username'],
			'name' => $user['name'],
			'email1' => $user['email'],
			'password1' => $user['password'], // First password field
			'password2' => $user['password2'], // Confirm password field
			'block' => 0
		);
		// register the new user
		$result = $model->register($data);

		$userObj = self::getUserByEmail($user['email']);
		// if user is created
		if (!empty($userObj->id)) {
			JFactory::getApplication()->enqueueMessage(JText::_('LNG_USER_ACCOUNT_CREATED_VERIFIFICATION'), 'success');

			return $userObj->id;
		} else {
			JError::raiseWarning(100, $model->getError());
		}
		return $result;
	}


	public static function createCustomJoomlaUser($userdata)
	{

		$model = self::getModel('registration', JPATH_ROOT . '/components/com_users', 'Users');
		JForm::addFormPath(JPATH_ROOT . '/components/com_users' . '/forms');
		JForm::addFormPath(JPATH_ROOT . '/components/com_users' .  '/models/forms');
		JForm::addFieldPath(JPATH_ROOT . '/components/com_users' . '/models/fields');
		JForm::addFormPath(JPATH_ROOT . '/components/com_users' . '/model/form');
		JForm::addFieldPath(JPATH_ROOT . '/components/com_users' . '/model/field');

		$data =  (array) $model->getData();

		// Initialise the table with JUser.
		$user = new JUser;

		$temp = array(
			'username' => $userdata['username'],
			'name' => $userdata['name'],
			'email1' => $userdata['email'],
			'password1' => $userdata['password'], // First password field
			'password2' => $userdata['password2'], // Confirm password field
			'block' => 0
		);

		// Merge in the registration data.
		foreach ($temp as $k => $v) {
			$data[$k] = $v;
		}

		// Prepare the data for the user object.
		$data['email'] = JStringPunycode::emailToPunycode($data['email1']);
		$data['password'] = $data['password1'];


		$data['activation'] = "";
		$data['block'] = 0;
		$data['activate'] = 1;

		// Bind the data.
		if (!$user->bind($data)) {
			// $this->setError(JText::sprintf('COM_USERS_REGISTRATION_BIND_FAILED', $user->getError()));
			return false;
		}

		// Load the users plugin group.
		JPluginHelper::importPlugin('user');

		// Store the data.
		if (!$user->save()) {
			// $this->setError(JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $user->getError()));
			return false;
		}

		$activationCode = self::createActivationCode($user->id);

		self::sendActivationEmail($user->id, $activationCode);

		self::loginUser($user->id);

		return $user->id;
	}

	/**
	 * Create the activation code for the user
	 *
	 * @return void
	 */
	public static function createActivationCode($userId)
	{
		$activationCode = JApplicationHelper::getHash(JUserHelper::genRandomPassword());

		//store user profile with the activation code
		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$userProfileTable = JTable::getInstance("UserProfile", "JTable");

		$userProfileTable->id = 0;
		$userProfileTable->user_id = $userId;
		$userProfileTable->activation_code = $activationCode;
		$userProfileTable->verified = 0;

		if (!$userProfileTable->store()) {
			throw new Exception($userProfileTable->getError());
			return false;
		}

		return $activationCode;
	}


	/**
	 * Send the email activation to the user
	 */
	public static function sendActivationEmail($userId, $activation = null)
	{

		if (empty($userId)) {
			return null;
		}

		//load the activation code
		if (empty($activation)) {
			JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
			$userProfileTable = JTable::getInstance("UserProfile", "JTable");
			$userProfile = $userProfileTable->getUserProfile($userId);
			if (!empty($userProfile)) {
				$activation = $userProfile->activation_code;
			}
		}

		//if there is no activation code create one
		if (empty($activation)) {
			$activation = self::createActivationCode($userId);
		}

		$config = JFactory::getConfig();

		$data = array();
		$data["userId"] = $userId;
		$data['activation'] = $activation;
		$data['activationLink'] = JRoute::link(
			'site',
			'index.php?option=com_jbusinessdirectory&task=businessuser.verifyEmail&activation_token=' . $data['activation'],
			false,
			1,
			true
		);

		// Send the registration email.
		$result = EmailService::sendUserEmailConfirmationEmail($data);

		return $result;
	}

	/**
	 * Login user
	 *
	 * @param [type] $data
	 * @return void
	 */
	public static function loginUser($id)
	{
		$db = JFactory::getDbo();
		$q = "SELECT * FROM `#__users` WHERE id = " . $id;
		$newUser = $db->setQuery($q)->loadAssoc();

		PluginHelper::importPlugin('user');

		// Initiate log in
		$options = array('action' => 'core.login.site', 'remember' => false);
		if (Factory::getApplication()->triggerEvent('onUserLogin', array($newUser, $options))[0]) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Login a user with provided credentials
	 * 
	 */
	public static function loginUserWithCredentials($credentials)
	{
		$app    = JFactory::getApplication();
		$result = $app->login($credentials);

		return $result;
	}
}
