<?php
namespace App\Libraries;

class ReportHelper
{
    protected $db;
    
    public function __construct($db)
    {
        $this->db = $db;
    }
    
    public function getReportData(string $accessnumber, int $eng): array
    {
        $hostnumber = $this->getHost($accessnumber);
        $result = $this->getResult($accessnumber, $eng);
        $info = $this->getData2($accessnumber);
        $notes = $this->getNotes($accessnumber);
        $others = $this->getOthers($accessnumber, $eng);
        $collData = $this->getCollData($accessnumber);
        $recvData = $this->getRecvData($accessnumber);
        $noSample = $this->getNoSample($accessnumber);
        
        $collData = $this->cutData($collData);
        $recvData = $this->cutData($recvData);
        
        if ($noSample == '') {
            $status = $this->getStatus($accessnumber);
        } else {
            $status = "PENDING";
        }
        
        $valBy = $this->getValBy($accessnumber);
        $valData = $this->getValData($accessnumber);
        $collectionDate = $this->getCollectionDateRaw($accessnumber);
        return [
            'hostnumber' => $hostnumber,
            'result' => $result,
            'info' => $info,
            'notes' => $notes,
            'others' => $others,
            'collData' => $collData,
            'recvData' => $recvData,
            'noSample' => $noSample,
            'status' => $status,
            'valBy' => $valBy,
			'val1User' => $valData['VAL1USER'] ?? '',
			'val2User' => $valData['VAL2USER'] ?? '',
			'val1Date' => isset($valData['VAL1DATE']) ? date('d-m-Y H:i', strtotime($valData['VAL1DATE'])) : '',
			'val2Date' => isset($valData['VAL2DATE']) ? date('d-m-Y H:i', strtotime($valData['VAL2DATE'])) : '',
            'date' => date('d-m-Y H:i'),
            'collectionDate' => $collectionDate
        ];
    }
    
    private function cutData(string $text): string
    {
        if (strlen($text) > 95) {
            $split_text = explode(" ", $text);
            $cut_length = 11;
            $split_text_cut1 = array_slice($split_text, 0, $cut_length);
            $split_text_cut2 = array_slice($split_text, $cut_length, count($split_text));
            $text1 = implode(" ", $split_text_cut1);
            $text2 = implode(" ", $split_text_cut2);
            $text = $text1 . "\r\n" . $text2;
        }
        return $text;
    }
    
    private function getHost(string $accessnumber): string
    {
        $sql = "SELECT EXTERNALORDERNUMBER FROM REQUESTS WHERE ACCESSNUMBER=?";
        $row = $this->db->query($sql, [$accessnumber])->getRowArray();
        return $row['EXTERNALORDERNUMBER'] ?? '';
    }
    
