<?php

//R041
function LoadResultHistory($Param){
    global $dbo;
        HasLogin($Param);
    
    //get student details
    $studDet = $dbo->SelectFirstRow("studentinfo_tb","","RegNo='{$Param['LoginName']}' OR JambNo='{$Param['LoginName']}' LIMIT 1");
    if(!is_array($studDet))Error(8);

    //get student current lvl sm
    //$curlvlsem = GetStudentCurrentLevelSemester($Param);

    // $lstcreg = $dbo->SelectFirstRow("coursereg_tb","","RegNo='".$dbo->SqlSafe($RegNo)."' ORDER BY SesID DESC, Lvl DESC, Sem DESC",MYSQLI_ASSOC);
       
    //get all Student Result
    $studrst = $dbo->Select("result_tb r, coursereg_tb c","r.*","(r.RegNo='{$studDet['RegNo']}' OR r.RegNo='{$studDet['JambNo']}') AND c.RegNo = r.RegNo AND r.Lvl=c.Lvl AND r.Sem=c.Sem AND r.SesID=c.SesID ORDER BY r.Lvl DESC, r.Sem DESC, r.GroupID DESC",MYSQLI_ASSOC);
    
    if(!is_array($studrst))Error(4, " : Reading Reading Result");
    if($studrst[1] < 1)Error(43);
    
    
    //loop and form the history array
    $HistArr = [];
    //for speed and optimization do an internal cache
    $LevelName = [];
    $SemesterName = [];
    $SessionName = [];
    $Found = [];
    $RstInfo = [];
    while($studRsti = $studrst[0]->fetch_assoc()){
        //get the course RegDetails
        if(!isset($LevelName[$studRsti['Lvl']])){ //if not in cache
          //get it
          $LevelName[$studRsti['Lvl']] = GetStudentLevelName($studRsti['Lvl'],$studDet['StudyID'],$studDet['ProgID']);
        }
        if(!isset($SemesterName[$studRsti['Sem']])){ //if not in cache
            //get it
            $SemesterName[$studRsti['Sem']] = GetStudentSemesterName($studRsti['Sem']);
          }
          if(!isset($SessionName[$studRsti['SesID']])){ //if not in cache
            //get it
            $SessionName[$studRsti['SesID']] = GetSessionName($studRsti['SesID']);
          }

          if(!isset($RstInfo[$studRsti['RstInfoID']])) {
            $rstset = $dbo -> SelectFirstRow("resultinfo_tb","","ID = '" . $studRsti['RstInfoID'] . "'");
            $RstInfo[$studRsti['RstInfoID']] = FALSE;
            if(is_array($rstset)) $RstInfo[$studRsti['RstInfoID']] = $rstset['PinVerify'] == "TRUE"? TRUE:FALSE; 
          }
    
    if(isset($Found[$studRsti['Lvl']."_".$studRsti['Sem']."_".$studRsti['SesID']]))continue;
    $Found[$studRsti['Lvl']."_".$studRsti['Sem']."_".$studRsti['SesID']] = true;
        $TRC = (int)$studRsti['TRC'];
    if($TRC < 1){
        if(trim($studRsti['Rst']) == "")continue; //if noresult upoaded yet
      $TRC = count(explode("&",$studRsti['Rst']));
    }
          
    $RegDate = date('d, M Y', strtotime($studRsti['RstDate']));
    if($RegDate == date('d, M Y'))$RegDate = "Today";
          $HistArr[] = ["SessionName"=>$SessionName[$studRsti['SesID']],"LevelName"=>$LevelName[$studRsti['Lvl']],"SemesterName"=>$SemesterName[$studRsti['Sem']],"ResultID"=>$studRsti['ID'],"ResultDate"=>$RegDate,"TRC"=>$TRC,"AllowPin"=>$RstInfo[$studRsti['RstInfoID']]];
    
    }
    return $HistArr;
    
    }
    

