<?php

session_start();
if (!isset($_POST['SubDir'])) {
    echo('{"Error":"Configuration Directory not sent"}');
    goto end;
}

function MoveOrder($order, $issue = "Unknown", $delete = true)
{
    global $dbo;
    $ordermove = $order;
    unset($ordermove['ID'], $ordermove['RequestDate'], $ordermove['ReceiptDate']); //
    $ordermove['Issue'] = $issue;
    $move = $dbo->Insert("order_ex_tb", $ordermove);
    // exit('{"Error":"'.$move.'","Ref":"'.$order['TransNum'].'"}');
    if ($delete) {
        //delete the order 
        $del = $dbo->Delete("order_tb", "ID=" . $order['ID']);
        return 0;
    } else {
        $del = $dbo->Update("order_tb", ["ExpiredRef" => $order['ExpiredRef'] . ":" . $order['TransNum'] . ":", "Amt" => $order['Amt']], "ID=" . $order['ID']);
        return (int)$order['ID'];
    }
}

//keep SubDir in session
$_SESSION['SubDir'] = $_POST["SubDir"];

//$Config = json_decode(urldecode($_POST['Config']),true);
$configdir = __DIR__."/../../../../" . urldecode($_POST["SubDir"]);
require_once(__DIR__."/../config.php");
require_once(__DIR__."/../TaquaLB/Elements/Elements.php");
require_once(__DIR__."/../getinfo.php");
global $dbo;


extract($_POST);

if (!isset($RegNo) || !isset($Lvl) || !isset($Sem) || !isset($SemPart) || !isset($PayID)) {echo('{"Error":"Invalid Payment Details"}');goto end;}

//BrkDwn
$BankPre = isset($BankPre) ? $BankPre : 'a';
/* exit('{"Error":"INVALID CANDIDATE/STUDENT' . $BankPre . '"}');
 */

//get student details
$studDet = GetBasicInfo($RegNo, "", $BankPre, 1, MYSQLI_ASSOC);

//exit('{"Error":"' . $BankPre . '"}');
$fregno = $dbo->SqlSafe($RegNo);

//if(!is_array($studDet))exit('{"Error":"Reading Payee Details Failed"}');
if (!is_array($studDet)) {
    if ($BankPre == 'a') $BankPre = 'p';
    //get details without getting other details by prog id
    $query = "(SELECT st.id as StudID, st.SurName, st.FirstName, st.OtherNames, CONCAT(st.SurName,' ', st.FirstName,' ', st.OtherNames) as Name, st.Gender, st.DOB,'' as FacName, 0 as FacID, st.RegNo, st.JambNo, '' as DeptName, '' as ProgName, '' as DegreeName, st.ModeOfEntry, st.RegDate, st.Passport, st.StateId, st.LGA, st.JambAgg, st.Accept, st.RegLevel, st.Addrs, st.Email, st.ProgID,st.OlevelRstDetails, st.OlevelRst, st.Phone,st.BloodGroup, sd.Name as StudyName, sd.AcceptLetter, st.StudyID, st.OtherDet, st.RegID,  'STUDENT' as StudType FROM studentinfo_tb st, study_tb sd WHERE (st.JambNo = '{$fregno}' OR st.RegNo = '{$fregno}') AND '{$fregno}' != '' AND st.StudyID = sd.ID)
    UNION
    (SELECT st.id as StudID, st.SurName, st.FirstName, st.OtherNames, CONCAT(st.SurName,' ', st.FirstName,' ', st.OtherNames) as Name, st.Gender, st.DOB,'' as FacName, 0 as FacID, st.RegNo, st.JambNo, '' as DeptName, '' as ProgName, '' as DegreeName, st.ModeOfEntry, st.RegDate, st.Passport, st.StateId, st.LGA, st.JambAgg, st.Accept, st.RegLevel, st.Addrs, st.Email, st.ProgID,st.OlevelRstDetails, st.OlevelRst, st.Phone,st.BloodGroup, sd.Name as StudyName, sd.AcceptLetter, st.StudyID, st.OtherDet, st.RegID,  'CANDIDATE' as StudType FROM {$BankPre}studentinfo_tb st, study_tb sd WHERE (st.JambNo = '{$fregno}' OR st.RegNo = '{$fregno}') AND '{$fregno}' != '' AND st.StudyID = sd.ID) LIMIT 1";
    $studDet = $dbo->RunQuery($query);
    if (!is_array($studDet)) {
        //get details from payee tb
        $studDet = $dbo->SelectFirstRow("payee_tb", "PayeeID as RegNo, 0 as ProgID", "PayeeID='" . $dbo->SqlSafe($RegNo) . "'");
        if (!is_array($studDet)) {echo('{"Error":"INVALID CANDIDATE/STUDENT"}');goto end;}
    } else {
        if ($studDet[1] > 0) {
            $studDet =  $studDet[0]->fetch_assoc();
        } else {
            $studDet = $dbo->SelectFirstRow("payee_tb", "PayeeID as RegNo, 0 as ProgID", "PayeeID='" . $dbo->SqlSafe($RegNo) . "'");
            if (!is_array($studDet)) {echo('{"Error":"INVALID CANDIDATE/STUDENT"}');goto end;}
        }
    }
    
}
if (trim($studDet['OtherDet']) != "") {
    $otherdet = json_decode($studDet['OtherDet'], true);
    $studDet = array_merge($studDet, $otherdet);
}
$Ref = NULL; //hold the payment reference number 
$TransOrderID = 0; //0=> will insert new order, >0=>will update the order Ref
//Get School Details
$schdet = GetSchool("OrderValidity,email,UniqueTransID");

