<?php

 header("Access-Control-Allow-Origin: http://localhost/rest-api-authentication-example/");
//header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
 
// files needed to connect to database

 $pathRoot = $_SERVER['DOCUMENT_ROOT'];
include_once  $pathRoot ."/saia/api/v1/config/database.php";
include_once $pathRoot ."/saia/api/v1/objects/appUser.php";

//========== Files needed for email =====================================
include_once $pathRoot ."/saia/api/v1/sendmail/customMailSender.php";


//================= JWT Library ==========================================
     include_once $pathRoot ."/saia/api/v1/config/core.php";
     include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/BeforeValidException.php";
     include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/ExpiredException.php";
     include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/SignatureInvalidException.php";
     include_once $pathRoot ."/saia/api/v1/libs/php-jwt-master/src/JWT.php";
      use \Firebase\JWT\JWT;

   $jwtDta = "";
   $jwtUserId = 0;
   $jwtUserEmail = "";
//========================================================================
 
// get database connection
$database = new Database();
$db = $database->getConnection();


//==== Get JSON data ===========
//$data = json_decode(file_get_contents("php://input"));
$data = json_decode(file_get_contents("php://input"));
$action = $data->action;
 $emptyData= "";

if(strcmp($action, $emptyData) == 0){
    http_response_code(400);
     echo json_encode(array("responseCode"=>400,"action" =>"","result"=>"no valid action"));
  // header('HTTP/1.1 404 Not Found');
   // echo http_response_code();
  // header('X-PHP-Response-Code: 404', true, 404);
    return ;
}
//================= Verify if user exists =====================================
if(strcmp($action,"userVerification")==0){
    $email =  $data->email;
    $user = new AppUser($db);
     $emailExists = $user->emailExists();
    if($emailExists == true){
         echo json_encode(array("responseCode"=>200,"action" =>"userVerification","result" => "yes")); 
         return;
    }else{
        echo json_encode(array("responseCode"=>200,"action" =>"userVerification","result" => "no")); 
        return;
    }
    
}
//================= Request Reset Password code ================================
if(strcmp($action,"requestAuthCode")==0){
    $email =  $data->email;
    $resend =  $data->resend;
    $user = new AppUser($db);
    $user->email =$email;
    //$userExists = $user->getAuthCode($email);
    $userExists = $user->emailExists();
    if(!$userExists){
         http_response_code(401);
        echo json_encode(array("responseCode"=>401,"action" =>"requestAuthCode","result"=>"Invalid user"));
        return;
           
    }
    $getStatus = $user->getAuthCode($email);
    $emptyData = "";
       if(strcmp($user->resetPasswordCode,$emptyData)==0){
            $verificationCode = mt_rand(100000,999999);
             $user->resetPasswordCode = strval($verificationCode);
              $user->updateResetAuthCode($email);
       }
    
    if(strcmp($resend,"yes")==0){
       
      
    }
     $succesfulSend = sendEmail("",$user->resetPasswordCode,$email,"PocketStylist Password Reset Confirmation Code",$user->name);
     if( strcmp($succesfulSend,"Email send")==0 ){
          http_response_code(200);
          echo json_encode(array("responseCode"=>200,"action" =>"requestAuthCode","result"=>"Email send"));
         return;
       }
     http_response_code(200);
     echo json_encode(array("responseCode"=>200,"action" =>"requestAuthCode","result"=>"Email error"));
    
}


//================== Reset Password ================================

if(strcmp($action, "resetPassword") == 0){
    $email =  $data->email;
    $user = new AppUser($db);
   // $user->email = htmlspecialchars(strip_tags($data->email));
    $user->email=$email ;
    //=== sanitize====
    //$new_password = htmlspecialchars(strip_tags($data->newPassword));
    $new_password = $data->newPassword;
    //$verificationCode = htmlspecialchars(strip_tags($data->confirmationCode));
    $verificationCode = $data->confirmationCode;
    $results = $user->resetPassword($verificationCode,$new_password);
    //echo json_encode(array("Reset" =>$results)); 
    echo json_encode(array("responseCode"=>200,"action" =>"resetPassword","result"=>$results));
    return;

}