//R042
function LoadResultDetails($Param){
global $dbo;global $__Root__;
    HasLogin($Param);
    $studDet = $dbo->SelectFirstRow("studentinfo_tb","RegNo,JambNo,ProgID,ClassID,StartSes","RegNo='{$Param['LoginName']}' OR JambNo='{$Param['LoginName']}' LIMIT 1",MYSQLI_ASSOC);
          if(!is_array($studDet))Error(8);
    //Error(0,$Param['ResultID']);
    $rsult = $dbo->SelectFirstRow("result_tb","","(RegNo='".$dbo->SqlSafe($studDet['RegNo'])."' OR RegNo='".$dbo->SqlSafe($studDet['JambNo'])."') and ID = {$Param['ResultID']} LIMIT 1",MYSQLI_ASSOC);
     if(!is_array($rsult))Error(44); //invalid result

     //get the result settings
     $rstset = $dbo -> SelectFirstRow("resultinfo_tb","","ID = (select GrdStrucID from school_tb limit 1)");
     if(!is_array($rstset))Error(45); //invalid result setting

     $PrePayStatus = (int)$rstset['PrePayStatus'];
     if($PrePayStatus == 1){//if to verify Payment
        
        list($studschlvl,$studschsem) = GetStudentLevelSemesterWhenSchoolStart($Param['LoginName']);
        //Error("CE",$studschlvl."-".$studschsem."-".$Param['LoginName']);
           //if result lvl is less than the student level wen school start, or the result level is same and the result sem is less than wen school sem start: implies that the result exist before the system start processing i.e should be made visible 
           if($studschlvl < (int)$rsult['Lvl'] || ($studschlvl == (int)$rsult['Lvl'] && $studschsem <= $rsult['Sem'])){
        $PayID = (int)$rstset['PrePayID'];
        $PrePayBases = (int)$rstset['PrePayBases'];
                //get the payment details
                $PayDet = $dbo -> SelectFirstRow("item_tb","","ID = $PayID LIMIT 1");
                if(!is_array($PayDet))Error(46); //invalid payment type 

                if($PrePayBases < 2){ //if full payment required
                    //full payment
                    $semcond = "AND SemPart > 1";
                }else{  //if part payment
                    $semcond = "AND SemPart >= 1";
                }
                
                //get the order details
                $OrderDet = $dbo -> SelectFirstRow("order_tb","","ItemID = $PayID AND (RegNo='".$dbo->SqlSafe($studDet['RegNo'])."' OR RegNo='".$dbo->SqlSafe($studDet['JambNo'])."') AND Lvl = {$rsult['Lvl']} AND (Sem = {$rsult['Sem']} || Sem = (SELECT COUNT(ID) + 1 FROM semester_tb WHERE Enable = 1)) $semcond AND ProgID=".$studDet['ProgID']." ORDER BY SemPart DESC, ID DESC LIMIT 1");
                
                $err = '<br />'.$PayDet['ItemName'].'<br /> Use the <span class="appcolor">Payment</span> <i class="fas fa-chevron-right"></i> <span class="appcolor">School</span>  Module to make Payment';
                //check if order exist
                // if(!is_array($OrderDet))Error(13,$err );
                $haspaid = false;
               // Error("CE","ItemID = $PayID AND (RegNo='".$dbo->SqlSafe($studDet['RegNo'])."' OR RegNo='".$dbo->SqlSafe($studDet['JambNo'])."') AND Lvl = {$rsult['Lvl']} AND (Sem = {$rsult['Sem']} || Sem = (SELECT COUNT(ID) + 1 FROM semester_tb WHERE Enable = 1)) $semcond AND ProgID=".$studDet['ProgID']." ORDER BY SemPart DESC LIMIT 1");
                if(!is_array($OrderDet))Error(13,$err);
                    
                    //get the ref
                    $Ref = $OrderDet['TransNum'];
                    //verify payment
                    $paid = HasPaidRef($Ref,$OrderDet);
                    // if($paid[0] != 1)Error(13,$err);
                    if($paid[0] != 1)Error(13,$err);
                /* else{
                    
                } */
                if(!$haspaid){
                    //check if the result is below the school start details
                    
                    
                }
           }
        
      }

      // verify scratch card pin
       $PinVerify = $rstset['PinVerify'];
      if($PinVerify == "TRUE") {
      $RstID = $Param['ResultID'];

        // check if pin exists
        $Pin = $Param['Pin'];
        $PinDet = $dbo->SelectFirstRow("pin_tb", "", "Pin = '$Pin' AND (RstID = '$RstID' OR ISNULL(RstID))",MYSQLI_ASSOC);

        if(!is_array($PinDet)) Error(73,$RstID);
        // if pin is not assigned, assign it
        if ($PinDet['RstID'] == null) {
          $AssignPin = $dbo->Update("pin_tb", ["RstID" => $RstID], "Pin = '$Pin'");
          if(!is_array($AssignPin)) Error(4);
        }

        $now = date("Y-m-d H:i:s");
        // check pin expiration
        if (!is_null($PinDet['ExpiryDate']) && $now > $PinDet['ExpiryDate']) Error(74);
        // check if max usage is exceeded
        if ($PinDet['PinUsage'] >= $PinDet['MaxUsage']) Error(75);
        // use pin and increase usage by 1
        $PinDet['PinUsage'] = (int)$PinDet['PinUsage'] + 1;
        $UsageUpdate = $dbo->Update("pin_tb", ["PinUsage" => $PinDet['PinUsage']], "Pin = '$Pin'");
        if(!is_array($UsageUpdate)) Error(4,$UsageUpdate);
      }   
    
        //get the uploaded results
        $Rst  = trim($rsult['Rst']);
        if($Rst == "")Error(43); //no result
        $RstInfo = trim($rsult['RstInfo']);
        $RstInfoObj = [];
        if($RstInfo == ""){
            
            //get the grading structure and others
            $SemCourses = GetCourses($studDet['ProgID'],$rsult['Lvl'], $rsult['Sem']);
            //get grading details
       //$grdstr = $dbo -> SelectFirstRow("resultinfo_tb","","ID = (select GrdStrucID from school_tb limit 1)");
        // $grdstr = is_array($grdstr)?$grdstr[1]:"";
        // $schgrdstr = GetGradeDetAll();
        }else{
            $RstInfoObj = json_decode($RstInfo,true);
        }

        //get results
        $RstArr = $dbo->DataArray($Rst);
        $RstDet = [];
        $posbycourse = false;
        $PortalResultDisplay = [];
        if(!is_null($rstset['PortalResultDisplay'])){
            $PortalResultDisplay = json_decode($rstset['PortalResultDisplay'],true);
            if(isset($PortalResultDisplay['POSCourse']) && (int)$PortalResultDisplay['POSCourse'] == 1){
                $AllClassStudTotScoreByCourse = GetStudentClassResultsAllCourse($rsult,$studDet,true);
                $posbycourse = true;
            }
        }
        //loop through individual result
        foreach ($RstArr as $CID => $IndRst) {
            if($posbycourse){
               $courserstdet = StudentPositionBySubjectinClass($Param['LoginName'],$CID,$AllClassStudTotScoreByCourse);
              $CAVG = $courserstdet['AVG'];
              $subjposord = $courserstdet['POS']; 
            }
            
            $CDet = [];
            //check if course details exist in $RstInfo
            if(isset($RstInfoObj[$CID])){
                $CDet = $RstInfoObj[$CID];
            }else{
                $CDet = isset($SemCourses[$CID])?$SemCourses[$CID]:CourseDetails($CID);       
            }

            $IndRstArr = explode("|",$IndRst);
            $Scores = $IndRstArr[0];
            $MaxScores = $IndRstArr[1];
            $Point = $IndRstArr[2];
            $Grade = $IndRstArr[3];
            $GradeDescr = $IndRstArr[4];
            $passed = $IndRstArr[5]; //1-PASS, 0-FAILED
            $CH = $IndRstArr[6];
            $GradePoint = $IndRstArr[7];
            $MaxScoresArr = [];
            //check if <v4 structure
            $commexist = strpos($Scores,",");
            if($commexist !== FALSE){ //=>v4
                //get ind scores
                $ScoresArr = explode(",",$Scores);
                $MaxScoresArr = explode(",",$MaxScores);
            }else{
                $ScoresArr = [$Scores,$MaxScores];//CA and Exam
            }

            $tot = array_sum($ScoresArr);
            $rstatus = (int)$passed <= 0?"FAILED":"PASSED";

            //check if course is approved
            $chkappr = $dbo->SelectFirstRow("resultapprove_tb","","Ses= {$rsult['SesID']} AND CourseID=$CID");
           // if(!is_array($chkappr))Error(45," (".$CDet['Title']." - ".$CDet['CourseCode'].")");
            if((!is_array($chkappr) || $chkappr['Status'] == "FALSE") && (int)$rstset['ViewOnApprove'] > 0){
               $dett = !is_array($chkappr)?"APPROVAL ERROR":"NOT APPROVED";
                $RstDet[] = ["CourseCode"=>PlainText($CDet['CourseCode']),"CourseCH"=>$CH,"CourseTitle"=>PlainText($CDet['Title']),"Total"=>"-","GradePoint"=>"-","Status"=>$dett,"Details"=>[],"Grade"=>"-","CourseID"=>$CID];
            }else{
                $Details = [];
                $StucArr = !is_null($chkappr['ScoreStruc'])?json_decode($chkappr['ScoreStruc'],true):["Assessment","Examination"];
                $MaxStucArr = !is_null($chkappr['ScoreStrucMax'])?json_decode($chkappr['ScoreStrucMax'],true):[];
                for($as=0; $as<count($StucArr); $as++){
                    $rScore = isset($ScoresArr[$as])?$ScoresArr[$as]:0;
                    $Details[] = ["StrucName"=>$StucArr[$as],"StrucScore"=>$rScore,"StrucMax"=>isset($MaxStucArr[$as])?("/".$MaxStucArr[$as]):"","StrucDescr"=>""];
                }
                $Details[] = ["StrucName"=>"TOTAL","StrucScore"=>$tot,"StrucMax"=>count($MaxStucArr)>0?("/".array_sum($MaxStucArr)):"","StrucDescr"=>""];
                $Details[] = ["StrucName"=>"GRADE","StrucScore"=>$GradeDescr,"StrucMax"=>" (".$Grade.")","StrucDescr"=>$GradeDescr];
                if($posbycourse){
                    $Details[] = ["StrucName"=>"AVG","StrucScore"=>$CAVG,"StrucMax"=>"","StrucDescr"=>""];
                    $Details[] = ["StrucName"=>"POSITION","StrucScore"=>$subjposord,"StrucMax"=>"","StrucDescr"=>""];
                }
                
                
                $RstDet[] = ["CourseCode"=>PlainText($CDet['CourseCode']),"CourseCH"=>$CH,"CourseTitle"=>PlainText($CDet['Title']),"Total"=>$tot,"GradePoint"=>$GradePoint,"Status"=>$rstatus,"Details"=>$Details,"Grade"=>$Grade,"CourseID"=>$CID];
            }
        }
       unset($rsult['RstInfo']);
       unset($rsult['Rst']);
       unset($rsult['COPRule']);
       unset($rsult['COPDetails']);
       unset($rsult['Rept']);
       unset($rsult['Outst']);
       //form the display result array
       $DisRest = [];
       if(count($PortalResultDisplay) > 0){
         $PortalResultDisplay = json_decode($rstset['PortalResultDisplay'],true);
         //check if position is visible
         $rsult['POS'] = "--";
         //check if position is visible
	//$rstarr['POS'] = "--";
	if($PortalResultDisplay['POS'] == 1){
		$rsult['POS'] = GetStudentResultPosition($rsult,$studDet);
		
		//$rstarr['POS'] = FormatPos($rstarr['POS']);
	}
	if($PortalResultDisplay['POSClass'] == 1){
		$rsult['POSClass'] = GetStudentResultPosition($rsult,$studDet,true);
		//$rstarr['POSClass'] = FormatPos($rstarr['POSClass']);
	}

	if($PortalResultDisplay['AVGClass'] == 1){
		$classrstdet = GetStudentOverallClassResultDetails($rsult,$studDet,true);
  $classavg =round($classrstdet[2]/$classrstdet[0],2);
  $rsult['AVGClass'] = $classavg ;
	}
         $DescrArr = ["GPA"=>["GPA","GPA"],"CGPA"=>["CGPA","CGPA"],"TOT"=>["Total","OTS"],"AVG"=>["Average","OAS"],"AVGClass"=>["Class Average","AVGClass"],"POS"=>["Level Position","POS"],"POSClass"=>["Class Position","POSClass"],"COP"=>["Grade","COP"]];
         foreach($PortalResultDisplay as $Dis=>$stat){
             if($stat != 0 && isset($DescrArr[$Dis])){
                 if($stat == 1){
                    $DisRest[] = ["Title"=>$DescrArr[$Dis][0],"Value"=>$rsult[$DescrArr[$Dis][1]]]; 
                 }else{
                    $DisRest[] = ["Title"=>$DescrArr[$Dis][0],"Value"=>"--"]; 
                 }
             }
         }

       }

       $ardata = "{Src:'{$__Root__}general/Slip.php?RID=".$rsult['ID']."&folder=Result&file=Slipi.php&SubDir=".urlencode($dbo->Config['SubDir'])."',PayperType:'A4',Orientation:'P',MarginTop:4,MarginBottom:4}";
    //$Param["PrintData"] = $ardata;


        return array_merge($rsult,["ResultDetails"=>$RstDet,"Overal"=>$DisRest,"PrintData"=>$ardata,"PinDetails"=>isset($PinDet)?$PinDet:[]]);
        //return ["GPA"=>1.7];
            
       // Error(0,json_encode($rsult));
    
}

function ResultCheckMenu($Param=[]){
    global $dbo;
    $menus = $dbo->SelectFirstRow("new_apply_tb a, new_apply_group_tb ag, resultcontrol_tb rc","a.ID,a.Name,a.Descr,a.GroupID,a.Logo,a.Color,a.Placeholder,ag.Logo as GroupLogo","a.ID=rc.CheckRstMenuID AND a.GroupID = ag.ID LIMIT 1",MYSQLI_ASSOC);
    if(!is_array($menus))$menus=["ID"=>0,"Name"=>"","Descr"=>"","GroupID"=>0,"Logo"=>"","Color"=>"","Placeholder"=>"textbox","GroupLogo"=>""];
    return ["CheckResultMenu"=>$menus];
}

?>

