<?php

namespace Myth\Auth\Controllers;

use Config\Email;
use CodeIgniter\Controller;
use CodeIgniter\I18n\Time;
use Myth\Auth\Entities\User;
use Myth\Auth\Models\UserModel;
use Myth\Auth\Models\LoginModel;
use \Config\Services;



class AuthController extends Controller
{
	protected $auth;
	/**
	 * @var Auth
	 */
	protected $config;

	/**
	 * @var \CodeIgniter\Session\Session
	 */
	protected $session;

	public function __construct()
	{
		// Most services in this controller require
		// the session to be started - so fire it up!
		$this->session = service('session');

		$this->config = config('Auth');
		$this->auth = service('authentication');
	}

	//--------------------------------------------------------------------
	// Login/out
	//--------------------------------------------------------------------

	/**
	 * Displays the login form, or redirects
	 * the user to their destination/home if
	 * they are already logged in.
	 */



	public function login()
	{
		$usr = model(UserModel::class);

		$db = \Config\Database::connect();
		$lg = model(LoginModel::class);

		// No need to show a login form if the user
		// is already logged in.

		if ($this->auth->check()) {
			//$redirectURL = session('redirect_url') ?? site_url('/d1');
			$redirectURL = '/d1';
			unset($_SESSION['redirect_url']);

			return redirect()->to($redirectURL);
		}

		$ua = $_SERVER['HTTP_USER_AGENT'];
		$ip = Services::request()->getIPAddress();
		$tg = date('Y-m-d H:i:s');
		$attempt = $lg->attempt($ua, $ip, $tg);
		if ($attempt == 1) {
			// Set a return URL if none is specified
			//$_SESSION['redirect_url'] = session('redirect_url') ?? previous_url() ?? site_url('/d1');
			$_SESSION['redirect_url'] = site_url('/d1');

			return $this->_render($this->config->views['login'], ['config' => $this->config, 'attempt' => 1]);
		} else {
			return $this->_render($this->config->views['login'], ['config' => $this->config, 'attempt' => 0]);
		}
	}

	/**
	 * Attempts to verify the user's credentials
	 * through a POST request.
	 */
	public function attemptLogin()
	{
		$lg = model(LoginModel::class);

		helper('erb');
		$rules = [
			'login'	=> 'required',
			'password' => 'required',
		];
		if ($this->config->validFields == ['email']) {
			$rules['login'] .= '|valid_email';
		}

		if (!$this->validate($rules)) {
			return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
		}

		$login = $this->request->getPost('login');
		$password = $this->request->getPost('password');
		$remember = (bool)$this->request->getPost('remember');


		//check $login sedang terpakai tidak 
		if ($lg->alreadyLogin($login) == 1) {
			return $this->_render($this->config->views['login'], ['config' => $this->config, 'attempt' => 2]);

		} else {
			// Determine credential type
			$type = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';

			// Try to log them in...
			if (!$this->auth->attempt([$type => $login, 'password' => $password], $remember)) {
				return redirect()->back()->withInput()->with('error', $this->auth->error() ?? lang('Auth.badAttempt'));
			}

			// Is the user being forced to reset their password?
			if ($this->auth->user()->force_pass_reset === true) {
				return redirect()->to(route_to('reset-password') . '?token=' . $this->auth->user()->reset_hash)->withCookies();
			}

			$redirectURL = session('redirect_url') ?? site_url('/d1');
			unset($_SESSION['redirect_url']);

			$session = \Config\Services::session();
			$user_data = hlp_userdata();


			$session->set('user_data', $user_data);

			return redirect()->to($redirectURL)->withCookies()->with('message', lang('Auth.loginSuccess'));
		}
	}

	/**
	 * Log the user out.
	 */
	public function logout()
	{
		if ($this->auth->check()) {
			$this->auth->logout();
		}

		return redirect()->to(site_url('/'));
	}

	//--------------------------------------------------------------------
	// Register
	//--------------------------------------------------------------------

	/**
	 * Displays the user registration page.
	 */


	public function register()
	{
		helper('erb_helper');

		//   check if already logged in.
		// Check if registration is allowed
		//		return $this->_render($this->config->views['register'], ['config' => $this->config]);
		return $this->_render($this->config->views['register'], ['config' => $this->config]);
		//		return $this->_render($this->config->views['kuser'], ['config' => $this->config,'data'=>$data])

	}


