<?php
defined('BASEPATH') OR exit('No direct script access allowed');
if (isset($_SERVER['HTTP_ORIGIN'])) {
  header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
  header('Access-Control-Allow-Credentials: true');
  header('Access-Control-Max-Age: 86400'); 
}

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])){
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
  }

  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])){
    header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
  }
  exit(0);
}

class Api extends CI_Controller {

  var $auth_token;
  private $cipher = "AES-256-CBC";
  public function __construct() {
    parent::__construct();
    date_default_timezone_set("Asia/Riyadh");
    $this->load->model('Api_model');    
    $this->load->model('Validation_model');
    $method = $this->router->fetch_method();        
    $data = (array) json_decode(file_get_contents('php://input'));
    if($method == 'profile') {
      $data = $_POST;
    }
    if (isset(apache_request_headers()['Auth'])) {
            $this->auth_token = apache_request_headers()['Auth'];
            $data['auth_token'] = $this->auth_token;
        }
    $res = $this->Validation_model->validation_check($method, $data);
    if($res['state'] == 1) {
      $this->errorResponse($res['response']['code'], $res['response']['message']);
      die;
    }
    
  }

  public function index() {
    $res = $this->Validation_model->validation_check('login',array('email_id'=>'adarsh'));
  }

  public function response($data) {
    $result =  array(
      'code' => 1,
      'message' => 'Success',
      'responseResult' =>$data
    );
    print json_encode($result);exit;
  }

  public function errorResponse($errorCode, $errorDesc) {
    $result =  array(
      'code' => 0,
      'message' => 'Failure',
      'errorCode'=> $errorCode,
      'errorDesc'=> $errorDesc
    );
    print json_encode($result);exit;
  }

