<?php

// generate json web token
include_once '../../_public/api_config.php';
include_once '../../_library/php-jwt-master/src/BeforeValidException.php';
include_once '../../_library/php-jwt-master/src/ExpiredException.php';
include_once '../../_library/php-jwt-master/src/SignatureInvalidException.php';
include_once '../../_library/php-jwt-master/src/JWT.php';

include_once '../../_library/libphonenumber-for-php/src/MetadataSourceInterface.php';
include_once '../../_library/libphonenumber-for-php/src/MetadataLoaderInterface.php';
include_once '../../_library/libphonenumber-for-php/src/DefaultMetadataLoader.php';
include_once '../../_library/libphonenumber-for-php/src/PhoneNumberUtil.php';
include_once '../../_library/libphonenumber-for-php/src/CountryCodeToRegionCodeMap.php';
include_once '../../_library/libphonenumber-for-php/src/PhoneNumberDesc.php';
include_once '../../_library/libphonenumber-for-php/src/NumberFormat.php';
include_once '../../_library/libphonenumber-for-php/src/PhoneNumberFormat.php';
include_once '../../_library/libphonenumber-for-php/src/PhoneMetadata.php';
include_once '../../_library/libphonenumber-for-php/src/MultiFileMetadataSourceImpl.php';
include_once '../../_library/libphonenumber-for-php/src/MatcherAPIInterface.php';
include_once '../../_library/libphonenumber-for-php/src/RegexBasedMatcher.php';
include_once '../../_library/libphonenumber-for-php/src/PhoneNumber.php';
include_once '../../_library/libphonenumber-for-php/src/CountryCodeSource.php';
include_once '../../_library/libphonenumber-for-php/src/Matcher.php';
include_once '../../_library/libphonenumber-for-php/src/NumberParseException.php';
include_once '../../_library/libphonenumber-for-php/src/PhoneNumberType.php';
include_once '../../_library/libphonenumber-for-php/src/ValidationResult.php';

include_once '../../_library/random_compat-master/lib/random.php';

//

use libphonenumber\PhoneNumberUtil;
//use libphonenumber\NumberParseException;
//use libphonenumber\PhoneNumberFormat;
use \Firebase\JWT\JWT;

$do = $_GET["ac"];

$otp_valid = 5;
$jwt_valid = 7;
$details = array();

switch ($do) {

   case "register":
      register();
      break;
   ###########################################
   case "onlineTests":
      onlineTests();
      break;

   case "onlineOffers":
      onlineOffers();
      break;

   case "onlineVisits":
      onlineVisits();
      break;

   default:
      break;
}


############################# register a new patient #########################

function register() {
   $mobile = trim($_POST['mobile']);
   $name = trim($_POST['name']);

   if (strpos($mobile, '00') === 0) {
      $mobile = '+' . substr($mobile, 2);
   }

   try {
      $valid = patientDataValidation($mobile, $name);
      if ($valid == 1) {
         $result = registerPatient($mobile, $name);
      } else {
         $result = $valid;
      }
   } catch (Exception $ex) {
      // print_r($ex);
      $result = errorObj(500, 'Internal Server Error', '');
   }

   echo json_encode($result);
}

##############

function patientDataValidation($mobile, $name) {
   global $details;
   $validNo = validateMobileNo($mobile);
   $validName = validatePatName($name);
   if ($validNo == 1 && $validName == 1) {
      $result = 1;
   } else {
      $result = errorObj(422, 'Invalid input data ', $details);
   }

   return $result;
}

##############

function validatePatName($name) {
   global $details;
   if (strlen($name) > 1) {
      $valid = checkNameDuplicate($name);
      if ($valid == 1) {
         return 1;
      } else {
         array_push($details, array("name" => "Name already exist "));
         return -1;
      }
   } else {
      array_push($details, array("name" => "Name must be at least 2 characters"));
      return -1;
   }
}