	public function attemptRegister()
	{

		$users = model(UserModel::class);

		// Validate here first, since some things,
		// like the password, can only be validated properly here.
		$rules = [
			'username'  	=> 'required|alpha_numeric_space|min_length[3]|is_unique[users.username]',
			//'email'			=> 'required|valid_email|is_unique[users.email]',
			'password'	 	=> 'required|strong_password',
			'pass_confirm' 	=> 'required|matches[password]',
		];

		// Save the user
		$allowedPostFields = array_merge(['password'], $this->config->validFields, $this->config->personalFields);
		$user = new User($this->request->getPost($allowedPostFields));

		$this->config->requireActivation !== false ? $user->generateActivateHash() : $user->activate();

		// Ensure default group gets assigned if set
		if (!empty($this->config->defaultUserGroup)) {
			$users = $users->withGroup($this->config->defaultUserGroup);
		}

		if (!$users->save($user)) {
			return redirect()->back()->withInput()->with('errors', $users->errors());
		}
		return;
	}

	/**
	 * Displays the forgot password form.
	 */
	public function forgotPassword()
	{
		if (!$this->config->activeResetter) {
			return redirect()->route('login')->with('error', lang('Auth.forgotDisabled'));
		}

		return $this->_render($this->config->views['forgot'], ['config' => $this->config]);
	}

	/**
	 * Attempts to find a user account with that password
	 * and send password reset instructions to them.
	 */
	public function attemptForgot()
	{
		if (!$this->config->activeResetter) {
			return redirect()->route('login')->with('error', lang('Auth.forgotDisabled'));
		}

		$users = model(UserModel::class);

		$user = $users->where('email', $this->request->getPost('email'))->first();

		if (is_null($user)) {
			return redirect()->back()->with('error', lang('Auth.forgotNoUser'));
		}

		// Save the reset hash /
		$user->generateResetHash();
		$users->save($user);

		$resetter = service('resetter');
		$sent = $resetter->send($user);

		if (!$sent) {
			return redirect()->back()->withInput()->with('error', $resetter->error() ?? lang('Auth.unknownError'));
		}

		return redirect()->route('reset-password')->with('message', lang('Auth.forgotEmailSent'));
	}

	/**
	 * Displays the Reset Password form.
	 */
	public function resetPassword()
	{
		if (!$this->config->activeResetter) {
			return redirect()->route('login')->with('error', lang('Auth.forgotDisabled'));
		}

		$token = $this->request->getGet('token');

		return $this->_render($this->config->views['reset'], [
			'config' => $this->config,
			'token'  => $token,
		]);
	}

	/**
	 * Verifies the code with the email and saves the new password,
	 * if they all pass validation.
	 *
	 * @return mixed
	 */
	public function attemptReset()
	{
		if (!$this->config->activeResetter) {
			return redirect()->route('login')->with('error', lang('Auth.forgotDisabled'));
		}

		$users = model(UserModel::class);

		// First things first - log the reset attempt.
		$users->logResetAttempt(
			$this->request->getPost('email'),
			$this->request->getPost('token'),
			$this->request->getIPAddress(),
			(string)$this->request->getUserAgent()
		);

		$rules = [
			'token'		=> 'required',
			'email'		=> 'required|valid_email',
			'password'	 => 'required|strong_password',
			'pass_confirm' => 'required|matches[password]',
		];

		if (!$this->validate($rules)) {
			return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
		}

		$user = $users->where('email', $this->request->getPost('email'))
			->where('reset_hash', $this->request->getPost('token'))
			->first();

		if (is_null($user)) {
			return redirect()->back()->with('error', lang('Auth.forgotNoUser'));
		}

		// Reset token still valid?
		if (!empty($user->reset_expires) && time() > $user->reset_expires->getTimestamp()) {
			return redirect()->back()->withInput()->with('error', lang('Auth.resetTokenExpired'));
		}

		// Success! Save the new password, and cleanup the reset hash.
		$user->password 		= $this->request->getPost('password');
		$user->reset_hash 		= null;
		$user->reset_at 		= date('Y-m-d H:i:s');
		$user->reset_expires    = null;
		$user->force_pass_reset = false;
		$users->save($user);

		return redirect()->route('login')->with('message', lang('Auth.resetSuccess'));
	}

