<?php
namespace Modules\Login\Controllers;

use App\Controllers\BaseController;
use Modules\Login\Models\model_login;
use Store\DataHelper;
use Constant\ConstantHelper;
use Login\LoginHelper;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

class Login extends BaseController {
	public function __construct() {
		$this->dataHelper 		= new DataHelper;
		$this->constantHelper	= new ConstantHelper;
		$this->loginHelper 		= new LoginHelper;
		$this->model_login  	= new Model_login;
	}

	public function index() {
		$this->constantHelper->CNT_dataConstant();
		$u = service('session')->get('usuario_logado');

		if(isset($u) AND !empty($u)) {
			return redirect()->to(BASECMSURL . "pagina-inicial");
		}
		else {
			$this->_login('Modules\Login\Views\view_login');
		}
	}

	public function autenticar() {
		$emailConfig = $this->dataHelper->DH_getEmailConfig();
		$config 		 = $this->dataHelper->DH_getCmsConfig();
		$plataforma  = $this->loginHelper->LG_getPlataforma();

		if(!empty($_POST['data_twofa'])) {

			/*
			* Auth por aplicativo
			*/

			$dados 	= service('request')->getPost('data_twofa');
			$dados 	= @unserialize(base64_decode(service('encrypter')->decrypt(hex2bin($dados), ['key' => getenv('ENCRYPTKEY')])));
			$codigo = service('request')->getPost('codigo');			

			if($this->dataHelper->DH_validaToken2FA($dados['id_usuario'], $codigo)) {
				$dadosUsuario = $this->model_login->getUsuario('', $dados['id_usuario']);

				if(!empty($dadosUsuario)) {
					$senha 			= service('encrypter')->decrypt(hex2bin($dadosUsuario->senha), ['key' => getenv('ENCRYPTKEY')]);
					$resultado 	= $this->model_login->autenticar($dadosUsuario->email, $senha);

					if($resultado == '1') {
						$arrResult = array ('response' => 'success', 'successMessage' => 'Tudo certo com os dados informados.', 'errorMessage' => '', 'log' => '');
					}
					else {
						$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-APP-2FA-0001', 'log' => '');
					}
				}
				else {
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-APP-2FA-0002', 'log' => '');
				}
			}
			elseif($dados AND !empty($dados) AND !empty($codigo)) {

				/*
				* Auth por e-mail
				*/

				$start 	= date_create_from_format('Y-m-d H:i:s', date('Y-m-d H:i:s'));
				$end 		= date_create_from_format('Y-m-d H:i:s', date('Y-m-d H:i:s', strtotime($dados['validade'])));
				$diff 	= date_diff($end,$start);

				if($diff->y == '0' AND $diff->m == '0' AND $diff->d == '0' AND $diff->h == '0' AND $diff->i < '10') {
					if($codigo == $dados['codigo']) {
						$dadosUsuario = $this->model_login->getUsuario('', $dados['id_usuario']);

						if(!empty($dadosUsuario)) {
							$senha 		 = service('encrypter')->decrypt(hex2bin($dadosUsuario->senha), ['key' => getenv('ENCRYPTKEY')]);
							$resultado = $this->model_login->autenticar($dadosUsuario->email, $senha);
							
							if($resultado == '1') {
								$arrResult = array ('response' => 'success', 'successMessage' => 'Tudo certo com os dados informados.', 'errorMessage' => '', 'log' => '');
							}
							else {
								$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-MAIL-2FA-0001', 'log' => '');
							}
						}
						else {
							$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-MAIL-2FA-0002', 'log' => '');
						}
					}
					else {
						$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Codigo invalido!<br> Cód. Erro: #AUTH-MAIL-2FA-0003', 'log' => '');
					}
				}
				else {
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Codigo expirado!<br> Cód. Erro: #AUTH-MAIL-2FA-0004', 'log' => '');
				}
			}
			else {
				die("------------------------------------------------------------[ 3 ]");
				$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-MAIL-2FA-0005', 'log' => '');
			}

			echo json_encode($arrResult);
			die();
		}

		/*
		* Gera token para login com 
		* autenticação de dois fatores
		* por e-mail
		*
		* AND ( $_POST['email'] != 'root@oliverdigital.com.br' AND $_POST['email'] != 'admin@oliverdigital.com.br' )
		*
		*/

		if($config->form_twofa == 1) {
			require PUBLICFOL . 'assets/vendor/PHPMailer-6.6.3/src/Exception.php';
			require PUBLICFOL . 'assets/vendor/PHPMailer-6.6.3/src/PHPMailer.php';
			require PUBLICFOL . 'assets/vendor/PHPMailer-6.6.3/src/SMTP.php';

			$email 	= service('request')->getVar('email', FILTER_SANITIZE_EMAIL);
			$senha  = service('request')->getPost('senha');

			$usuario 				= $this->model_login->getUsuario($email);
			$usuario->senha = service('encrypter')->decrypt(hex2bin($usuario->senha), ['key' => getenv('ENCRYPTKEY')]);

			if(!empty($usuario) AND $usuario->senha === $senha AND $email === $email) {
				$dados['id_usuario'] 	= $usuario->id;
				$dados['codigo'] 			= $this->random_str_generator(6, 'ativo');
				$codigo 							= $dados['codigo']; 
				$dados['validade'] 		= date('Y-m-d H:i:s', strtotime('+10 minutes'));
				$validade 						= $dados['validade']; 

				$dados = bin2hex(service('encrypter')->encrypt(base64_encode(serialize($dados)), ['key' => getenv('ENCRYPTKEY')]));

				$data = array(
					"data_atual"    => date('d/m/Y H:i:s'),
					"email_cabec" 	=> (!empty($config->imagem)) ? $config->imagem : "",
					"codigo"				=> $codigo,
					"validade"			=> $validade,
				);

				$html = view('Modules\Login\Views\view_email_twofa', $data);

				try {
					$mail = new PHPMailer(true);

					$mail->isSMTP();

					if(!empty($emailConfig->e_debug) AND $emailConfig->e_debug == 1) {
						$mail->SMTPDebug 	= SMTP::DEBUG_SERVER;
					}
					else {
						$mail->SMTPDebug 	= 0;
					}

					$mail->Host = $emailConfig->e_host;
					$mail->Port = $emailConfig->e_port;

					if(!empty($emailConfig->e_secure) AND $emailConfig->e_secure != 'none') {
						$mail->SMTPAuth   = true;
						$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
					}

					$mail->Username = $emailConfig->e_username;
					$mail->Password = $emailConfig->e_password;

					$mail->setFrom($emailConfig->e_from, $emailConfig->e_from_name);
					$mail->addAddress($email);

					$mail->isHTML(true);

					$mail->CharSet = 'utf-8';
					$mail->Subject = "Codigo de acesso - " . date('d/m/Y H:i:s');
					$mail->Body    = $html;

					if(@$mail->send()) {
						$arrResult = array ('twofa' => 'active', 'data' => $dados);
						echo json_encode($arrResult);
						die();
					}
					else {
						$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Houve um erro ao enviar enviar os dados.<br> Cód. Erro: #AUTH-SEND-MAIL-2FA-0001', 'log' => '');
						echo json_encode($arrResult);
						die();
					}
				}
				catch (Exception $e) {
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Houve um erro ao enviar enviar os dados.<br> Cód. Erro: #PHPMAILER', 'log' => $mail->ErrorInfo);
					echo json_encode($arrResult);
					die();
				}
			}
			else {
				$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-SEND-MAIL-2FA-0002', 'log' => '');
			}

			echo json_encode($arrResult);
		}
		else {

			/*
			* Login sem autenticação de dois fatores
			*/

			if($config->form_login == 1) {

				/*
				* Google reCaptcha ::: Ativado
				*/

				if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])) {
					$secret 	 = $plataforma->recaptcha_secreta;
					$resultado = 0;

					if( ini_get('allow_url_fopen') ) {
						$verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=' . $secret . '&response=' . $_POST['g-recaptcha-response']);
						$responseData   = json_decode($verifyResponse);
					} 
					elseif( function_exists('curl_version') ) {
						$fields = array(
							'secret'    =>  $secret,
							'response'  =>  $_POST['g-recaptcha-response'],
							'remoteip'  =>  $_SERVER['REMOTE_ADDR']
						);

						$verifyResponse = curl_init("https://www.google.com/recaptcha/api/siteverify");

						curl_setopt($verifyResponse, CURLOPT_RETURNTRANSFER, true);
						curl_setopt($verifyResponse, CURLOPT_TIMEOUT, 15);
						curl_setopt($verifyResponse, CURLOPT_POSTFIELDS, http_build_query($fields));

						$responseData = json_decode(curl_exec($verifyResponse));

						curl_close($verifyResponse);
					} 
					else {
						$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Houve um problema na tentativa de acesso, tente novamente mais tarde.<br> Cód. Erro: #AUTH-RECAPTCHA-0001', 'log' => '');
						echo json_encode($arrResult);
						die();
					}

					if(isset($responseData) AND !empty($responseData)) {
						if(isset($responseData->score) AND $responseData->score < 0.5) {
							$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Me parece que você não é humano.<br> Cód. Erro: #AUTH-RECAPTCHA-0002', 'log' => '');
						} 
						else {
							if(isset($responseData->success) AND !empty($responseData->success)) {
								try {
									$email 			 = service('request')->getVar('email', FILTER_SANITIZE_EMAIL);
									$senha       = service('request')->getPost('senha');

									$resultado   = $this->model_login->autenticar($email, $senha);

									if($resultado == '0') {
										$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Algo deu errado na validação dos dados.<br> Cód. Erro: #AUTH-RECAPTCHA-0003', 'log' => '');
									}

									if($resultado == '1') {
										$arrResult = array ('response' => 'success', 'successMessage' => 'Tudo certo com os dados informados.', 'errorMessage' => '', 'log' => '');
									} 

									if($resultado == '2') {
										$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'E-mail e/ou senha, incorretos.<br> Cód. Erro: #AUTH-RECAPTCHA-0005', 'log' => '');
									} 

									if($resultado == '3') {
										$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'E-mail e/ou senha, incorretos.<br> Cód. Erro: #AUTH-RECAPTCHA-0006', 'log' => '');
									} 
								} 
								catch (Exception $e) {
									$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => $e->errorMessage(), 'log' => '1');
								} 
								catch (\Exception $e) {
									$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => $e->getMessage(), 'log' => '2');
								}