function checkNameDuplicate($name) {
   $sql = ' (  SELECT id    FROM patients    WHERE wifename  =   ?  and deleted = 0    )  ';
   $sql .= '  union ';
   $sql .= ' ( SELECT id   FROM patients_web    WHERE   name =   ?  and  verified = 1   and   deleted = 0    )';

   $patients = R::getAll($sql, [$name, $name]);

   //  print_r($patients);

   if (count($patients) > 0) {
      return -1;
   } else {
      return 1;
   }
}

##############

function validateMobileNo($mobile) {
   global $details;
   $labSetting = R::findOne('programesettinglab');
   $code = $labSetting->phone_code;
   if ($code == '' || is_null($code)) {
      $code = '+966';
   }


   $phoneUtil = PhoneNumberUtil::getInstance();
   $numberProto = $phoneUtil->parse($mobile);

   $codAllowed = $phoneUtil->getRegionCodesForCountryCode(str_replace('+', '', $code));

   if ($phoneUtil->isValidNumberForRegion($numberProto, $codAllowed[0])) {
      $valid = checkMobileDuplicate($mobile, $code);
      if ($valid == 1) {
         return 1;
      } else {
         array_push($details, array("phone" => "Mobile number already exist "));
         return -1;
      }
   } else {
      array_push($details, array("phone" => "Invalid Mobile number "));
      return -1;
   }
}

function checkMobileDuplicate($mobile, $code) {
   $mob = str_replace($code, '', $mobile);

   $sql = ' (  SELECT id    FROM patients    WHERE ( mobile =   ? ||  phone =   ? ) and deleted = 0    )  ';
   $sql .= '  union ';
   $sql .= ' ( SELECT id   FROM patients    WHERE  ( mobile =   ? ||  phone =   ?  ) and deleted = 0  )';
   $sql .= '  union ';
   $sql .= ' ( SELECT id   FROM patients_web    WHERE   phone =   ?  and  verified = 1   and   deleted = 0    )';

   $patients = R::getAll($sql, [$mobile, $mobile, $mob, $mob, $mobile]);

   //  print_r($patients);

   if (count($patients) > 0) {
      return -1;
   } else {
      return 1;
   }
}

##############

function registerPatient($mobile, $name) {
   global $otp_valid;

   $otp = createOtp();
   $createDate = date('Y-m-d H:i:s');
   $expireDate = date('Y-m-d H:i:s', strtotime('+' . $otp_valid . ' minutes', strtotime(date("Y-m-d H:i:s"))));
   addNewWebPatient($mobile, $name, $otp, $createDate, $expireDate);
   $result = array(
       "success" => true
       , "message" => 'OTP sent to your mobile number'
       , "data" => array(
           "mobile" => $mobile
           , "otp" => $otp
           , "otp_expires_at" => $expireDate
       )
   );

   return $result;
}

function addNewWebPatient($mobile, $name, $otp, $createDate, $expireDate) {
   $patient = R::findOne('patients_web', ' name = ? and  phone = ? and verified = ?  and deleted = ?  order by create_date desc '
                   , [$name, $mobile, 0, 0]);
   if (!($patient && count($patient) > 0)) {
      $patient = R::xdispense('patients_web');
      $patient->name = $name;
      $patient->phone = $mobile;
      $patient->verified = 0;
      $patient->deleted = 0;
      $patient->create_date = date('Y-m-d H:i:s');
   }

   $patient->otp = $otp;
   $patient->otp_create_date = $createDate;
   $patient->otp_expire_date = $expireDate;

   R::store($patient);
}

######################################################

function createOtp($length = 6) {
   // Calculate the minimum and maximum values for the desired length
   $min = pow(10, $length - 1);
   $max = pow(10, $length) - 1;

   // Generate a random integer within the range
   $otp = str_pad(random_int($min, $max), $length, '0', STR_PAD_LEFT);

   return $otp;
}

function errorObj($code, $message, $details) {
   $result = array(
       "success" => false
       , "error" => array(
           "code" => $code
           , "message" => $message
           , "details" => $details
       )
   );

   return $result;
}

####################################################