//========= Verify JWT =====================
   try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){
             http_response_code(401);
             echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
          echo json_encode(array("responseCode"=>401));
         return;

    }



//===================== Update User Details ============================

if(strcmp($action, "updateUser") == 0){

     //============== Get JWT from Header =====================
     //============ If Empty, return 401 =====================
    try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){

             http_response_code(401);
             echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
         echo json_encode(array("responseCode"=>401));
         return;

    }
    

    //============== Decode JWT =============================
    try{
        $decoded = JWT::decode($jwt, $key, array('HS256'));
    }catch(Exception $e){
        http_response_code(401);
        echo json_encode(array("responseCode"=>401));
        $jwtDta = "";
        $jwtUserId = 0;
        $jwtUserEmail = "";
        $saveResults = "error: Verification" ;
        return;
    }
    //========== Get Data from JSON ==========================
    $name = $data->name;
    $email = $data->email;
    $celnr = $data->celnr;
    try{
        $country = $data->country;
    }catch(Exception $e){
        $country = "";

    }
    $password = $data->password;
  
    
    $notifications = $data->notifications;
    $versionControl = $data->versionControl;
    if((strcmp($name, "") == 0) && (strcmp($email, "") == 0)&& (strcmp($celnr, "") == 0) && (strcmp($password, "") == 0) && (strcmp($notifications, "") == 0)  && (strcmp($country, "") == 0))
    {
         http_response_code(400);
         echo json_encode(array("responseCode"=>400,"action" =>"updateUser","result"=>"no data","jwt"=>"")); 
         return;
        
    }
    $generateNewJwt = "no";

    if(strcmp($jwt, "") != 0){
        try {
             $user = new AppUser($db);


        // show user details
           $jwtDta = $decoded->data;
           $jwtUserId = $jwtDta -> id;
           $jwtUserEmail = $jwtDta -> email;

            if(!$user->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){

                http_response_code(401);
                echo json_encode(array("responseCode"=>401));
                return;
            }
           $emptyString = "";
           if(strcmp($jwtUserEmail,$email)!= 0 && strcmp($email,$emptyString)!==0){
               $generateNewJwt = "yes";

           }

           $user->name = $name;
            $user->email = $email;
            $user->celnr = $celnr;
            $user->country = $country;
            $user->notifications = $notifications;
            $user->id =  $jwtUserId;
            $user->password = $password;
            $user->versionControl = $versionControl;
           // $saveResults = $user->updateAppUserDetails();
            $saveResults = $user->updateAppUser();
            $newJwt = "";
            if(strcmp($generateNewJwt,"yes")== 0){
              //  echo $generateNewJwt;
                if(strcmp($saveResults,"saved")==0){

                    $newJwt = createNewJWT($jwtUserId,$email,$iss,$aud,$iat,$nbf,$key);
                }
                
            }


         }catch (Exception $e){
             http_response_code(500);
             echo json_encode(array("responseCode"=>500));
            $jwtDta = "";
            $jwtUserId = 0;
            $jwtUserEmail = "";
            $saveResults = "error:".$e ;
           //$saveResults = $e;
             
        }
         http_response_code(200);
        echo json_encode(array("responseCode"=>200,"action" =>"updateUser","result"=>$saveResults,"jwt"=>$newJwt)); 
         return;

    }

}

//======================== Get User Details =================================

 if(strcmp($action, "getUserDetails") == 0){
     
        //----------------- Get JWT from Header ----------------------
    try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){
             http_response_code(401);
             echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
         echo json_encode(array("responseCode"=>401));
         return;

    }
    
    if(strcmp($jwt, "") != 0){
    // if decode succeed, show user details

        try {
        // decode jwt
            $decoded = JWT::decode($jwt, $key, array('HS256'));
            

        // show user details
           $jwtDta = $decoded->data;
           $jwtUserId = $jwtDta -> id;
           $jwtUserEmail = $jwtDta -> email;

           $user = new AppUser($db);
           $user->id =  $jwtUserId;
           echo $user->getAppUserProfile();
          return;


         }catch (Exception $e){
            $response["responseCode"] = 500;
            $response["result"] = "Error: ".$e;
            echo json_encode($response);
            return;
             
        }
        

    }
     http_response_code(401);
     echo json_encode(array("responseCode"=>401,"result"=>"not Authorized"));
    
    return;
    
     
 }
 //================= Save USer Personal Details ==============================
 //===================== Update User Details ============================