								echo json_encode($arrResult);
								die();
							} 
							else {
								$e = (array)$responseData;
								$m = "";

								foreach ($e['error-codes'] as $k => $r) {
									$m .= $r;

									if($k >= 1) {
										$m .= "<br/>";
									}
								}

								$arrResult = array ('response' => 'error', 'successMessage' => '','errorMessage' => 'Houve um problema no envio, por favor tente novamente mais tarde.<br> Cód. Erro: #AUTH-RECAPTCHA-0007', 'log' => $m);
							}
						}
					}
					else {
						$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Não foi possível verificar seus dados, tente novamente mais tarde.<br> Cód. Erro: #AUTH-RECAPTCHA-0008', 'log' => '');
					}
				} 
				else { 
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Houve um problema no envio, por favor tente novamente mais tarde.<br> Cód. Erro: #AUTH-RECAPTCHA-0009', 'log' => '');
				}
			}
			else {

	    	/*
				* Google reCaptcha ::: Desativado
				*/

				$email 			 = service('request')->getVar('email', FILTER_SANITIZE_EMAIL);
				$senha       = service('request')->getPost('senha');

				$resultado   = $this->model_login->autenticar($email, $senha);

				if($resultado == '0') {
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'Algo deu errado na validação dos dados.<br> Cód. Erro: #AUTH-NOT-RECAPTCHA-0001', 'log' => '');
				}

				if($resultado == '1') {
					$arrResult = array ('response' => 'success', 'successMessage' => 'Tudo certo com os dados informados.', 'errorMessage' => '', 'log' => '');
				} 

				if($resultado == '2') {
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'E-mail e/ou senha, incorretos.<br> Cód. Erro: #AUTH-NOT-RECAPTCHA-0002', 'log' => '');
				} 

				if($resultado == '3') {
					$arrResult = array ('response' => 'error', 'successMessage' => '', 'errorMessage' => 'E-mail e/ou senha, incorretos.<br> Cód. Erro: #AUTH-NOT-RECAPTCHA-0003', 'log' => '');
				} 
			}
			echo "<pre>";
			print_r($arrResult);
			echo "</pre>";
			die("------------------------------------------------------------[ x ]");

			echo json_encode($arrResult);
		}
	}

	function random_str_generator($len_of_gen_str, $number=null){
		if(!empty($number)) {
			$chars = "0123456789";
		}else {
			$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%&*(){}[]";
		}
		$var_size = strlen($chars);
		$random_str = '';
		for( $x = 0; $x < $len_of_gen_str; $x++ ) {  
			$random_str .= $chars[ rand( 0, $var_size - 1 ) ];  
		}
		return $random_str;
	}

	public function recuperaSenha() {
		require PUBLICFOL . 'assets/vendor/PHPMailer-6.6.3/src/Exception.php';
		require PUBLICFOL . 'assets/vendor/PHPMailer-6.6.3/src/PHPMailer.php';
		require PUBLICFOL . 'assets/vendor/PHPMailer-6.6.3/src/SMTP.php';

		$email = service('request')->getPost('email');

		$consulta = $this->model_login->getUsuario($email);

		if(!empty($consulta)) {
			$novaSenha = $this->random_str_generator(12);
			$senhaCriptografada = bin2hex(service('encrypter')->encrypt($novaSenha, ['key' => getenv('ENCRYPTKEY')]));
			$this->model_login->atualizaSenha($senhaCriptografada, $consulta->id, $consulta->titulo);

			$config = $this->dataHelper->DH_getCmsConfig();

			$data = array(
				"data_atual"    => date('d/m/Y H:i:s'),
				"email_cabec" 	=> (!empty($config->imagem)) ? $config->imagem : "",
				"url"			=> BASEURL,
				"email"			=> $email,
				"senha"         => $novaSenha,
			);

			$html = view('Modules\Login\Views\view_email_recupera_senha', $data);

			try {
				$mail = new PHPMailer(true);

				$mail->isSMTP();

				if(!empty($config->e_debug) AND $config->e_debug == 1) {
					$mail->SMTPDebug 	= SMTP::DEBUG_SERVER;
				}
				else {
					$mail->SMTPDebug 	= 0;
				}

				$mail->Host       	= $config->e_host;
				$mail->Port       	= $config->e_port;

				if(!empty($config->e_secure) AND $config->e_secure != 'none') {
					$mail->SMTPAuth   = true;
					$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
				}

				$mail->Username   	= $config->e_username;
				$mail->Password   	= $config->e_password;

				$mail->setFrom($config->e_from, $config->e_from_name);
				$mail->addAddress($email);

				$mail->isHTML(true);

				$mail->CharSet = 'utf-8';
				$mail->Subject = "Nova senha - " . date('d/m/Y H:i:s');
				$mail->Body    = $html;

				if($mail->send()) {
					$arrResult = array('error' => '0', 'message' => 'Os dados de acesso foram enviados no e-mail <strong>'.$email.'</strong>!');
					echo json_encode($arrResult);
					die();
				}
				else {
					$arrResult = array('error' => '1', 'message' => 'Houve um erro ao enviar os dados de acesso');
					echo json_encode($arrResult);
					die();
				}
			}
			catch (Exception $e) {
				echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
			}
		}
		else {
			$arrResult = array('error' => '1', 'message' => 'E-mail invalido!');
			echo json_encode($arrResult);
			die();
		}
	}

	public function deslogar() {
		$this->constantHelper->CNT_dataConstant();
		$u = service('session')->get('usuario_logado');
		$r = $this->model_login->deslogar($u);

		if($r) {
			service('session')->destroy();
			service('response')->setCookie('homologacao', 'disabled', time()-3600);

			return redirect()->to(BASECMSURL . 'login');
		}
	}
}
