<?php
/**
 * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Application\Controller;

use Application\Master;
use Laminas\View\Model\ViewModel;

class UserController extends \Application\Master\GlobalActionController
{
    public function __construct($headScript)
    {

        $this->headScript   = $headScript;

        $this->deviceId     = null;
        $this->accessToken  = null;
        $this->myData       = null;
        $this->findBy       = null;
        $this->userId       = null;

    }

    public function indexAction() {
        $result = new Result(0, 403, 'invalid_controller');
        header('Content-Type: application/json');
        return $this->redirect()->toRoute('login');
    }

    public function loginAction(){
        try {
            $view = new ViewModel();

            $session        = $this->getSession();

            if($session) {
                $message = $session->get('message');
            }

            $view->setVariables(array(
                'message'           => $message,
            ));

            $view->setTerminal(true);

            $this->layout("layout/layout_login");

            return $view;
        } catch (Exception $ex) {
            error_log($ex->getMessage());
            return $this->redirect()->toRoute('login');
        }
    }

    public function logintbAction(){
        try {

            
            $view = new ViewModel();

            $session        = $this->getSession();

            if($session) {
                $message = $session->get('message');
            }

            $view->setVariables(array(
                'message'           => $message,
            ));

            $view->setTerminal(true);

            $this->layout("layout/layout_admin_header");

            return $view;
        } catch (Exception $ex) {
            error_log($ex->getMessage());
            return $this->redirect()->toRoute('login');
        }
    }

    public function authenticateApiAction($username, $password){
        // $uri     = $this->getRequest()->getUri();
        // $baseurl = $uri->getHost();

        // $ch = curl_init();
        
        // $url = $baseurl."/api/ssologin";
	    // $actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]"."/api/ssologin";
        
        // curl_setopt($ch, CURLOPT_URL,$actual_link);
        // curl_setopt($ch, CURLOPT_POST, 1);
        // curl_setopt($ch, CURLOPT_POSTFIELDS, "usernam3=$username&passw0rds=$password");

        // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        // $server_output = curl_exec($ch);

        // $return_api = json_decode($server_output)->data;
        // $return_api = $return_api->return;

        // curl_close ($ch);
        
        
        // return $return_api;
        // print_r("here");die;
        $cradential = $this->forward()->dispatch(ApiController::class, array(
            'action'        => 'ssoLogin',
            'usernam3'      =>  $username, 
            'passw0rds'     =>  $password, 
        ));
        // print_r("here");die;
        $getCradential= json_decode($cradential->getBody());
        
        return $getCradential;
    }

    public function getAttributeUserApiAction($username, $password){
        // $uri     = $this->getRequest()->getUri();
        // $baseurl = $uri->getHost();
        
        // $ch = curl_init();

	    // $actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]"."/api/ssoGetAllAttribute";
        // //$url = $baseurl."/api/ssoGetAllAttribute";
                
        // curl_setopt($ch, CURLOPT_URL,$actual_link);
        // curl_setopt($ch, CURLOPT_POST, 1);
        // curl_setopt($ch, CURLOPT_POSTFIELDS, "usernam3=$username");

        // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        // $server_output = curl_exec($ch);
        // $return_api = json_decode($server_output)->data;
        // $return_api = (array) $return_api;

        // curl_close ($ch);
        
        // return $return_api;

        $cradential = $this->forward()->dispatch(ApiController::class, array(
            'action'        => 'ssoGetAllAttribute',
            'usernam3'      =>  $username, 
        ));
    
        $getCradential= json_decode($cradential->getBody());
        
        return $getCradential;
    }

    public function authenticateAction(){
        // phpinfo();die;
        try {
            
            $uri     = $this->getRequest()->getUri();
            $baseurl = sprintf('//%s', $uri->getHost());

            $post    = $this->getRequest()->getPost();
            $session = $this->getSession();

            $username = $post['username'];
            $password = $post['passwd'];
            
            // print_r($username." ".$password);die;
            $storage = \Khansia\Access\User\Storage::factory($this->getDb(), $this->getConfig());
            $user    =  new \Khansia\Access\User($storage);
            
            if($user->load($username,  \Khansia\Access\User\Storage::LOADBY_CODE)){ // sukses load then
                
                $authResult = $user->authenticate($password, null, \Khansia\Access\User::RETRIES_TRUE);
                // print_r($authResult);die;
                if($authResult->code == $authResult::CODE_SUCCESS) {
                    
                    $session->owner($user->id);
                    
                    /* get access role */
                    $access = $user->loadAccess($user->id, true);

                    $accessArray = array();

                    foreach($access->data as $data=> $val){

                        if($val['access_status'] == 'TRUE'){
                            $newStat = true;
                        }else{
                            $newStat = false;
                        }
                        $accessArray[$val['access_code']] = $newStat;

                    }

                    /* update tokensss */
                    $this->userId = $user->id;
                    $this->updateToken();

                    $session->put(null, array(
                        'baseurl'           => $baseurl,
                        'user_id'           => $user->id,
                        'usernamed'         => $user->username,
                        'passwd'            => $user->password,
                        'name'              => $user->name,
                        'role'              => $user->role,
                        'kodeprodi'         => $user->nim,
                        'status'            => $user->status,
                        'deviceid'          => $user->deviceid,
                        'retries'           => $user->retries,
                        'create_dtm'        => $user->create_dtm,
                        'access'            => $accessArray,
                        'csrf_token'        => $this->accessToken, // buat csrf token na hela gans biar gege
                        'role_code'         => $access->data[0]['role_code'],
                        'nopeg'             => $user->nopeg,
                        'kaprodi'           => $user->kaprodi,
                        'prodi'             => $user->prodi,
                        'nim'               => $user->nim,
                        'koordinator'       => $user->koordinator
                    ));
                    // print_r($session);die;
                    $session->flush();

                    /* direct data */ //inih kebangsadan
                    // if($session->get('role') == 200 ){
                    //     // return $this->redirect()->toRoute('mahasiswa');
                    //     return $this->redirect()->toRoute('mahasiswa');
                    // } else if($session->get('role') == 10){
                    //     return $this->redirect()->toRoute('admin');
                    // } else if($session->get('role') == 50){
                    //     return $this->redirect()->toRoute('dosen');
                    // } else if($session->get('role') == 210){
                    //     return $this->redirect()->toRoute('kaprodi');
                    // }

                    return $this->redirect()->toRoute('home');

                }else{
                    
                    $check  = $this->authenticateApiAction($username, $password);
                    
                    if($check->code == 0){
                        $getAttribute   = $this->getAttributeUserApiAction($username, $password);
                        $$attributedata  = $getAttribute->data;
                        
                        $status         = $getAttribute->itbStatus;
                        // print_r($status);die;
                        if($status == "Karyawan" || $status == "Tenaga Kontrak"){
                            $nip = $attributedata->itbNIP;

                            if(($pos = strpos($nip, ',')) !== false){
                                $arr = explode(",", $nip, 2);
                                $nip = $arr[0];
                            }

                            $arraydata = array(
                                'username'      => $username,
                                'password'      => md5($password),
                                'update_date'   => $this->STORAGE_NOW(),
                            );

                            $storage = \Khansia\Access\User\Storage::factory($this->getDb(), $this->getConfig());
                            $user    = new \Khansia\Access\User($storage);

                            $check   = $user->updatepasspegawai($arraydata, $username);

                            if($check){
                                $this->authenticateAction();
                            }

                        }elseif($status == "Mahasiswa"){
                            $nim = $attributedata->itbNIM;

                            if(($pos = strpos($nim, ',')) !== false){
                                $nim = substr($nim, $pos+1);
                            }

                            $storage = \Khansia\Access\User\Storage::factory($this->getDb(), $this->getConfig());
                            $user    = new \Khansia\Access\User($storage);

                            $arraydata = array(
                                'username'      => $username,
                                'password'      => md5($password),
                                'update_date'   => $this->STORAGE_NOW(),
                            );

                            $check = $user->updatepassmhs($arraydata, $username);

                            if($check){
                                $this->authenticateAction();
                            }
                        }elseif($status == "Dosen"){
                            $nip = $attributedata->itbNIP;
                            // print_r($nip);die;
                            if(($pos = strpos($nip, ',')) !== false){
                                $arr = explode(",", $nip, 2);
                                $nip = $arr[0];
                            }
                            
                            $arraydata = array(
                                'username'      => $username,
                                'password'      => md5($password),
                                'update_date'   => $this->STORAGE_NOW(),

                            );
                            // print_r($arraydata);die;
                            $storage = \Khansia\Access\User\Storage::factory($this->getDb(), $this->getConfig());
                            $user    = new \Khansia\Access\User($storage);

                            $check   = $user->updatepasspegawai($arraydata, $username);
                            
                            if($check){
                                $this->authenticateAction();
                            }
                        }else{
                            $session = $this->getSession();
                            $message = "Invalid Username or Password";

                            $session->put(null, array('message' => $message));
                            return $this->redirect()->toRoute('login');
                        }

                    }else{
                        switch($authResult->code) {
                            case \Khansia\Access\User::CODE_AUTH_INVALID:
                                $authMessage = 'User tidak valid';
                                break;
                            case \Khansia\Access\User::CODE_AUTH_SUSPEND:
                                $authMessage = 'User ditangguhkan';
                                break;
                            case \Khansia\Access\User::CODE_AUTH_LOCKED:
                                $authMessage = 'User tidak aktif';
                                break;
                            case \Khansia\Access\User::CODE_AUTH_FAILED:
                                $authMessage = 'Password tidak sesuai';
                                break;
                        }
                    }

                    $message = htmlspecialchars($authMessage, ENT_QUOTES, 'UTF-8');

                    $session->put(null, array('message' => $message));

                    return $this->redirect()->toRoute('login');
                }
            }else{
                
                $check  = $this->authenticateApiAction($username, $password);
                
                
                if($check->code == 0){
                    
                    $getAttribute   = $this->getAttributeUserApiAction($username, $password);
                    $attributedata  = $getAttribute->data;
                    
                    $status         = $attributedata->itbStatus;
                    $ou             = $attributedata->ou;


                    
                    if($status == "Karyawan" || $status == "Tenaga Kontrak"){
                        $nip = $attributedata->itbNIP;

                        if(($pos = strpos($nip, ",")) !== false){
                            $arr = explode(",", $nip, 2);
                            $nip = $arr[0];
                        }

                        if($status == 'Karyawan'){
                            $arraydata = array(
                                'username'      => $username,
                                'password'      => md5($password),
                                'nopeg'         => $nip,
                                'nip'           => $nip,
                                'nama'          => $attributedata->cn,
								'id_sta_peg'    => $attributedata->itbStatus,
								'email'         => $attributedata->mail
                            );
                        }else{
                            // ini yak sayang
                            $random_nip = $this->generateRandomCharacter();
							
							$arraydata = array(
								'username'      => $username,
								'password'      => md5($password),
								'nopeg'         => $random_nip,
								'nip'           => $random_nip,
								'nama'          => $attributedata->cn,
								'id_sta_peg'    => $attributedata->itbStatus,
								'email'         => $attributedata->mail
							);
                        }

                        

                    // print_r($arraydata);die;
                        $storage = \Khansia\Access\User\Storage::factory($this->getDb(), $this->getConfig());
                        $user    = new \Khansia\Access\User($storage);

                        $check   = $user->identify($nip, $status);
                        // print_r($check);die;
                        if($check->code == $check::CODE_SUCCESS){
                            
                            $session = $this->getSession();
                            $message = "User telah terdaftar, menunggu verifikasi admin";
                        }else{
                            // print_r("dies");die;
                            $saveidentify = $user->saveidentify($arraydata);
                            
                            $session = $this->getSession();
                            $message = "User telah terdaftar, menunggu verifikasi admin";
                        }

                        $session->put($null, array('message' => $message));
                        return $this->redirect()->toRoute('login');

                    }elseif($status == "Mahasiswa"){
                        $nim = $attributedata->itbNIM;
                        // print_r("modarrr");die;
                        if(($pos = strpos($nim, ",")) !== false){
                            $nim = substr($nim, $pos+1);
                        }
                        
                        $arraydata = array(
                            'username'      => $username,
                            'password'      => md5($password),
                            'nim'           => $nim,
                            'nama'          => $attributedata->cn,
                            'email'         => $attributedata->mail
                        );

                        $arrayuser = array(
                            'username'      => $username,
                            'password'      => md5($password),
                            'role'          => '200',
                            'status'        => '10',
                            'nim'           => $nim,
                            'name'          => $attributedata->cn,
                        );

                        $storage = \Khansia\Access\User::factory($this->getDb(), $this->getConfig());
                        $user    = new \Khansia\Access\User($storage);

                        $check   = $user->identifymhs($nim, $status);

                        if($check->code != 0){
                            $savemhs = $user->savemhs($arraydata, $arrayuser, true);
                                                                                
                            if($savemhs){
                                $this->authenticateAction();
                            }
                        }else{
                            $saveMhs = $user->savemhs($arraydata, $arrayuser, false);
                            if($saveMhs){
                                $this->authenticateAction();
                            }
                        }
                    }elseif($status == "Dosen"){
                        $nip = $attributedata->itbNIP;
                        // print_r($nip);die;

                        if(($pos = strpos($nip, ',')) !== false){
                            $arr = explode(",", $nip, 2);
                            $nip = $arr[0];
                        }

                        $arraydata = array(
                            'username'      => $username,
                            'password'      => md5($password),
                            'nopeg'         => $nip,
                            'nip'           => $nip,
                            'nama'          => $attributedata->cn,
                            'id_sta_peg'    => $attributedata->itbStatus,
                            'email'         => $attributedata->mail,
                        );

                        $arrayuser = array(
                            'username'      => $username,
                            'password'      => md5($password),
                            'role'          => '50',
                            'status'        => '10',
                            'nopeg'         => $nip,
                            'name'          => $attributedata->cn,
                        );
                        // print_r($arrayuser);
                        // print_r($arraydata);
                        // die;
                        $check = $user->identify($nip, $status); 
                        // print_r($check);die;
                        if($check->code == $check::CODE_SUCCESS){ // dah ada di t_peg_itb
                            // print_r($check::CODE_SUCCESS);die;
                            $savedosen = $user->savedosen($arrayuser);
                            if($savedosen){
                                $this->authenticateAction();
                                // print_r($username);die;
                            }
                        }else{ //lom ada di t_peg
                            $saveidentify = $user->saveidentify($arraydata);
                            $savedosen    = $user->savedosen($arrayuser);

                            if($savedosen){
                                $this->authenticateAction();
                            }
                        }
                        
                    }else{
                        $session = $this->getSession();
                        $message = 'Invalid username or password';
        
                        $session->put(null, array('message' => $message));
        
                        return $this->redirect()->toRoute('login');
                    }
                }else{
                    $session = $this->getSession();
                    $message = "Invalid username or password";
                    $session->put(null, array('message' => $message));
                    return $this->redirect()->toRoute('login');
                }
            }

        } catch (\Exception $ex) {
            $session = $this->getSession();
            $message = htmlspecialchars($ex->getMessage(), ENT_QUOTES, 'UTF-8');

            $session->put(null, array('message' => $message));

            return $this->redirect()->toRoute('login');
        }
    }

    private function updateToken(){

        $this->deviceId     = $this->getMacAddress();
        $this->accessToken  = bin2hex(random_bytes(32));
        $this->myData       = array('iduser' => $this->userId, 'accessToken' => $this->accessToken, 'deviceid' => $this->deviceId, 'update_date' => $this->STORAGE_NOW());
        $this->findBy       = 'iduser='.$this->userId;
        
        $_storage           = \Application\Model\Param\Storage::factory($this->getDb(), $this->getConfig());                    
        $_model  	        = new \Application\Model\Param($_storage);
        
        $getResults         = $_model->updateGlobal('user_data_header', $this->myData,  $this->findBy);
        
        
        if($getResults->code == $getResults::CODE_SUCCESS) {

            /* send seed for client */
            return true;
            
        }else{

            $session = $this->getSession();
            $message = 'Failed Generate CSRF-Token';

            $session->put(null, array('message' => $message));

            return $this->redirect()->toRoute('login');
            exit;

        }

    }
    
    public function logoutAction() {
        try {

            $session = $this->getSession();

            $session->stop();

            return $this->redirect()->toRoute('login');

        } catch (\Exception $ex) {

            return $this->redirect()->toRoute('login');

        }
    }

    private function generateRandomCharacter($length = 9){
        $result = '';

		for($i = 0; $i < $length; $i++) {
			$result .= mt_rand(0, 9);
		}
		
		return $result;
    }


}