if(strcmp($action, "updateUserPersonal") == 0){

     //============== Get JWT from Header =====================
     //============ If Empty, return 401 =====================
    try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){
             http_response_code(401);
              echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
          echo json_encode(array("responseCode"=>401));
         return;

    }
    

    //============== Decode JWT =============================
    try{
        $decoded = JWT::decode($jwt, $key, array('HS256'));
		 $jwtDta = $decoded->data;
         $jwtUserId = $jwtDta -> id;
         $jwtUserEmail = $jwtDta -> email;
    }catch(Exception $e){
        http_response_code(401);
         echo json_encode(array("responseCode"=>401));
        return;
    }
	
	//=============== Verify that jwt decoding deails exists =============
	$user = new AppUser($db);
	 if(!$user->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){
              //  echo "test";
                http_response_code(401);
                 echo json_encode(array("responseCode"=>401));
                return;
     }
    //========== Get Data from JSON ==========================
	$updateType= $data->updateType;
	$updateValue = $data->updateValue;
	$versionControl = $data->versionControl;

	
	//================ Evaluate which colomn needs to be updated ===========

	if((strcmp($updateType, "name") !== 0) && (strcmp($updateType, "email") !== 0) && (strcmp($updateType, "celnr") !== 0) && (strcmp($updateType, "country") !== 0) && (strcmp($updateType, "notifications") !== 0) &&(strcmp($updateType, "password") !== 0) ){
	    
		echo json_encode(array("responseCode"=>400,"action"=>"updateUserPersonal","result"=>"no data","jwt"=>"")); 
		return;
	}
	
	if((strcmp($updateType, "") == 0)){
		echo json_encode(array("responseCode"=>401,"action"=>"updateUserPersonal","result"=>"no data","jwt"=>"")); 
		return;
	 }
	 if($versionControl < 1){
		$versionControl = 1;
	 }
	
	
	//=================Updating data ======================================================
	$newJwt = "";
	try{
	   $user->id = $jwtUserId; 
		$saveResults = $user->updateAppUserPersonalDetails($updateType,$updateValue,$versionControl);
		if(strcmp($saveResults,"saved")==0){
		    if(strcmp($user->feedback,"New JWT")==0){
			    $newJwt = createNewJWT($jwtUserId,$user->email,$iss,$aud,$iat,$nbf,$key);		
		    }
		}
		
		echo json_encode(array("responseCode"=>200,"action"=>"updateUserPersonal","result"=>$saveResults,"jwt"=>$newJwt)); 
         return;		
	
	}catch (Exception $e){
             http_response_code(500);
			echo json_encode(array("responseCode"=>500,"action"=>"updateUserPersonal","result"=>"Error Saving".$e,"jwt"=>"")); 
             
     }
     return;
  

}
 