//if student Email not set use the school email
if (!isset($studDet['Email']) || trim($studDet['Email']) == "") $studDet['Email'] = $schdet['email'];




//Get the payment Item Details
$PayItemDet = $dbo->SelectFirstRow("item_tb", "", "ID=" . $PayID, MYSQLI_ASSOC);
if (!is_array($PayItemDet)) {echo('{"Error":"Reading Payment Type Failed"}');goto end;}

//Comfirm if order exist (Normal School Payment) @@Must be based on wallet payment or school payment
if ($PayItemDet['studType'] != "w") { //for non wallet payment get order details using student academic details
    $order = $dbo->SelectFirstRow("order_tb", "", "RegNo='" . $dbo->SqlSafe($RegNo) . "' AND ItemID=$PayID AND Lvl=" . $dbo->SqlSafe($Lvl) . " AND (Sem = " . $dbo->SqlSafe($Sem) . " OR Sem = 3) AND (ProgID=" . $studDet['ProgID'] . " OR ProgID = 0) AND SemPart=" . $dbo->SqlSafe($SemPart), MYSQLI_ASSOC);
} else { //for wallet payment (deposit), check order by the amount to deposit
    //use this oportunity to check if a valid wallet payment i.e amount sent
    if (!isset($Amt) || (float)$Amt <= 0) {echo('{"Error":"Invalid Amount Specified"}');goto end;}
    $order = $dbo->SelectFirstRow("order_tb", "", "RegNo='" . $dbo->SqlSafe($RegNo) . "' AND ItemID=$PayID AND Amt=" . (float)$Amt, MYSQLI_ASSOC);
}


 
//if exist
if (is_array($order)) {
    //check if payment already made for none wallet payment
    //if($order['Paid'] == 1 && $PayItemDet['studType'] != "w")exit('{"Error":"Payment Already Made","Ref":"'.$order['TransNum'].'"}'); //@@ wallet payment does not have already paid - rather it craete another order
    //check from paygateway
   
    $paid = HasPaidRef($order['TransNum'], $order);
    //exit('{"Error":"'.$paid[0].'"}');
    //$rtn = ["Error"=>$paid[0],"Ref"=>$order['TransNum']];
    //exit(json_encode($rtn));
    //if already paid for non wallet, return allready paid
    if ($paid[0] == 1 && $PayItemDet['studType'] != "w") {echo('{"Error":"Payment Already Made","Ref":"' . $order['TransNum'] . '"}');goto end;}
    //not paid, check if the current order is still valid

    if ($paid[0] == 0) { //if not paid
        //get the order date
        $OrderDate = date_create($order['RegDate']);
        $Now = date_create(date("Y-m-d"));
        $diff = date_diff($OrderDate, $Now);
        $days = (int)$diff->format('%R%a');
        //get the validity days
        if ($days > (int)$schdet['OrderValidity'] || $schdet['UniqueTransID'] == "TRUE") { //if not valid

            $issue = ($days > (int)$schdet['OrderValidity']) ? "Transaction (Order) Expired" : "Transaction ID Re-generated";
            $TransOrderID = MoveOrder($order, $issue, false); //up
            /* $ordermove = $order;
            unset($ordermove['ID']);
            $ordermove['Issue'] = $issue;
            $move = $dbo->Insert("order_ex_tb",$ordermove);
        //delete the order 
        $del = $dbo->Delete("order_tb","ID=".$order['ID']); */
            //exit('{"Error":"Order Expired and Deleted"}');
        } else { //if still valid
            // exit('{"Error":"Order Not Expired"}');
            //check if the New Amt is same as old amt
            //exit('{"Error":"'.json_encode(VerifyPayFromGateway('140279641557',$order)).'"}');
            if (trim($Amt) == '' || (float)$Amt == (float)$order['Amt']) {echo('{"Ref":"' . $order['TransNum'] . '","Amt":' . $order['Amt'] . '}');goto end;}
            $order['Amt'] = $Amt;
            //delete the order - amount has changed
            $TransOrderID = MoveOrder($order, "Transaction Amount Has Changed", false);
            //$del = $dbo->Delete("order_tb","ID=".$order['ID']);
        }
    }
} else {
    //exit('{"Error":"Order Not Found - '.$order.'"}');
}