	/**
	 * Activate account.
	 *
	 * @return mixed
	 */
	public function activateAccount()
	{
		$users = model(UserModel::class);

		// First things first - log the activation attempt.
		$users->logActivationAttempt(
			$this->request->getGet('token'),
			$this->request->getIPAddress(),
			(string) $this->request->getUserAgent()
		);

		$throttler = service('throttler');

		if ($throttler->check($this->request->getIPAddress(), 2, MINUTE) === false) {
			return service('response')->setStatusCode(429)->setBody(lang('Auth.tooManyRequests', [$throttler->getTokentime()]));
		}

		$user = $users->where('activate_hash', $this->request->getGet('token'))
			->where('active', 0)
			->first();

		if (is_null($user)) {
			return redirect()->route('login')->with('error', lang('Auth.activationNoUser'));
		}

		$user->activate();

		$users->save($user);

		return redirect()->route('login')->with('message', lang('Auth.registerSuccess'));
	}

	/**
	 * Resend activation account.
	 *
	 * @return mixed
	 */
	public function resendActivateAccount()
	{
		if ($this->config->requireActivation === false) {
			return redirect()->route('login');
		}

		$throttler = service('throttler');

		if ($throttler->check($this->request->getIPAddress(), 2, MINUTE) === false) {
			return service('response')->setStatusCode(429)->setBody(lang('Auth.tooManyRequests', [$throttler->getTokentime()]));
		}

		$login = urldecode($this->request->getGet('login'));
		$type = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';

		$users = model(UserModel::class);

		$user = $users->where($type, $login)
			->where('active', 0)
			->first();

		if (is_null($user)) {
			return redirect()->route('login')->with('error', lang('Auth.activationNoUser'));
		}

		$activator = service('activator');
		$sent = $activator->send($user);

		if (!$sent) {
			return redirect()->back()->withInput()->with('error', $activator->error() ?? lang('Auth.unknownError'));
		}

		// Success!
		return redirect()->route('login')->with('message', lang('Auth.activationSuccess'));
	}

	protected function _render(string $view, array $data = [])
	{
		return view($view, $data);
	}

	public function user_kelola()
	{
		helper('erb_helper');
		//		$db = \Config\Database::connect();
		//		$query = $db->query("select * from users");
		//		$data = $query->getResultArray();
		$data = '';
		return $this->_render($this->config->views['kuser'], ['config' => $this->config, 'data' => $data]);
	}

	public function user_gantipass()
	{
		$session = \Config\Services::session();
		helper('erb_helper');
		//		$u = $session->get('user_data');
		//		echo '<pre>';print_r($u);echo '</pre>';
		$data = '';
		return $this->_render($this->config->views['kuserpass'], ['config' => $this->config, 'data' => $data]);
	}