//================== Save UserProfile =========================================
 if(strcmp($action, "saveProfile") == 0){

     
    // =============== Get and check for valid JWT ====================
   try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){
             http_response_code(401);
             echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
         echo json_encode(array("responseCode"=>401));
         return;

    }   
    $decoded = "";
    $jwtDta = "";
    $jwtUserId = 0;
     $jwtUserEmail = "";
    
    if(strcmp($jwt, "") != 0){
    // if decode succeed, show user details
        //====  decode jwt=====
        try {
            $decoded = JWT::decode($jwt, $key, array('HS256'));
            $jwtDta = $decoded->data;
            $jwtUserId = $jwtDta -> id;
            $jwtUserEmail = $jwtDta -> email;
            
        }catch (Exception $e){
            http_response_code(401);
            echo json_encode(array("responseCode"=>401));
           //  $response["action"] = "saveProfile";
          //  $response["result"] = "Error";
         //   $response["details"] = "Authentication Error".$e;
         //   echo json_encode($response);
           return;
        }
        

        try {
 
           $user = new AppUser($db);
           $user->id =  $jwtUserId;
           //====== Check if user and id exists ===================

           if(!$user->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){
                http_response_code(401);
                echo json_encode(array("responseCode"=>401));
                return;
           }
           //=========== Get JSON data =============================
            $name = $data->name;
            $celnr = $data->celnr;
            $country = $data->country;
            $profile = $data->profileData;
            $consultantId =  $data->consultantId;
            $consultantEmail = $data->consultantEmail;
            $notifications = $data->notifications;
            $versionControl = $data->versionControl;
            
            $user->name = $name ;
            $user->celnr = $celnr;
            $user->country = $country;
           $user->consultantId = $consultantId;
            $user->consultantEmail = $consultantEmail;
            $user->notifications = $notifications;
            $user->versionControl = $versionControl;

            $saveStatus = $user->saveUserProfile($profile);
            $response["responseCode"] = 200;
            $response["action"] = "saveProfile";
            if(strcmp($saveStatus, "true") == 0){
                $response["result"] = "saved";
            }else{
                $response["result"] = "not saved";
            }
            
           echo json_encode($response);
          return;


         }catch (Exception $e){
              http_response_code(500);
             $response["responseCode"] = 500;
            $response["action"] = "saveProfile";
            $response["result"] = "error".$e;

           echo json_encode($response);
          return;
             
        }
        
    }
     
 }
 //============== Delete User Profile ==============================
 if(strcmp($action, "deleteProfile") == 0){

    try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){
             http_response_code(401);
              echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
          echo json_encode(array("responseCode"=>401));
         return;

    }


    //============== Decode JWT =============================
    try{
        $decoded = JWT::decode($jwt, $key, array('HS256'));
        $jwtDta = $decoded->data;
        $jwtUserId = $jwtDta -> id;
        $jwtUserEmail = $jwtDta -> email;
    }catch(Exception $e){
        http_response_code(401);
         echo json_encode(array("responseCode"=>401));
        return;
    }
        //========== Get Data from JSON ==========================
    $emailAddressToDelete = $data->email;
    if(strcmp($emailAddressToDelete, $jwtUserEmail) != 0){
       http_response_code(401);
       echo json_encode(array("responseCode"=>401));
       return;
    }
	
    //=============== Verify that jwt decoding deails exists =============
    $user = new AppUser($db);
    if(!$user->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){
              //  echo "test";
       http_response_code(401);
       echo json_encode(array("responseCode"=>401));
       return;
     }
     $deleteResults = $user->deleteUserAccount($jwtUserEmail,$jwtUserId);
     if(strcmp($deleteResults,"success")== 0){
         http_response_code(200);
        $response["responseCode"] = 200;
        $response["result"] = "success";
        echo json_encode($response);
        return;
     }

     http_response_code(500);
     $response["responseCode"] = 500;
     $response["result"] = $deleteResults;
     echo json_encode($response);
     return; 
     
 }
 
    