    private function getData2(string $accessnumber): string
    {
        $sql = "SELECT R.EXTERNALORDERNUMBER AS EXTERNALORDERNUMBER, 
            FORMAT(SR.COLLECTIONDATE,'dd-MM-yyyy') AS REQDATE, 
            P.NAME AS NAME, 
            RIGHT(P.PATNUMBER,16) AS PATNUM,
            dmg.DMG_CADDRESS AS DMG_CADDRESS, 
            P.TELEPHON AS TELEPHON, 
            P.EMAIL AS EMAIL,
            CASE
                WHEN P.SEX=1 THEN 'Male'
                WHEN P.SEX=2 THEN 'Female'
                ELSE 'Unknown'
            END AS SEX,
            CASE WHEN FORMAT(P.BIRTHDATE,'MMdd')=FORMAT(R.COLLECTIONDATE,'MMdd')
                THEN DATEDIFF(YEAR,P.BIRTHDATE, R.COLLECTIONDATE)
                ELSE FLOOR(DATEDIFF(DAY, P.BIRTHDATE, R.COLLECTIONDATE) / 365.25)
            END AS AGE,
            CASE WHEN DATEPART(day,R.COLLECTIONDATE) >= DATEPART(day,P.BIRTHDATE)
                THEN DATEDIFF(MONTH,P.BIRTHDATE, R.COLLECTIONDATE)%12
                ELSE DATEDIFF(MONTH, P.BIRTHDATE, DATEADD(MONTH,-1,R.COLLECTIONDATE))%12
            END AS AGEMONTHS,
            RO.COMMENTTEXT AS COMMENTTEXT, 
            dmg.DMG_CCITY AS DMG_CCITY, 
            P.BIRTHDATE AS BIRTHDATE, 
            T.SHORTTEXT AS SHORTTEXT
        FROM REQUESTS R
        LEFT JOIN SP_REQUESTS SR ON SR.SP_ACCESSNUMBER=R.ACCESSNUMBER
        LEFT JOIN PATIENTS P ON P.PATID=R.PATID
        LEFT JOIN REQUESTS_OCOM RO ON RO.REQUESTID=R.REQUESTID
        LEFT JOIN DICT_TEXTS T ON P.TITLEID=T.TEXTID
        LEFT JOIN GDC_CMOD.dbo.TDL_DEMOGRAPHIC dmg ON RIGHT(P.PATNUMBER,16)=dmg.DMG_CPATNUMBER COLLATE Latin1_general_CS_AS
        WHERE R.ACCESSNUMBER=?";
        
        $row = $this->db->query($sql, [$accessnumber])->getRowArray();
        
        $regno = $row['EXTERNALORDERNUMBER'] ?? '';
        $reqdate = $row['REQDATE'] ?? '';
        $pname = $row['NAME'] ?? '';
        $pnum = $row['PATNUM'] ?? '';
        $paddress = $row['DMG_CADDRESS'] ?? '';
        $pphone = $row['TELEPHON'] ?? '';
        $pemail = $row['EMAIL'] ?? '';
        $psex = $row['SEX'] ?? '';
        $pAge = $row['AGE'] ?? '';
        $pAgeM = $row['AGEMONTHS'] ?? '';
        $rcomment = $row['COMMENTTEXT'] ?? '';
        $pcity = $row['DMG_CCITY'] ?? '';
        $pdob = '';
        if (isset($row['BIRTHDATE']) && $row['BIRTHDATE'] != null) {
            $pdob = date('d-m-Y', strtotime($row['BIRTHDATE']));
        }
        $title = $row['SHORTTEXT'] ?? '';
        if ($title != '') {
            $pname = "$pname, $title";
        }
        
        $sql = "SELECT ODR_CRESULT_TO, ODR_CREFERENCENAME, ODR_CREFERENCEDOCNAME FROM GDC_CMOD.dbo.TDL_ORDER WHERE ODR_CNOLAB=?";
        $row2 = $this->db->query($sql, [$regno])->getRowArray();
        
        $sendto = $row2['ODR_CRESULT_TO'] ?? '';
        $loc = $row2['ODR_CREFERENCENAME'] ?? '';
        $doc = $row2['ODR_CREFERENCEDOCNAME'] ?? '';
        
        if ($loc == 'PT. BANGUN GUNUNG SARI (BGS)') {
            $loc = "PT. BANGUN GUNUNG SARI (BGS";
        } elseif ($loc == 'PT. PUTRA DUTA PEMBANGUNAN') {
            $loc = "PT. PUTRA DUTA PEMBANGUNAN";
        } elseif ($loc == 'PT. BENSA ADHI CIPTA') {
            $loc = "-";
        } elseif ($loc == 'PT. LIM SIANG HUAT BALINDO') {
            $loc = "-";
        } elseif ($loc == '') {
            $loc = 'WALK IN';
        }
        if ($doc == '') {
            $doc = $loc;
        }
        
        $data = "<table class='info'>
            <tr style='border-bottom:solid 1px black'><th colspan='5'>CLINICAL LABORATORY</th></tr>
            <tr> <td>Reg#</td> <td>:</td> <td>$regno</td> <td>Date</td> <td><pre>: $reqdate  $sendto</pre></td></tr>
            <tr> <td>Lab#</td> <td>:</td> <td>$accessnumber</td> <td>DoB</td> <td>: $pdob (D-M-Y)</td> </tr>
            <tr> <td>MR</td> <td>:</td> <td>$pnum</td> <td>Age</td> <td>: $pAge years, $pAgeM months</td> </tr>
            <tr> <td>Name</td> <td>:</td> <td colspan='3'>$pname</td> </tr>
            <tr> <td>Address</td> <td>:</td> <td colspan='3'>$paddress</td> </tr>
            <tr> <td>Phone/Email</td> <td>:</td> <td colspan='3'>$pphone / $pemail</td> </tr>
            <tr> <td>City</td> <td>:</td> <td colspan='3'>$pcity</td> </tr>
            <tr> <td>Sex</td> <td>:</td> <td colspan='3'>$psex</td> </tr>
            <tr> <td>Reff</td> <td>:</td> <td colspan='3'>$loc</td></tr>
            <tr> <td>Doctor</td> <td>:</td> <td colspan='3'>$doc</td></tr>
        </table>";
        
        return $data;
    }
    