if ((int)$PayItemDet['Currency'] > 0) {
    $cur = $dbo->SelectFirstRow("currency_tb", "", "ID=" . $PayItemDet['Currency']);
    $PayItemDet['Currency'] = is_array($cur) ? $cur['Name'] : $PayItemDet['Currency'];
}

//the logic operator initial was || but incase of Dynamic amount where user spaecify the amount is not supose to generate breakdown
//e.g wallet payment 
//exit('{"Error":"Storing order details Failed - f'.$Amt.'"}');

if (trim($BrkDwn) == "") { //if no breakdown supplied and user did not sent amt
    //Generate the breakdown
   
    $anal = PaymentBreakDown($PayItemDet['PayBrkDn'], $Lvl, $Sem, $studDet, $SemPart);
    
    $BrkDwn = is_array($anal) ? $anal[2] : "";
    if (!isset($Amt)) $Amt = $anal[0];
    
}

//exit(json_encode(["Error"=>$BrkDwn]));
if ((float)$Amt <= 0.0) {echo('{"Error":"Invalid Payment: No Payment Item Found"}');goto end;}

//get the payment gateway details
$PayGateWayDet = $dbo->SelectFirstRow("thirdparty_tb", "", "ID=" . $PayItemDet['PayGatewayID'], MYSQLI_ASSOC);
if (!is_array($PayGateWayDet)) {echo('{"Error":"Reading Payment Gateway Details Failed"}');goto end;}

$params = $_POST; //payment details
//update  Amt
$params['Amt'] = $Amt;

$gatewayparam = $PayGateWayDet['USE'] == "LIVE" ? $PayGateWayDet['PARAM'] : $PayGateWayDet['DEMO_PARAM'];
//remove gateway param
unset($PayGateWayDet['PARAM']);
unset($PayGateWayDet['DEMO_PARAM']);