  public function login(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->login($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function register(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->register($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function forgot(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->forgot($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function popular() {
    $res = $this->Api_model->popular();
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function category() {
    $res = $this->Api_model->category();
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function locality($city_id = '') {
    $res = $this->Api_model->locality($city_id);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function favourite(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->favourite($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function favouritelist() {
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->favouritelist($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function bookedlist() {    
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->bookedlist($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function bookingdetails() {    
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->bookingdetails($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function cancel() {    
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->cancel($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function confirm() {
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->confirm($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function userinfo() {
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->userinfo($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function profile() {
    $data = $_POST;
    if(isset($_FILES['profile_picture'])) {
      $data['file'] = $_FILES['profile_picture'];
    } 
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->update_profile($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function tempbooking() {
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->tempbooking($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function recommend() {
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;

    $res = $this->Api_model->recommend($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function discover() {
    $data = (array) json_decode(file_get_contents('php://input'));
    //$data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->discover($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function event() {
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = (isset($this->auth_token))?$this->auth_token:'';
    $res = $this->Api_model->event($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function search() {
    $data = (array) json_decode(file_get_contents('php://input'));

    $res = $this->Api_model->search($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function searchEvent($str = null) {
    $data['str'] = $str;
    $res = $this->Api_model->searchEvent($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function get_cms_data() {
    $res = $this->Api_model->get_cms_data();
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function save_organizer(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->save_organizer($data);
    if($res['status']!=0){
      $this->response($res['status']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }  
  }

  public function payNow($auth_token='',$amount=0,$booking_id='',$event_id='',$cardData=''){
    $settings   = getSettings();
    $redUrl     = $settings['web_base_url'];

    if(empty($auth_token) || empty($amount) || empty($booking_id)){
      redirect($redUrl.'failure');
    }
    $payData = array('auth_token'=>$auth_token,'amount'=>$amount,'booking_id'=>$booking_id);
    $res = $this->Api_model->payNow($payData);

    if($res['status']==1){
       $this->paymentGateway($amount,$res['transaction_id'],$event_id,$booking_id,$res['custData'],$cardData);
    }
    else{
       redirect($redUrl.'failure?event_id='.$eventid);
    }
  }

  public function paymentGateway($amount='0',$last_id='0',$event_id='0',$booking_id='0',
                                 $custData=array(),$cardData=array()){
    $customerName = array();
    if(isset($custData->name) && !empty($custData->name)){
      $customerName = explode(' ',$custData->name);
    }
    $amount   = $amount;
    $phone    = (isset($custData->phone))?$custData->phone:'';
    $email    = (isset($custData->email))?$custData->email:'';
    $userId   = (isset($custData->userId))?$custData->userId:'';
    $f_Name   = (isset($customerName[0]))?$customerName[0]:'';
    $l_Name   = (isset($customerName[1]))?$customerName[1]:'T';
    $add1     = $add2 = $city = $state = 'Saudi Arabia';
    $pincode  = '61961';

    $noCard    = 0;
    $saveCard  = 1;
    $savedCard = 0;
    if(!empty($cardData)){
      if(isset($cardData['cvv']) && !empty($cardData['cvv']) && 
         isset($cardData['tocken']) && !empty($cardData['tocken'])){
        $savedCard = 1;
      } else if(isset($cardData['cvv']) && !empty($cardData['cvv']) || 
                isset($cardData['cardType']) && !empty($cardData['cardType']) || 
                isset($cardData['cardNumber']) && !empty($cardData['cardNumber']) || 
                isset($cardData['expMonthYear']) && !empty($cardData['expMonthYear']) || 
                isset($cardData['cardHolderName']) && !empty($cardData['cardHolderName'])){

        $cvv      = $cardData['cvv'];
        $cardNo   = $cardData['cardNumber'];
        $holder   = $cardData['cardHolderName'];
        $cardType = $cardData['cardType'];
        $expMonth = substr($cardData['expMonthYear'],0,2);
        $expYear  = '20'.substr($cardData['expMonthYear'],2,2);
        $saveCard = (isset($cardData['saveCard'])&&!empty($cardData['saveCard'])&&$cardData['saveCard']==0)?0:1;
      } else {
        $noCard = 1;
      }
    } else {
      $noCard = 1;
    }

    $failureUrl = base_url('Api/paymentFailureUrl');
    $successUrl = base_url('Api/paymentSuccessUrl');
      
    $pText  = '1111110||';
    $pText .= '11111111|'.$last_id.'|'.$amount.'|'.$successUrl.'|'.$failureUrl.'|INTERNET|DD|01|SAR||';
    $pText .= '1111111111111|'.$f_Name.'|'.$l_Name.'|'.$add1.'|'.$add2.'|'.$city.'|'.$state.'|'.$pincode.
              '|SA|'.$email.'|'.$phone.'|34|344|34355344||';
    $pText .= '111111111111|'.$f_Name.'|'.$l_Name.'|'.$add1.'|'.$add2.'|'.$city.'|'.$state.'|'.$pincode.
              '|SA|'.$phone.'|34|344|34355344||';
    if($savedCard == 1){
      $pText .= '00010000001|'.$cardData['cvv'].'|'.$cardData['tocken'].'||';
    } else {
      if($noCard == 0){
        $pText .= '11111100000|'.$cardNo.'|'.$expMonth.'|'.$expYear.'|'.$cvv.'|'.$holder.'|'.$cardType.'||';
      } else {
        // No Card Payment Method Logic.

        // $holder   = 'Basanta Mahunta'; $cardType = 'MasterCard'; $cardNo = '5111111111111118';
        // $cvv      = '100'; $expMonth = '06'; $expYear  = '2022';
      }
    }
    $pText .= '1110000|'.$last_id.'|'.$event_id.'|'.$booking_id.'||';
    if($saveCard == 1){
      $pText .= '1000000|'.$userId;
    }

    $settings   = getSettings();
    $iv         = $settings['merchant_iv'];
    $mId        = $settings['merchant_id'];
    $mKey       = $settings['merchant_key'];
    $colabId    = $settings['collaborator_id'];
    $requestUrl = $settings['payment_gateway_url'];

    $size = openssl_cipher_iv_length($this->cipher);
    $pad = $size - (strlen($pText) % $size);
    $painText = $pText . str_repeat(chr($pad), $pad);
    $painText = base64_encode(openssl_encrypt($painText,$this->cipher,base64_decode($mKey), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
    
    $this->load->view('payment/payment',array('rUrl'=>$requestUrl,'mId'=>$mId,'colabId'=>$colabId,
                                              'requestParam'=>$mId.'||'.$colabId.'||'.$painText));
  }

  public function paymentSuccessUrl(){
    if(isset($_REQUEST['responseParameter']) && !empty($_REQUEST['responseParameter']) && 
       !empty($response = explode("||",$_REQUEST['responseParameter'])) && !isset($_POST['txnErrMsg'])){
      
      $settings   = getSettings();
      $iv         = $settings['merchant_iv'];
      $mKey       = $settings['merchant_key'];
      $redUrl     = $settings['web_base_url'];

      if(!isset($response[1]) || empty($response[1])){
        redirect($redUrl.'failure');
      }

      $enctext = base64_decode($response[1]);   
      $padtext = openssl_decrypt($enctext,$this->cipher, base64_decode($mKey),OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
      $pad = ord($padtext{strlen($padtext) - 1});
      if($pad > strlen($padtext)){
        redirect($redUrl.'failure');
      }
      if(strspn($padtext, $padtext{strlen($padtext)-1},strlen($padtext)-$pad) != $pad){
        redirect($redUrl.'failure');
      }
      $response = substr($padtext, 0, -1 * $pad);

      if(empty($response) || empty($response = explode("||",$response))){
        redirect($redUrl.'failure');
      }

      $last_id = '';
      $eventid = '';
      $booking_id = '';
      $transaction_id = '';

      if(isset($response[2]) && !empty($response[2]) && !empty($data = explode('|',$response[2])) && 
         isset($data[1]) && !empty($data[1])){
        $transaction_id = $data[1];
      }

      if(isset($response[4]) && !empty($response[4]) && !empty($data = explode('|',$response[4])) && 
         isset($data[1]) && !empty($data[1]) && isset($data[2]) && !empty($data[2]) && 
         isset($data[3]) && !empty($data[3])){
        $last_id = $data[1];
        $eventid = $data[2];
        $booking_id = $data[3];
      }

      if(!empty($transaction_id) && !empty($last_id)){
        $this->Api_model->update_payment($response,$transaction_id,$last_id,'1') ;
      }

      if(!empty($booking_id)){
        redirect($redUrl.'bookingdetails?booking_id='.$booking_id);
      }
    }
    redirect($redUrl.'failure');
  }

  public function paymentFailureUrl(){
    $settings   = getSettings();
    $redUrl     = $settings['web_base_url'];

    if(empty($_REQUEST['responseParameter'])){
      redirect($redUrl.'failure');
    }

    if(isset($_REQUEST['responseParameter']) && !empty($_REQUEST['responseParameter']) && 
       !empty($response = explode("||",$_REQUEST['responseParameter']))){
      $iv         = $settings['merchant_iv'];
      $mKey       = $settings['merchant_key'];

      if(!isset($response[1]) || empty($response[1])){
        redirect($redUrl.'failure');
      }
      $enctext = base64_decode($response[1]);   
      $padtext = openssl_decrypt($enctext,$this->cipher, base64_decode($mKey),OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
      $pad = ord($padtext{strlen($padtext) - 1});
      if($pad > strlen($padtext)){
        redirect($redUrl.'failure');
      }
      if(strspn($padtext, $padtext{strlen($padtext)-1},strlen($padtext)-$pad) != $pad){
        redirect($redUrl.'failure');
      }
      $response = substr($padtext, 0, -1 * $pad);

      if(empty($response = explode("||",$response))){
        redirect($redUrl.'failure');
      }

      $last_id = '';
      if(isset($response[1]) && !empty($response[1]) && !empty($data = explode('|',$response[1])) && 
         isset($data[1]) && !empty($data[1])){
        $last_id = $data[1];
        $this->Api_model->update_payment($response,'',$last_id,'0');

        $sql = "SELECT BOK.event_id FROM transaction AS TX
                INNER JOIN booking AS BOK ON (BOK.bookId=TX.booking_id)
                WHERE TX.id='$last_id'";
        $trxData = $this->db->query($sql)->row_array();
        if(!empty($trxData) && isset($trxData['event_id']) && !empty($trxData['event_id'])){
          redirect($redUrl.'failure?event_id='.$trxData['event_id']);
        }
      }
    }
    redirect($redUrl.'failure');
  }

  public function reset_password(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->reset_password($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function verifyMail($unique_id = '') {
    $res = $this->Api_model->verifyMail(array('unique_id'=>$unique_id));
  }

  public function checkSeatAvailability(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->checkSeatAvailability($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function getCountry() {
    $res = $this->Api_model->getCountry();
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function validate_promo_code(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $data['auth_token'] = $this->auth_token;
    $res = $this->Api_model->validate_promo_code($data);
    $result =  array('code' => $res['status'],'message' => $res['message'],
                     'responseResult' => (isset($res['data']) && !empty($res['data']))?$res['data']:'');
    print json_encode($result);exit;
  }

  public function getSavedCards(){
    $data         = (array) json_decode(file_get_contents('php://input'));
    $cust_id      = $this->Api_model->auth_token_get($this->auth_token);
    if(empty($cust_id) || empty($data) || !isset($data['email']) || empty($email = $data['email'])){
      $this->errorResponse('891','Invalid User');
    }

    $settings     = getSettings();
    $merchant_iv  = $settings['merchant_iv'];
    $merchant_id  = $settings['merchant_id'];
    $merchant_key = $settings['merchant_key'];

    $ses_id       = time().rand(100000,999999);
    $reqData      = '{"sessionId":"'.$ses_id.'","merchantId":"'.$merchant_id.'","custId":"'.$cust_id.'","emailId":"'.$email.'"}';
    $plainText    = $this->encryptePayData($merchant_iv,$merchant_key,$reqData);
    $plainText    = $merchant_id.'|'.$plainText;

    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,'https://staging.bayanpay.sa/direcpay/secure/PaymentsMerchStoredCardDtlsAPI');
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch,CURLOPT_POST,1);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$plainText); 
    curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-Type: text/plain')); 
    $result = curl_exec($ch);

    if(empty($result)){
      $this->errorResponse('892','Something went wrong, Please try again');
    }
    $resp = $this->decryptePayData($merchant_iv,$merchant_key,$result);
    if(empty($resp) || !isset($resp->txnCardDetails) || 
       empty($resp->txnCardDetails) || count($resp->txnCardDetails) <= 0){
      $this->errorResponse('893','No Data Found');
    }
    $this->response(array('saved_cards'=>$resp->txnCardDetails));
  }

  function encryptePayData($merchant_iv='',$merchant_key='',$plainText='') {  
    if(empty($merchant_iv) || empty($merchant_key) || empty($plainText)){
      return false;
    }
    $key        = $this->cipher;
    $size       = openssl_cipher_iv_length($key);
    $mKey       = base64_decode($merchant_key);
    $padDat     = $size - (strlen($plainText) % $size);
    $padtext    = $plainText . str_repeat(chr($padDat), $padDat);
    $encText    = openssl_encrypt($padtext,$key,$mKey,OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,$merchant_iv);
    return base64_encode($encText);
  }

  function decryptePayData($merchant_iv='',$merchant_key='',$encText='') {
    if(empty($merchant_iv) || empty($merchant_key) || empty($encText)){
      return false;
    }
    $key        = $this->cipher;
    $mKey       = base64_decode($merchant_key);
    $encText    = base64_decode($encText);
    $padtext    = openssl_decrypt($encText,$key,$mKey,OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $merchant_iv);
    $padData    = ord($padtext{strlen($padtext) - 1});

    if ($padData > strlen($padtext)) return false;
    if (strspn($padtext,$padtext{strlen($padtext)-1},strlen($padtext)-$padData)!=$padData) return false;

    $response    = substr($padtext,0,-1*$padData);
    return json_decode($response);
  }

  public function encrypt($plainText='',$mKey='',$mIv='') {   
    if(empty($plainText) || empty($mKey) || empty($mIv)){
      return '';
    }
    if (in_array($this->cipher, openssl_get_cipher_methods())) {
      $ciphertext = openssl_encrypt($plainText, $this->cipher, $this->key, $options=0, $this->iv);
      return $ciphertext;
    }
  }

  public function decrypt($encText='',$mKey='',$mIv='') {
    if(empty($plainText) || empty($mKey) || empty($mIv)){
      return '';
    }
    if (in_array($this->cipher, openssl_get_cipher_methods())) {       
      $original_plaintext = openssl_decrypt($encText, $this->cipher, $this->key, $options=0, $this->iv);
      return $original_plaintext;
    }
  }

  /*================ START : Checker API ================*/

  public function checker_bookingDetails(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->checkerbookingdetails($data);
    if($res['status']!=0){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function checker_login(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->checker_login($data);
    if($res['status']!=0){
      $this->response($res['data']);
    } else {
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  public function getCheckerBookList(){
    $data = (array) json_decode(file_get_contents('php://input'));
    $res = $this->Api_model->getOrganiserBookList($data);
    if(isset($res['data']) && !empty($res['data'])){
      $this->response($res['data']);
    }
    else{
      $this->errorResponse($res['code'],$res['message']);
    }
  }

  /*================ END : Checker API ================*/
}
?>