	function user_data()
	{
		$page = 1;
		$rows = 50;
		if (isset($_POST['page'])) $page = $_POST['page'];
		if (isset($_POST['rows'])) $rows = $_POST['rows'];
		$offset = ($page - 1) * $rows;

		//$picpass = "/assets/images/".FLD_APP."/resetpass.png";
		//$picactive0 = "/assets/images/".FLD_APP."/userdis.png";
		//$picactive1 = "/assets/images/".FLD_APP."/useren.png";

		$picpass = '<span class="fa fa-key" style="font-size:20px" data-toggle="tooltip" data-placement="top" title="Ubah Password"></span>';
		$picedit = '<span class="fa fa-edit" style="font-size:20px" data-toggle="tooltip" data-placement="top" title="Edit Data"></span>';
		$pichapus = '<span class="fa fa-trash" style="font-size:20px;color:red;" data-toggle="tooltip" data-placement="top" title="Hapus Data"></span>';
		$picactive0 = '<span class="fa fa-user-times" style="font-size:20px;color:red;" data-toggle="tooltip" data-placement="top" title="Toggle Aktif/Block"></span>';
		$picactive1 = '<span class="fa fa-user" style="font-size:20px" data-toggle="tooltip" data-placement="top" title="Toggle Aktif/Block"></span>';

		$qf = '';
		if (isset($_POST['filterRules'])) 	$filter = json_decode($_POST['filterRules'], true);
		else $filter = '';
		if ($filter !== '') {
			foreach ((array)$filter as $r) {
				if ($r['field'] == 'username') {
					if ($r['value'] !== '')
						$qf = $qf . " and a.username like  '%$r[value]%'  ";
				} else 
				if ($r['field'] == 'realname') {
					if ($r['value'] !== '')
						$qf = $qf . " and a.realname like  '%$r[value]%' ";
				}
			}
		}
		$db = \Config\Database::connect();

		$q = "select a.user_id,a.username,a.realname,a.active,a.nip,b.user_photo,b.user_phone,b.jbt_nama,b.jbt_uk,b.jbt_pangkat,b.email,c.group_id, d.name as role,d.id as role,d.name as rolet from users a left join users_profile b on a.user_id=b.user_id
        left join auth_groups_users c on a.user_id=c.user_id left join auth_groups d on c.group_id=d.id where 1 " . $qf . " order by a.user_id desc " . " limit  $offset,$rows ";


		$query = $db->query($q);
		$data = $query->getResultArray();

		foreach ($data as $k => $v) {
			$usernamet = $v['username'];
			if ($v['role'] == 'pegawai')
				$usernamet = '<a href="/profile/' . $v['user_id'] . '" target="_blank">' . $v['username'] . '</a>';

			if ($v['active'] == 1) $picactive = $picactive1;
			else $picactive = $picactive0;
			$data[$k]['aksi'] =
				'<div align="center"><a href="#"  class="easyui-linkbutton" onclick="editUser(' . $v['user_id'] . ')">' . $picedit . '</a>&nbsp&nbsp&nbsp<a href="#"  class="easyui-linkbutton" onclick="destroyUser(' . $v['user_id'] . ')">' . $pichapus . '</a>&nbsp&nbsp&nbsp<a href="#"  class="easyui-linkbutton" onclick="setpassword(' . $v['user_id'] . ')">' . $picpass . '</a>&nbsp&nbsp&nbsp 
				<a href="#"  class="easyui-linkbutton" onclick="setactive(' . $v['user_id'] . ',' . $v['active'] . ')">' . $picactive . '</a>
				</div>';
			$data[$k]['usernamet'] = $usernamet;

			if ($v['nip'] == '' || $v['nip'] == 0) $data[$k]['nip'] = '';
		}

		$q = $db->query("select a.user_id from users a  ");
		$d['total'] = $q->getNumRows();
		//		$d['total'] = 15;

		$dataf = array();
		foreach ($data as $k => $v) {
			$dataf[$v['user_id']][] = $v;
		}

		$user_id = 9999;
		foreach ($data as $k => $v) {
			if ($v['user_id'] == $user_id) unset($data[$k]);
			else $user_id = $v['user_id'];
		}
		$data = array_values($data);

		$d['rows'] = $data;

		echo json_encode($d);
	}

	function user_simpan()
	{
		$db = \Config\Database::connect();

		$db->transStart();
		$email = "default@gmail.com";
		$username = $_POST['username'];
		$password = $_POST['password'];

		$realname = $_POST['realname'];
		$user_phone = $_POST['user_phone'];
		$nip = $_POST['nip'];
		$active = $_POST['active'];
		$role = $_POST['role'];
		$email = $_POST['email'];

		$user = new user(array('password' => $password));
		$user->password_hash;
		$password =  $user->password_hash;


		$q = "insert into users (username,email,realname,nip,active,password_hash) values (:username:,:email:,:realname:,:nip:,:active:,:password:)";
		$db->query($q, [
			'username' => $username,
			'email'	=> $email,
			'realname' => $realname,
			'nip' => $nip,
			'active'   => $active,
			'password' => $password
		]);

		$insertedid = $db->insertID();

		//insert to auth_groups_users
		$q = "insert into auth_groups_users (group_id,user_id) values (:group_id:,:user_id:) on duplicate key update group_id = :group_id:, user_id=:user_id: ";
		$db->query($q, ['group_id' => $role, 'user_id' => $insertedid]);

		//insert to users_profile

		$q = "insert into users_profile (
		user_id,
		user_phone,
		email) 
	values (
		:user_id:,
		:user_phone:,
		:email:)";

		$db->query($q, [
			'user_id' => $insertedid,
			'user_phone' => $user_phone,
			'email' => $email
		]);