// ================== Request Consultation Email ==============================

 if(strcmp($action, "requestConsultationEmail") == 0){
          //----------------- Get JWT from Header ----------------------
    try{
        $jwtAuth =  getBearerToken();
        $jwt=isset($jwtAuth) ? $jwtAuth : "";
        if(strcmp($jwt, "") == 0){
             http_response_code(401);
             echo json_encode(array("responseCode"=>401));
            return;
        }
    }catch (Exception $e){
         http_response_code(401);
         echo json_encode(array("responseCode"=>401));
         return;

    }
    
      if(strcmp($jwt, "") != 0){
    // if decode succeed, show user details

        try {
        // decode jwt
            $decoded = JWT::decode($jwt, $key, array('HS256'));
            

        // show user details
           $jwtDta = $decoded->data;
           $jwtUserId = $jwtDta -> id;
           $jwtUserEmail = $jwtDta -> email;
           $consultantId =  $data->consulId;
           $consultantEmail = $data->consulEmail;
           $consultantMobile = $data->consulMobile;
           $consulRequest = $data->consulRequest;
           $consulType = $data->consulType;
           

           $user = new AppUser($db);
           $user->id =  $jwtUserId;

           if($user->verifyJwtIdEmail($jwtUserEmail,$jwtUserId)){
               $sendStatus = sendRequestMail($consultantEmail, $consulRequest,$consulType,$user);
               if(strcmp($sendStatus, "Email send") == 0){
                    $response["responseCode"] = 200;
                    $response["action"] = "requestConsultationEmail";
                    $response["result"] = "send";
               }else{
                    $response["responseCode"] = 200;
                    $response["action"] = "requestConsultationEmail";
                    $response["result"] = "not send" + $sendStatus ;

               }
               
               echo json_encode($response);
               return;
           }
           $response["responseCode"] = 401;
            $response["result"] = "Mail not send, No valid user";
           echo json_encode($response);
          return;


         }catch (Exception $e){
            http_response_code(401);
            echo json_encode(array("responseCode"=>401));
            return;
             
        }
        
    }
     
     
 }
 
 //================= Send Mail Requesting Consultation ========================
 function sendRequestMail($consultantEmail,$consulRequest,$consulType,$user){
      $msg = "Good Day \r\n Request for the following consultations has been received: " . $consulType. "\r\n Client Name: ".$user->name."\r\n Contact email: ".$user->email."\r\n MobileNr:".$user->celnr."\r\n" ;
      $msg = wordwrap($msg,70);
      

      
    $to      = $consultantEmail;
    $subject = "Consultation Request";

  //  $headers = array(
 //   'From' => 'requestManager@pocketstylists.com',
 //   'Reply-To' => 'emile@ideas4apps.co.za',
 //   'Bcc' => 'emile@gits.sa@gmail.com',
 //   'X-Mailer' => 'PHP/' . phpversion()
  //  );
    
    $mailResults = sendCustomMail("connect@pocketstylists.com","helpdesk@saimage-apps.co.za","Helpdesk",$to,$user->name,$subject, $msg,"");
    return     $mailResults;

  //  $mailResults = mail($to, $subject, $msg, $headers);
    // if($mailResults){
    //    return "Request Send";
    //}else{
    //    return $mailResults;
   // }  
 
 }
 
//======================= Generate new JWT =====================================
function createNewJWT($userId,$newEmail, $iss,$aud,$iat,$nbf,$key){
     $token = array(
       "iss" => $iss,
       "aud" => $aud,
       "iat" => $iat,
       "nbf" => $nbf,
       "data" => array(
           "id" => $userId,
           "email" => $newEmail
       )
    );
    $newJwt = JWT::encode($token, $key);
    return  $newJwt;
}


//==============================================================================

 function sendEmail($AdditionalEmail,$code,$emailAddress,$subject,$userName){
     $msg = "Confirmation Code: " . $code;
      $msg = wordwrap($msg,70);
    $headers = "From: authenticator@pocketstylists.com";
    // send email
  //  $mailResults = mail($emailAddress,"PocketStylist Registration Confirmation //Code",$msg,$headers);
    //$subject = "PocketStylist Registration Confirmation Code";
    $mailResults = sendCustomMail($AdditionalEmail,"helpdesk@saimage-apps.co.za","Helpdesk", $emailAddress ,$userName,$subject, $msg,"");
    if($mailResults){
        return "Email send";
    }else{
        return $mailResults;
    }
 }
 
 
/** 
 * Get header Authorization
 * */
function getAuthorizationHeader(){
        $headers = null;
        if (isset($_SERVER['Authorization'])) {
            $headers = trim($_SERVER["Authorization"]);
        }
        else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
            $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
        } elseif (function_exists('apache_request_headers')) {
            $requestHeaders = apache_request_headers();
            // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
            $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
            //print_r($requestHeaders);
            if (isset($requestHeaders['Authorization'])) {
                $headers = trim($requestHeaders['Authorization']);
            }
        }
       // $headers = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDAsImRhdGEiOnsiaWQiOiIzIiwiZW1haWwiOiJlbWlsZUBpZGVhczRhcHBzLmNvLnphIn19.PsusjAZ10bdOtOuB0CCTv9O3D68-v_YRaCC48oYh_EI";
        return $headers;
    }
/**
 * get access token from header
 * */
function getBearerToken() {
    $headers = getAuthorizationHeader();
    // HEADER: Get the access token from the header
    if (!empty($headers)) {
        if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
            return $matches[1];
        }
    }
    return "";
}
 
?>