function validateJWT() {

   $jwt = null;
   foreach (getallheaders() as $name => $value) {
      if ($name == "Key") {
         $jwt = $value;
      }
   }

   try {
      $decoded_key = JWT::decode($jwt, getenv('api_key'), array('HS256'));
      if ($decoded_key->username === getenv('api_user')) {
         if ($decoded_key->password === getenv('api_password')) {
            //continue below
         } elseif ($decoded_key->password !== getenv('api_password')) {
            //echo "e1";
            header("HTTP/1.1 401 Method not NotAllowed");
            exit();
         }
      } else {
         //echo "e2";
         header("HTTP/1.1 401 Method not NotAllowed");
         exit();
      }
   } catch (Exception $e) {
      //echo "e3";
      //echo $e->getTraceAsString();
      header("HTTP/1.1 401 Method not NotAllowed");
      exit();
   }
}

######################################################

function onlineTests() {
   $result = array("success" => 0, "error" => 0, "errorMsg" => '', "tests" => array());

   try {
      $result = loadOnlineTests($result);
      $result['error'] = 0;
      $result['success'] = 1;
      $result['errorMsg'] = "";
   } catch (Exception $ex) {
      $result['success'] = 0;
      $result['error'] = 1;
      $result['errorMsg'] = "Error !!!!!!!!!!!!!!!";
   }

   //print_r($result);
   echo json_encode($result);
}

function loadOnlineTests($result) {
   //    r::debug(true, 2);

   $invests = R::getAll('select invests.id ,  invests.name   ,  invests.name_ar  
                                                    from invests
                                                   join  investcats      on    investcats.id = invests.investcatid
                                                 where   invests.deleted = 0 and investcats.deleted = 0 
                                                           and invests.active_online = 1
                                                 order by   invests.periority  desc  , invests.name asc ');

   //  r::debug(false);
//    print_r($invests);

   $result['tests'] = $invests;
   return $result;
}

######################################################

function onlineOffers() {
   $result = array("success" => 0, "error" => 0, "errorMsg" => '', "offers" => array());

   try {
      $result = loadOnlineOffers($result);
      $result['error'] = 0;
      $result['success'] = 1;
      $result['errorMsg'] = "";
   } catch (Exception $ex) {
      $result['success'] = 0;
      $result['error'] = 1;
      $result['errorMsg'] = "Error !!!!!!!!!!!!!!!";
   }

   //print_r($result);
   echo json_encode($result);
}

function loadOnlineOffers($result) {
   //    r::debug(true, 2);

   $offers = R::getAll('select invoffer.id ,  invoffer.name     ,  invoffer.name_ar  
                                                    from invoffer
                                                 where   del = 0 and active = 1    and active_online = 1 ');

   $i = 0;
   foreach ($offers as $offer) {
      $invs = R::getRow('SELECT  sum(price) as price   FROM  invofferdetails where invoffer_id = ? and  del = ?  ', [$offer['id'], 0]);

      $offerInvests = R::getAll('select  invofferdetails.id , invests.name , invests.name_ar , invofferdetails.price  
                                                    from invofferdetails
                                                   join  invests            on    invests.id = invofferdetails.inv_id
                                                 where    invofferdetails.invoffer_id = ? and  invofferdetails.del = ? ', [$offer['id'], 0]);

      $offers[$i]['price'] = $invs['price'];
      $offers[$i]['offerInvests'] = $offerInvests;
      $i++;
   }

   //  r::debug(false);


   $result['offers'] = $offers;
   return $result;
}

######################################################

function onlineVisits() {
   $result = array("success" => 0, "error" => 0, "errorMsg" => '', "offers" => array());

   try {
      $result = addOnlineVisits($result);
      $result['error'] = 0;
      $result['success'] = 1;
      $result['errorMsg'] = "";
   } catch (Exception $ex) {
      $result['success'] = 0;
      $result['error'] = 1;
      $result['errorMsg'] = "Error !!!!!!!!!!!!!!!";
   }

   //print_r($result);
//   echo json_encode($result);
}

function addOnlineVisits() {
   $visitRequest = json_decode(file_get_contents("php://input"));
   print_r('<pre>');
   print_r($visitRequest);
   print_r('</pre>');
}