    private function getResult(string $accessnumber, int $eng): array
    {
        $_chinese = [
            "HBSAG" => "B型肝炎抗原", "GGT" => "丙种谷氨酰转肽酶", "NEUT" => "中性粒细胞",
            "HBSAT" => "乙肝表面抗体", "AHBS" => "乙肝表面抗体", "AHBST" => "乙肝表面抗体效价",
            "LDH" => "乳酸脱氢酶", "LDL" => "<br/>低密度脂蛋白", "PROLA" => "促乳素",
            "TPHCG" => "促绒毛膜性激素测验", "PSA" => "前列腺特异性抗原", "MONO" => "单核细胞",
            "HSV1G" => "单纯疱疹病毒抗体1IgG", "HSV1M" => "单纯疱疹病毒抗体1IgM",
            "HSV2G" => "单纯疱疹病毒抗体2IgG", "HSV2M" => "单纯疱疹病毒抗体2IgM",
            "CRPQN" => "反应蛋白质量", "2SWTH" => "咽喉", "2DIPT" => "咽喉",
            "BASO" => "嗜性粒血球数", "EOS" => "嗜酸性粒血球", "EOSC" => "嗜酸性粒血球",
            "PBF" => "<br/>外周血沈淀率", "UA" => "尿酸", "CMVG" => "巨细胞病毒IgG",
            "CMVM" => "巨细胞病毒IgM", "MCHC" => "平均含血红素浓度", "MCH" => "平均含血红素量",
            "ACAG" => "异常冠状动脉IgG", "ACAM" => "异常冠状动脉IgM", "GDS" => "当时",
            "VDRL" => "性病研究实验试验", "CHOL" => "总胆固醇", "UBIL" => "总胆红素",
            "TP" => "总蛋白质(量)", "EBVEA" => "抗EB病毒定量免疫A", "EBVVA" => "抗EB病毒滴度免疫A",
            "SALMG" => "抗沙门菌IgG", "SALMM" => "抗沙门菌IgM", "DENGG" => "抗登革热IgG",
            "DENGR" => "抗登革热IgG/IgM快速", "DENGM" => "抗登革热IgM", "ICTTB" => "抗结核菌抗体线测试",
            "ASTO" => "抗链球菌", "AMUBA" => "抗阿米巴", "TPHA" => "梅毒螺旋体血凝集测定",
            "PAPS" => "涂片", "LYM" => "淋巴细胞", "1GO" => "淋病", "FPSA" => "游离前列腺特异性抗原",
            "GLOB" => "球蛋白", "TG" => "甘油三脂", "GROW" => "生长荷尔蒙",
            "PTH" => "甲状旁腺激素", "TPO" => "甲状腺过氧化物酶抗体", "AFP" => "甲胎蛋白",
            "CA125" => "癌抗体125", "CA153" => "癌抗体15-3", "CA199" => "癌抗体19-9",
            "CA724" => "癌抗体72-4", "CEA" => "癌胚抗原", "1NEIS" => "白喉（咽）",
            "2DIPN" => "白喉（鼻）", "WBC" => "白细胞", "FWBC" => "白细胞",
            "ULEUX" => "白细胞数目", "ALB" => "白蛋白", "CORPG" => "皮质醇",
            "CORSR" => "皮质醇", "DBIL" => "直接", "TESTO" => "睾酮", "ALP" => "<br/>碱性磷酸",
            "NSE" => "神经原特异性烯醇化酶", "GLUP" => "空腹", "HBA1C" => "空腹与餐后血糖水平",
            "2SPER" => "精虫", "SPERM" => "精虫", "RBC" => "红细胞", "FRBC" => "红细胞",
            "UERY" => "红细胞数目", "LED" => "红细胞沈降率", "MCV" => "红血球平均体积",
            "PCV" => "红血球积压", "PASMS" => "组织学 病理", "CYSMS" => "细胞学",
            "CKMB" => "细胞角蛋白", "CREA" => "肌酸酐,肌酸内酰胺酸", "BTGN" => "肾石化验",
            "BATU" => "胆石化验", "CHE" => "胆碱酯酶", "INSL" => "胰岛素", "CYSTC" => "胱硫醚",
            "APN" => "脂联素", "LIPO" => "脂蛋白", "2PUS" => "脓", "DHEAS" => "脱氢表雄酮硫酸酯",
            "UGLU" => "葡萄糖", "UPROT" => "蛋白", "GOLRH" => "血型", "PLT" => "血小板",
            "BUN" => "血尿素氮", "TBIL" => "血清谷丙转氨酶", "SGPT" => "血清谷丙转氨酶",
            "SGOT" => "血清谷草转氨酶", "HB" => "血红素", "CHLAA" => "衣原体素",
            "CHLAG" => "衣原体素IgG", "CHLAM" => "衣原体素IgM", "HSCRP" => "赵敏反应蛋白",
            "APOA1" => "载脂蛋白", "APOB" => "载脂蛋白", "APOR" => "载脂蛋白比率",
            "SDLDL" => "载脂蛋白比率", "ALDO" => "醛固酮", "DIFF" => "鉴别",
            "ESTRI" => "雌三醇", "FESTR" => "雌三醇", "RUBG" => "风疹IgG",
            "RUBM" => "风疹IgM", "GLU2P" => "餐后两个小时", "HDL" => "高密度脂蛋白"
        ];
        
        $_italic = ["UTRI","ITALIC","PLSFC", "PLSOV", "PLSML", "PLSVI"];
        
        $sql = "SELECT DC.FULLTEXT AS CHAPTER, 
            DT.TESTCODE AS TESTCODE, 
            T.VALIDATIONSTATUS AS VALIDATIONSTATUS,
            RESULT = CASE
                WHEN T.RESTYPE=0 THEN 'Pending'
                WHEN T.RESTYPE=4 AND T.RESVALUE='' AND T.RESSTATUS=1 THEN '.'
                WHEN T.RESTYPE IN (7,15,4) THEN T.RESVALUE
                WHEN T.RESTYPE=9 THEN +'< '+T.RESVALUE
                WHEN T.RESTYPE=10 THEN +'> '+T.RESVALUE
                WHEN T.RESVALUE IS NULL THEN
                    CASE
                        WHEN T.CODEDRESULTID IS NULL AND DT.TESTTYPE IN (4,5) THEN NULL
                        WHEN T.CODEDRESULTID IS NULL THEN TC.COMMENTTEXT
                        WHEN T.CODEDRESULTID IS NOT NULL AND T.RESTYPE=6 AND SUBSTRING(DX.FULLTEXT,1,3) NOT LIKE '%#%' THEN DX.FULLTEXT
                    END
                ELSE T.RESVALUE
            END,
            T.MINIMUM AS MINIMUM, 
            T.MAXIMUM AS MAXIMUM,
            DT.FULLTEXT AS FULLTEXT,
            DT.RESPRECISION AS PRECISION1, 
            DT.RESPRECISION2 AS PRECISION2, 
            DT.OPERAND AS OPERAND, 
            DT.SOFTCONVERSION AS SOFTCONVERSION, 
            DT.UNITS AS U1, 
            DT.UNITS2 AS U2, 
            T.RESTYPE AS RESTYPE, 
            VI.FULLTEXT AS I,
            CASE
                WHEN TC.COMMENTTEXT IS NULL THEN DX2.FULLTEXT
                ELSE TC.COMMENTTEXT
            END AS RESCOM, 
            T.RERUN AS RERUN
        FROM TESTS T
        JOIN DICT_TESTS DT ON DT.TESTID=T.TESTID
        LEFT JOIN DICT_TEXTS DX ON DX.TEXTID=T.CODEDRESULTID
        LEFT JOIN TESTS_COMMENTS TC ON TC.REQTESTID=T.REQTESTID
        LEFT JOIN DICT_TEXTS DX2 ON DX2.TEXTID=TC.COMMENTCODEDID
        LEFT JOIN REQUESTS R ON R.REQUESTID=T.REQUESTID
        LEFT JOIN DICT_CHAPTERS DC ON DC.CHAPID=T.CHAPID
        LEFT JOIN GDC_CMOD.dbo.V_INTER2 VI ON VI.ATR_ACCESSNUMBER=R.ACCESSNUMBER AND DT.TESTCODE=VI.ATR_TESTCODE
        WHERE R.ACCESSNUMBER=? AND T.NOTPRINTABLE IS NULL AND DT.TESTCODE<>'STATS' AND ISNUMERIC(DT.TESTCODE)=0
        ORDER BY T.TESTORDER";
        
        $stmt = $this->db->query($sql, [$accessnumber]);
        $rows = $stmt->getResultArray();
        
        $CHAP = "";
        $i = 0;
        $page = 1;
        $line = 0;
        $lpp = 39;
        $done[1] = "";
        $nline = 0;
        $RERUN = 1;
        
        foreach ($rows as $row) {
            $CHAPTER = $row['CHAPTER'];
            $TESTCODE = $row['TESTCODE'];
            $VALIDATIONSTATUS = $row['VALIDATIONSTATUS'];
            $R1 = $row['RESULT'];
            if ($R1 == '****') {
                $R1 = '-';
            }
            $L1 = $row['MINIMUM'];
            $H1 = $row['MAXIMUM'];
            $FULLTEXT = $row['FULLTEXT'];
            $PRECISION1 = $row['PRECISION1'];
            $PRECISION2 = $row['PRECISION2'];
            $OPERAND = $row['OPERAND'];
            $SOFTCONVERSION = $row['SOFTCONVERSION'];
            $U1 = $row['U1'];
            $U2 = $row['U2'];
            $RESTYPE = $row['RESTYPE'];
            $I = $row['I'];
            $RESCOM = $row['RESCOM'];
            
            if ($eng == 1) {
                $ICHAPTER = substr($CHAPTER, strpos($CHAPTER, '#E') + 2, strrpos($CHAPTER, '#E') - strpos($CHAPTER, '#E') - 2);
                if ($ICHAPTER != $CHAP) {
                    $raw[$i] = "	<tr><td colspan='7'><pre>$ICHAPTER</pre></td> </tr>\r\n";
                    $nline += 1;
                }
                $CHAP = $ICHAPTER;
                $ITEXT = substr($FULLTEXT, strpos($FULLTEXT, '#E') + 2, strrpos($FULLTEXT, '#E') - strpos($FULLTEXT, '#E') - 2);
            } else {
                $ICHAPTER = substr($CHAPTER, 2, strrpos($CHAPTER, '#I') - 2);
                if ($ICHAPTER != $CHAP) {
                    $raw[$i] = "	<tr><td colspan='7'><pre>$ICHAPTER</pre></td> </tr>\r\n";
                    $nline += 1;
                }
                $CHAP = $ICHAPTER;
                $ITEXT = substr($FULLTEXT, 2, strrpos($FULLTEXT, '#I') - 2);
            }
            
            if ($TESTCODE == 'PCRN') {
                $raw[$i] .= "	<tr> <td></td> <td colspan='6'><br/><pre>$ITEXT</pre></td></tr>";
                $done[$page] .= $raw[$i];
            } elseif (!is_numeric($RESTYPE)) {
                if (array_key_exists($TESTCODE, $_chinese)) {
                    $ITEXT = rtrim($ITEXT)." <span class='textC'>".$_chinese[$TESTCODE].'</span>';
                }
                if ($ITEXT != '') {
                    $ITEXT = "	<tr> <td colspan='7'><pre>$ITEXT</pre></td> </tr>\r\n";
                    $nline += 1;
                    $raw[$i] .= $ITEXT;
                }
                
                $RERUN = $row['RERUN'];
            } else {
                if (substr($R1, 0, 2) == '< ' && is_numeric(substr($R1, 2, strlen($R1)))) {
                    $r1 = substr($R1, 2, strlen($R1));
                    $r1 -= 1;
                } elseif (substr($R1, 0, 2) == '> ' && is_numeric(substr($R1, 2, strlen($R1)))) {
                    $r1 = substr($R1, 2, strlen($R1));
                    $r1 += 1;
                } else {
                    $r1 = $R1;
                }
                $F = "";
                if ($TESTCODE != 'TROPI') {
                    if ($r1 < $L1 && is_numeric($r1) && is_numeric($L1)) {
                        $F = "*L";
                    } elseif ($r1 > $H1 && is_numeric($r1) && is_numeric($H1)) {
                        $F = "*H";
                    }
                }
                
                if ($RESTYPE == '9' && $TESTCODE == 'LH') {
                    $qr1 = preg_replace('/<|>| |/', '', $r1);
                    if ($qr1 < $L1 && is_numeric($qr1) && is_numeric($L1)) {
                        $F = "*L";
                    } elseif ($qr1 > $H1 && is_numeric($qr1) && is_numeric($H1)) {
                        $F = "*H";
                    }
                }
                
                if ($RESTYPE == 0) {
                    $R2 = "";
                    $L1 = "";
                    $H1 = "";
                    $L2 = "";
                    $H2 = "";
                } else {
                    if (is_numeric($L1) && $PRECISION1 != 0) {
                        $L1 = number_format($L1, $PRECISION1);
                    } else {
                        $L1 = number_format($L1);
                    }
                    if (is_numeric($H1) && $PRECISION1 != 0) {
                        $H1 = number_format($H1, $PRECISION1);
                    } else {
                        $H1 = number_format($H1);
                    }
                    if (in_array($RESTYPE, [7, 15, 4]) && $OPERAND == 3) {
                        if (is_numeric($R1)) {
                            $R2 = number_format($R1 * $SOFTCONVERSION, $PRECISION2, '.', '');
                        } else {
                            $R2 = '';
                        }
                        if ($L1 != 0) {
                            $L2 = number_format($L1 * $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $L2 = 0;
                        }
                        if (is_numeric($H1) && $H1 != 0) {
                            $H2 = number_format($H1 * $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $H2 = 0;
                        }
                    } elseif (in_array($RESTYPE, [7, 15, 4]) && $OPERAND == 4) {
                        if (is_numeric($R1)) {
                            $R2 = number_format($R1 / $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $R2 = '';
                        }
                        if (is_numeric($L1) && $L1 != 0) {
                            $L2 = number_format($L1 / $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $L2 = 0;
                        }
                        if (is_numeric($H1) && $H1 != 0) {
                            $H2 = number_format($H1 / $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $H2 = 0;
                        }
                    } elseif (in_array($RESTYPE, [9, 10]) & $OPERAND == 3) {
                        $r21 = substr($R1, 0, 2);
                        $r22 = substr($R1, 2, 10);
                        if (strlen($r22) > 5) {
                            $r21 = substr($r21, 0, 1);
                        }
                        $R1 = $r21.$r22;
                        $r22 = number_format($r22 * $SOFTCONVERSION, $PRECISION2, '.', '');
                        $R2 = $r21.$r22;
                        if ($L1 != 0) {
                            $L2 = number_format($L1 * $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $L2 = '';
                        }
                        if ($H1 != 0) {
                            $H2 = number_format($H1 * $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $H2 = '';
                        }
                    } elseif (in_array($RESTYPE, [9, 10]) & $OPERAND == 4) {
                        $r21 = substr($R1, 0, 2);
                        $r22 = substr($R1, 2, 10);
                        $r22 = number_format($r22 / $SOFTCONVERSION, $PRECISION2, '.', '');
                        $R2 = $r21.$r22;
                        if ($L1 != 0) {
                            $L2 = number_format($L1 / $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $L2 = '';
                        }
                        if ($H1 != 0) {
                            $H2 = number_format($H1 / $SOFTCONVERSION, $PRECISION2);
                        } else {
                            $H2 = '';
                        }
                    } else {
                        $R2 = $R1;
                        $L2 = $L1;
                        $H2 = $H1;
                    }
                }
                
                if (($L1 == 0) && ($H1 == 0)) {
                    $L1 = '';
                    $H1 = '';
                    $L2 = '';
                    $H2 = '';
                }
                
                if (is_numeric($R1) && is_numeric($PRECISION1)) {
                    $R1 = number_format($R1, $PRECISION1, '.', ',');
                }
                if (is_numeric($R2) && is_numeric($PRECISION2)) {
                    $R2 = number_format($R2, $PRECISION2, '.', ',');
                }
                
                $TEXT = explode("\r\n", $ITEXT);
                $test = [];
                $res = [];
                foreach ($TEXT as $text_item) {
                    $test[] = substr($text_item, 0, 33);
                    $res[] = substr($text_item, 33, strlen($text_item));
                }
                $space = (strlen($test[0]) - strlen(ltrim($test[0]))) * 7;
                $test = rtrim(implode("\r\n", $test));
                $res = implode("\r\n", $res);
                
                if (in_array($TESTCODE, $_italic)) {
                    $test = "<i>$test</i>";
                }
                if (array_key_exists($TESTCODE, $_chinese)) {
                    $test .= " <span class='textC'>".$_chinese[$TESTCODE].'</span>';
                }
                
                $tline = count(explode(PHP_EOL, $test));
                $rline = count(explode(PHP_EOL, $res));
                $r1line = count(explode(PHP_EOL, $R1));
                if ($rline < $r1line) {
                    $rline = $r1line;
                }
                
                if ($test == ' Note') {
                    $ITEXT = "	<tr> <td style='padding-left:".$space."px'><br/>$test</td> <td colspan='6'><br/><pre>$res            </pre></td> </tr>\r\n";
                } elseif (strlen($RESCOM) < 2) {
                    $ITEXT = "	<tr> <td style='padding-left:".$space."px'>$test</td> <td colspan='6'><pre>$res  </pre></td> </tr>\r\n";
                } else {
                    $rline += count(explode(PHP_EOL, $RESCOM));
                    $res = rtrim($res);
                    $ITEXT = "	<tr> <td style='padding-left:".$space."px'>$test</td> <td colspan='6'><pre>$res        \r\n$RESCOM</pre></td> </tr>\r\n ";
                }
                
                if ($tline > $rline) {
                    $nline += $tline;
                } else {
                    $nline += $rline;
                }
                
                $posR1 = strpos($ITEXT, "{R1");
                $posR12 = strrpos($ITEXT, "{R1");
                $posR2 = strpos($ITEXT, "{R2");
                $posR22 = strrpos($ITEXT, "{R2");
                $posI1 = strpos($ITEXT, "{I");
                $posI2 = strrpos($ITEXT, "{I");
                
                $posL1 = strpos($ITEXT, "{L1");
                $posL12 = strrpos($ITEXT, "{L1");
                $posH1 = strpos($ITEXT, "{H1");
                $posH12 = strrpos($ITEXT, "{H1");
                $posL2 = strpos($ITEXT, "{L2");
                $posL22 = strrpos($ITEXT, "{L2");
                $posH2 = strpos($ITEXT, "{H2");
                $posH22 = strrpos($ITEXT, "{H2");
                $posU1 = strpos($ITEXT, "{U1");
                $posU2 = strpos($ITEXT, "{U2");
                
                $ITEXT = str_replace("{R1", "   ", $ITEXT);
                $ITEXT = str_replace("{R2", "   ", $ITEXT);
                $ITEXT = str_replace("{I", "  ", $ITEXT);
                $ITEXT = str_replace("{L1", "   ", $ITEXT);
                $ITEXT = str_replace("{H1", "   ", $ITEXT);
                $ITEXT = str_replace("{L2", "   ", $ITEXT);
                $ITEXT = str_replace("{H2", "   ", $ITEXT);
                $ITEXT = str_replace("{U1", "   ", $ITEXT);
                $ITEXT = str_replace("{U2", "   ", $ITEXT);
                
                if (in_array($RESTYPE, [4, 6, 7, 9, 10, 15])) {
                    if ($R1 == 'Negatif') {
                        $R2 = 'Negative';
                    }
                    if ($R1 == 'Positif') {
                        $R2 = 'Positive';
                    }
                    $ITEXT = $this->f_repl($ITEXT, $R1.' '.$F, $posR1);
                    if ($posR1 != $posR12) {
                        $ITEXT = $this->f_repl($ITEXT, $R1.' '.$F, $posR12);
                    }
                    $ITEXT = $this->f_repl($ITEXT, $L1 ?? '', $posL1);
                    if ($posL1 != $posL12) {
                        $ITEXT = $this->f_repl($ITEXT, $L1 ?? '', $posL12);
                    }
                    $ITEXT = $this->f_repl($ITEXT, $H1 ?? '', $posH1);
                    if ($posH1 != $posH12) {
                        $ITEXT = $this->f_repl($ITEXT, $H1 ?? '', $posH12);
                    }
                    if (isset($R2)) {
                        $ITEXT = $this->f_repl($ITEXT, $R2.' '.$F, $posR2);
                        if ($posR2 != $posR22) {
                            $ITEXT = $this->f_repl($ITEXT, $R2.' '.$F, $posR22);
                        }
                    }
                    if (isset($L2)) {
                        $ITEXT = $this->f_repl($ITEXT, $L2 ?? '', $posL2);
                    }
                    if ($posL2 != $posL22) {
                        $ITEXT = $this->f_repl($ITEXT, $L2 ?? '', $posL22);
                    }
                    if (isset($H2)) {
                        $ITEXT = $this->f_repl($ITEXT, $H2 ?? '', $posH2);
                    }
                    if ($posH2 != $posH22) {
                        $ITEXT = $this->f_repl($ITEXT, $H2 ?? '', $posH22);
                    }
                    if ($I == 'Negative' || $I == 'Negatif') {
                        $I1 = "Negatif";
                        $I2 = "Negative";
                        $ITEXT = $this->f_repl($ITEXT, $I1, $posI1);
                        $ITEXT = $this->f_repl($ITEXT, $I2, $posI2);
                    } else {
                        $ITEXT = $this->f_repl($ITEXT, $I ?? '', $posI1);
                        $ITEXT = $this->f_repl($ITEXT, $I ?? '', $posI2);
                    }
                    $ITEXT = $this->f_repl($ITEXT, $U1 ?? '', $posU1);
                    $ITEXT = $this->f_repl($ITEXT, $U2 ?? '', $posU2);
                } elseif (in_array($RESTYPE, [2, 0, 5])) {
                    if (strlen($RESCOM) < 2) {
                        if ($TESTCODE == 'BUCRR') {
                            $ITEXT = $this->f_repl($ITEXT, $R1 ?? '', $posR1);
                            $ITEXT = $this->f_repl($ITEXT, $R1 ?? '', $posR2);
                        } else {
                            $ITEXT = substr($ITEXT, 0, $posR1);
                            $ITEXT .= $R1."</pre></td> </tr>";
                        }
                    } else {
                        $ITEXT = substr($ITEXT, 0, $posR1);
                        $ITEXT .= "$R1 \r\n$RESCOM</pre></td> </tr>";
                    }
                }
                
                $raw[$i] .= $ITEXT;
                $line += $nline;
                
                if ($TESTCODE != 'COVGG') {
                    if ($line > $lpp) {
                        $page++;
                        $done[$page] = "";
                        $line = $nline;
                    }
                } else {
                    if ($line > $lpp - 14) {
                        $page++;
                        $done[$page] = "";
                        $line = $nline;
                    }
                }
                
                if ($line > $lpp) {
                    $page++;
                    $done[$page] = "";
                    $line = $nline;
                }
                $done[$page] .= $raw[$i];
                $i++;
                $raw[$i] = "";
                $nline = 0;
            }
        }
        
        return $done;
    }
    
    private function f_repl(string $text, string $ntext, int $pos): string
    {
        if ($pos != 0) {
            $len = strlen($ntext);
            if (substr($text, $pos, 1) == ' ') {
                $text = substr_replace($text, $ntext, $pos, $len);
            }
        }
        return $text;
    }
    
    private function getNotes(string $accessnumber): string
    {
        $sql = "SELECT RO.COMMENTTEXT FROM REQUESTS R
            LEFT JOIN REQUESTS_OCOM RO ON RO.REQUESTID=R.REQUESTID
            WHERE R.ACCESSNUMBER=?";
        $row = $this->db->query($sql, [$accessnumber])->getRowArray();
        return $row['COMMENTTEXT'] ?? '';
    }
    
    private function getOthers(string $accessnumber, int $eng): string
    {
        $sql = "SELECT DT.FULLTEXT AS FULLTEXT FROM TESTS T
            LEFT JOIN REQUESTS R ON R.REQUESTID=T.REQUESTID
            LEFT JOIN DICT_TESTS DT ON DT.TESTID=T.TESTID
            WHERE R.ACCESSNUMBER=? AND ISNUMERIC(DT.TESTCODE)=1
            ORDER BY T.TESTORDER";
        $stmt = $this->db->query($sql, [$accessnumber]);
        $rows = $stmt->getResultArray();
        
        $i = 1;
        $raw = "";
        foreach ($rows as $row) {
            $text = $row['FULLTEXT'];
            if ($eng == 1) {
                $text = substr($text, strpos($text, '#E') + 2, strrpos($text, '#E') - strpos($text, '#E') - 2);
            } else {
                $text = substr($text, strpos($text, '#I') + 2, strrpos($text, '#I') - strpos($text, '#I') - 2);
            }
            $text = str_replace("{R1", "   ", $text);
            $text = str_replace("{R2", "   ", $text);
            $text = str_replace("{I", "  ", $text);
            $text = str_replace("{L1", "   ", $text);
            $text = str_replace("{H1", "   ", $text);
            $text = str_replace("{L2", "   ", $text);
            $text = str_replace("{H2", "   ", $text);
            $text = str_replace("{U1", "   ", $text);
            $text = str_replace("{U2", "   ", $text);
            $text = trim($text);
            $raw .= "$i. $text <br/>\r\n";
            $i++;
        }
        return $raw;
    }
    
    private function getCollData(string $accessnumber): string
    {
        $collData = "";
        $sql = "SELECT DISTINCT FORMAT(COLLECTIONDATE,'dd-MM-yyyy') AS COLLDATE, FORMAT(COLLECTIONDATE,'HH:mm') AS COLLTIME, STUFF(
            (SELECT ', ' + dst.SHORTTEXT FROM GDC_CMOD.dbo.TUBES t1
            LEFT JOIN glendb.dbo.DICT_SAMPLES_TYPES dst ON t1.TUBENUMBER=dst.SAMPCODE
            WHERE t1.ACCESSNUMBER=t.ACCESSNUMBER
            AND FORMAT(t1.COLLECTIONDATE,'dd-MM-yyyy HH:mm')=FORMAT(t.COLLECTIONDATE,'dd-MM-yyyy HH:mm')
            FOR XML PATH('')),
            1,1, '') AS SAMPLES
        FROM GDC_CMOD.dbo.TUBES t WHERE t.ACCESSNUMBER=? AND STATUS=1";
        $stmt = $this->db->query($sql, [$accessnumber]);
        $rows = $stmt->getResultArray();
        
        $date1 = '';
        foreach ($rows as $row) {
            if ($date1 == $row['COLLDATE']) {
                $collData .= $row['COLLTIME'].$row['SAMPLES'].'. ';
            } else {
                $collData .= $row['COLLDATE'].' '.$row['COLLTIME'].$row['SAMPLES'].'. ';
            }
            $date1 = $row['COLLDATE'];
        }
        return $collData;
    }
    
    private function getRecvData(string $accessnumber): string
    {
        $recvData = "";
        $sql = "SELECT ds.SHORTTEXT AS SHORTTEXT, FORMAT(st.COLLECTIONDATE,'dd-MM-yyyy') AS RECVDATE, FORMAT(st.COLLECTIONDATE,'HH:mm') AS RECVTIME FROM SP_TUBES st
            LEFT JOIN DICT_SAMPLES_TYPES ds ON ds.SAMPCODE=st.SAMPLETYPE
            WHERE st.SP_ACCESSNUMBER=? AND st.TUBESTATUS=4";
        $stmt = $this->db->query($sql, [$accessnumber]);
        $rows = $stmt->getResultArray();
        
        $date1 = '';
        $time1 = '';
        foreach ($rows as $row) {
            $x = $row['SHORTTEXT'];
            $date = $row['RECVDATE'];
            $time = $row['RECVTIME'];
            if ($date1 == $date) {
                if ($time1 == $time) {
                    $recvData .= $x.'. ';
                } else {
                    $recvData .= $time.' '.$x.'. ';
                }
            } else {
                $recvData .= $date.' '.$time.' '.$x.'. ';
            }
            $date1 = $date;
            $time1 = $time;
        }
        return $recvData;
    }
    
    private function getNoSample(string $accessnumber): string
    {
        $sql = "SELECT DST.SHORTTEXT AS SHORTTEXT FROM SP_TUBES ST
            LEFT JOIN DICT_SAMPLES_TYPES DST ON DST.SAMPCODE=ST.TUBETYPE
            WHERE ST.SP_ACCESSNUMBER=? AND ST.TUBESTATUS<>4";
        $stmt = $this->db->query($sql, [$accessnumber]);
        $rows = $stmt->getResultArray();
        
        $noSample = '';
        foreach ($rows as $row) {
            $sample = $row['SHORTTEXT'];
            $noSample .= "<tr> <td>$sample</td> <td colspan='6'>No Sample</td> </tr>\r";
        }
        return $noSample;
    }
    
    private function getStatus(string $accessnumber): string
    {
        $sql = "SELECT STATS FROM GDC_CMOD.dbo.V_DASHBOARD WHERE SP_ACCESSNUMBER=?";
        $row = $this->db->query($sql, [$accessnumber])->getRowArray();
        
        if (isset($row['STATS'])) {
            $status = $row['STATS'];
            if ($status == 'Comp') {
                $status = 'FINAL';
            } else {
                $status = 'PENDING';
            }
        } else {
            $status = '';
        }
        return $status;
    }
    
    private function getValBy(string $accessnumber): string
    {
        $sql = "SELECT TOP 1 a.INITUSER, MAX(STEPDATE) as STEPDATE
            FROM glendb.dbo.AUDIT_TRAIL a WHERE (a.LIS_SESSION='VAL' OR (a.LIS_SESSION='ERM' AND a.VALIDATION=5))
            AND a.ATR_ACCESSNUMBER=?
            GROUP BY a.INITUSER, a.STEPDATE
            ORDER BY a.STEPDATE DESC";
        $row = $this->db->query($sql, [$accessnumber])->getRowArray();
        
        $valBy = $row['INITUSER'] ?? '';
        if ($valBy == '' || $valBy == 'LIS') {
            $valBy = "AHT";
        }
        return $valBy;
    }

	private function getValData(string $accessnumber): array {
		$sql = "SELECT TOP 1 * FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
		$row = $this->db->query($sql, [$accessnumber])->getRowArray();
		return $row ?? [];
	}

	private function getCollectionDateRaw(string $accessnumber): string {
		$sql = "SELECT FORMAT(SR.COLLECTIONDATE,'yyyy-MM-dd') AS COLLDATE 
				FROM REQUESTS R
				LEFT JOIN SP_REQUESTS SR ON SR.SP_ACCESSNUMBER=R.ACCESSNUMBER
				WHERE R.ACCESSNUMBER=?";
		$row = $this->db->query($sql, [$accessnumber])->getRowArray();
		return $row['COLLDATE'] ?? '';
	}
}