		$db->transComplete();
		if ($db->transStatus() === false) {
			echo json_encode(array('errorMsg' => 'Sila Ulangi Lagi'));
		} else {
			echo json_encode(array('sucess' => true));
		}
	}


	function user_update($user_id)
	{
		$db = \Config\Database::connect();

		$db->transStart();
		$realname = $_POST['realname'];
		$user_phone = $_POST['user_phone'];
		$nip = $_POST['nip'];
		$active = $_POST['active'];
		$role = intval($_POST['role']);
		$email = $_POST['email'];

		$q = "update users set realname = :realname:,nip=:nip:,active=:active: where user_id=:user_id: ";
		$db->query($q, [
			'realname' => $realname,
			'active'   => $active,
			'nip'   => $nip,
			'user_id' => $user_id
		]);

		//insert to auth_groups_users	
		if ($role > 0) {
			$q = "insert into auth_groups_users (group_id,user_id) values (:group_id:,:user_id:) on duplicate key update group_id = :group_id:, user_id=:user_id: ";

			$db->query($q, ['group_id' => $role, 'user_id' => $user_id]);
		}

		$q = "insert into users_profile (user_id,user_phone,email) 
	values (:user_id:,:user_phone:,:email:)
	on duplicate key update user_id=:user_id:,user_phone=:user_phone:,email=:email:";

		$db->query($q, ['user_id' => $user_id, 'user_phone' => $user_phone, 'email' => $email]);

		$db->transComplete();
		if ($db->transStatus() === FALSE) {
			echo json_encode(array('errorMsg' => 'Sila Ulangi Lagi'));
		}

		echo json_encode(array('sucess' => true));
	}

	function user_destroy()
	{
		$db = \Config\Database::connect();
		$user_id = $_POST['user_id'];
		$db->query("delete from users where user_id = :user_id:", ['user_id' => $user_id]);
		echo json_encode(array('success' => true));
	}

	function password_simpan()
	{
		$db = \Config\Database::connect();
		$password = $_POST['password'];
		$user_id = $_POST['user_id'];
		$user = new user(array('password' => $password));
		$user->password_hash;
		$password =  $user->password_hash;

		$db->query("update users set password_hash = :password: where user_id = :user_id:", ['password' => $password, 'user_id' => $user_id]);

		echo json_encode(array('success' => true));
	}

	function passwordganti_simpan()
	{
		$session = \Config\Services::session();
		helper('erb_helper');
		$db = \Config\Database::connect();
		$u = $session->get('user_data');
		$user_id = $u['user_id'];
		$username = $u['username'];

		$password = $this->request->getPost('password');
		$passwordold = $this->request->getPost('passwordold');

		//Jika status = 0, berarti password lama salah,  status=1, password lama ok
		if (!$this->auth->attempt(['username' => $username, 'password' => $passwordold], 0)) $status = 0;
		else $status = 1;
		if ($status == 1) {
			$user = new user(array('password' => $password));
			$user->password_hash;
			$password =  $user->password_hash;

			$db->query("update users set password_hash = :password: where user_id = :user_id:", ['password' => $password, 'user_id' => $user_id]);

			echo json_encode(array('success' => true, 'uid' => $user_id, 'uname' => $username, 'p' => $password, 'pold' => $passwordold, 'status' => $status));
		} else {
			echo json_encode(array('errorMsg' => 'Password lama tidak sesuai'));
		}
	}




	function setactive()
	{
		$db = \Config\Database::connect();
		$user_id = $_POST['user_id'];
		$status = $_POST['status'];
		$status = $status > 0 ? 0 : 1;
		echo $user_id . ' ' . $status;
		$db->query("update users set active = :active: where user_id = :user_id:", ['active' => $status, 'user_id' => $user_id]);
		echo json_encode(array('html' => 'berhasil'));
	}





	function db_active()
	{
		$d[0] = array('value' => 0, 'text' => 'Tidak Aktif');
		$d[1] = array('value' => 1, 'text' => 'Aktif');
		echo json_encode($d);
	}

	function db_role()
	{
		$db = \Config\Database::connect();
		$query = $db->query("select id as value,name as text from auth_groups ");
		$d = $query->getResultArray();
		echo json_encode($d);
	}

	function db_unitkerja()
	{
		$db = \Config\Database::connect();
		$query = $db->query('select id_unitkerja as value,nama_unitkerja as text from rb_unitkerja');
		$d = $query->getResultArray();
		echo json_encode($d);
	}
}