//Order ID - generted from EP
$OrderID = mt_rand(1000, 999999999) . date("U") . (isset($studDet['StudID']) ? $studDet['StudID'] : $studDet['ID']);

//form the finish url (response url)
//$resurl = _CURURL_;
$resurl = $dbo->Config['Core2'] . "general/Payment/finish.php";

$params = array_merge($params, $PayGateWayDet, $dbo->DataArray($gatewayparam), $studDet, ["ItemName" => $PayItemDet['ItemName'], "ItemDescr" => $PayItemDet['ItemDescr'], "Currency" => $PayItemDet['Currency'], "ItemRef" => $PayItemDet['PaymentID'], "OrderID" => $OrderID, "FinishUrl" => $resurl]);

//exit('{"Error":"aaa"}');

   
//include the payment gateway script epconfig/gateways/etranzact_script.php
$scrarr = explode("/", $PayGateWayDet['Script']);

require_once "Gateways/" . $scrarr[count($scrarr) - 1];

//require_once "../../../epconfig/Gateways/etranzact_script.php";


if (function_exists($PayGateWayDet['PrePayMethod'])) {
     
    $rst = call_user_func($PayGateWayDet['PrePayMethod'], $params);
    //exit('{"Error":"'.json_encode($rst).'"}');
    //expect an array {"Error":"...."} OR {"Ref":"....."}
    if (isset($rst['Ref'])) {

        //insert the order
        //get the current session
        $CurSes = CurrentSes();
        $CurSes = $CurSes['SesID'];
        $HeihestSemNum = HighestSemester();
        $PaySem = (int)$Sem > (int)$HeihestSemNum['Num'] ? (int)$HeihestSemNum['Num'] : $Sem;

        $orderData = [
            "ItemNo" => $OrderID,
            "TransNum" => $rst['Ref'],
            "ItemName" => $PayItemDet['ItemName'],
            "ItemDescr" => isset($PayDescr) && trim($PayDescr) != ''?$PayDescr:$PayItemDet['ItemDescr'],
            "Amt" => $Amt,
            "Currency" => $PayItemDet['Currency'],
            "RegNo" => $RegNo,
            "SemPart" => $SemPart,
            "Sem" => $Sem,
            "Lvl" => $Lvl,
            "ItemID" => $PayID,
            "Paid" => 0,
            "Ses" => $CurSes,
            "RegDate" => date('Y-m-d'),
            "BrkDwn" => $BrkDwn,
            "PayGatewayID" => $PayItemDet['PayGatewayID'],
            "Info" => StudPatchDet($RegNo, $PayID, $Lvl, $BankPre),
            "PayScope" => $PayItemDet['studType'],
            "SchSem" => $PaySem,
            "ProgID" => $studDet['ProgID']
        ];
      
        if ($TransOrderID < 1) {
            $insorder = $dbo->InsertID2("order_tb", $orderData);
        } else {
            
            $updorder = $dbo->Update("order_tb", $orderData, "ID=" . $TransOrderID);
            $insorder = is_array($updorder) ? $TransOrderID : $updorder;
           
        }

        if (!is_numeric($insorder) || $insorder < 1) {echo('{"Error":"Storing order details Failed"}');goto end;}
        $rst['PayUrl'] = isset($rst['PayUrl'])?$rst['PayUrl']:'';
       
       //echo '{Ref":"' .$rst['Ref'] .'","Amt":' .'2000'. '}' ;
       // exit;
        echo '{"Ref":"' . $rst['Ref'] . '","Amt":"' . $Amt . '"}';goto end;
    } else {
        if (isset($rst['Error'])) {echo(json_encode($rst));goto end;}
        echo '{"Error":"Invalid Error Message from Gateway Script"}';
    }
} else {
    echo '{"Error":"Gateway initialization module not found"}';goto end;
}
end:
//echo "";
//exit('{"Error":"'.$dbo->DataString($params).'"}');
