<?php

namespace Application\Service\DB\Project;

use Application\Common\StatusCode;
use Application\Service\DB\Db;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Interop\Container\ContainerInterface;
use Laminas\Validator\Exception\InvalidArgumentException;
use Application\Service\Extension\Xml\XmlBuilder;
use Application\Service\Extension\Xml\LaboratoryXmlGenerator;
use Application\Common\Ocr;
use Application\Service\Extension\Uploader\adapter\Oss;
use Application\Service\Extension\Uploader\ImageUploader;
use Laminas\Db\Sql\Expression;
use PHP_CodeSniffer\Tokenizers\PHP;

class Identificationexport extends \Application\Service\DB\AbstractDb {
    private $item_name; //项目编号

    private $item_number; //项目编号
    private $signatoryName; //中心名称
    private $item_researchstage; //项目阶段名称
    private $patientDatas;  //受试者信息
    private $itemchecktime_arr;  //项目对应的检查点信息
    private $itemstage_arr;  //项目阶段对应的检查点id信息
    private $itemform_arr;  //项目对应的表单信息
    private $UserNameData;  //人员信息
    private $pic_data;  //化验单信息
    private $patient_checktime_form_data;  //受试者对应的检查点表单数据
    private $item_sae_data;  //AE数组

    //受试者对应的AE信息
    private $patient_case; //受试者和AE信息关联信息
    private $create_time; //申请时间

    public function __construct($dbAdapter, ContainerInterface $container) {
        $this->redisObj = Laminas::$serviceManager->redisExtend->setDatabase(13)->getRedisInstance();
        $this->tableName = 'yikeen_item_identificationexport';
        parent::__construct($dbAdapter, $container);
    }

    /**
     * Notes: 导出
     * @param
     * @return
     * @author haojinhua
     * @date 2024-05-28
     */
    public function execute($data)
    {
        $item_id           = $data['item_id'];
        $itemsig_id        = $data['itemsig_id'];
        $patient_ids       = $data['patient_ids'];
        $this->create_time = $data['create_time'];
        //项目名称 中心名称 受试者 阶段-检查点 表单
        $this->item_name = $this->LocalService()->itemInfo->getOneFieldVal('name',[
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称
        //查询中心信息
        $sig_data = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id);
        $sig_name = isset($sig_data[0]['number']) && !empty($sig_data[0]['number']) ? '【'.$sig_data[0]['number'].'】'.$sig_data[0]['info_name'] : $sig_data[0]['info_name'];
        $this->signatoryName = $sig_name;
        //查询当前项目阶段 阶段表【yikeen_item_researchstage】
        $this->item_researchstage =  $this->LocalService()->itemResearchstage->fetchCol('stage_name',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);
        //查询当前项目检查点 检查点表【yikeen_item_checktime】 检查点是副项目下设置的
        $this->itemchecktime_arr = $this->LocalService()->itemChecktime->fetchCol('check_name',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);
        //获取检查点对应的阶段ID
        $this->itemstage_arr = $this->LocalService()->itemChecktime->fetchCol('stage_id',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        //查询受试者信息数组
        $this->patientDatas = $this->LocalService()->patient->fetchDataByKey('is_del = 0',['id','patient_name','patient_number'],['id'],['id'=>0]);
        //表单信息数组
        $this->itemform_arr = $this->LocalService()->itemForm->fetchCol('name',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);
        //人员信息
        $this->UserNameData = $this->LocalService()->adminUser->fetchCol('realname','is_del = 0');

            $change_where = [
                'is_del' => 0,
                'item_id' => $item_id,
                'itemsig_id' => $itemsig_id,
                'lock_state' => 1,
            ];
            if (empty($patient_ids)) {
                //默认查询中心下的所有受试者
                $patient_id_arr = $this->LocalService()->patient->fetchCol('id', 'itemsig_id =' . $itemsig_id);
                $patient_ids = !empty($patient_id_arr) ? implode(',',$patient_id_arr): 0;
            }

            if (!empty($patient_ids)) {
                $change_where['patient_id'] = StringHelper::toArray($patient_ids);
            }

            //根据项目ID 查询category_id
            $itemCate_arr = $this->LocalService()->itemCheckname->getFiledRelation('is_del = 0','item_id','category_id',['item_id','category_id'],2);
            $itemcatArr = isset($itemCate_arr[$item_id])&& !empty($itemCate_arr[$item_id]) ? $itemCate_arr[$item_id] : '';
            if(!empty($itemcatArr)){
                $itemcatArr = array_unique($itemcatArr);
                $change_where['category_id'] = StringHelper::toArray($itemcatArr);
            }

            $ae_where = [
                'is_del' => 0,
                'lock_state' => 1,
                'is_ae_sure' => 1,
                'item_id' => $item_id,
            ];
            if (!empty($patient_ids)) {
                $ae_where['patient_id'] = StringHelper::toArray($patient_ids);
            }

            $this->item_sae_data = [];
            $ae_cond = [
                'where'=>$ae_where,
                'columns'=>['id','item_name','result','reference_range_max','reference_range_min','unit','ae_type','is_normal_type','item_id','patient_id'],
                'order'=>['item_id','patient_id']
            ];
             //查询AE信息   $this->item_sae_data
            $item_sae_data = $this->LocalService()->itemCsae->fetchAll($ae_cond);
            if(!empty($item_sae_data)){
                foreach ($item_sae_data as $item_sae){
                    $this->item_sae_data[$item_sae['item_id']][$item_sae['patient_id']][] = $item_sae;
                }
            }

            $relation_data = $this->LocalService()->itemIdentificationresultchange->getRelationArr($change_where);

            $this->pic_data                    = $relation_data['pic_data'];
            $this->patient_checktime_form_data =  $relation_data['patient_checktime_form_data'];

            $where2CahangeArr        = [
                'where'   => $change_where,
                'columns' => ['id', 'item_id', 'itemsig_id', 'patient_id', 'is_normal_type', 'annex_path', 'form_id','patient_form_id', 'checktime_id','is_normal_type','category_id','patient_form_id','create_user_id','create_time'],
                'order'   => ['patient_id', 'checktime_id', 'form_id'],
                'group'   => ['patient_id', 'checktime_id', 'form_id'],
            ];
            $identification_allresults = $this->LocalService()->itemIdentificationresultchange->fetchAll($where2CahangeArr);

            //导出pdf
            $this->pdf($identification_allresults);
        }


        /**
         * Notes:生成pdf
         * @param
         * @return
         * @author haojinhua
         * @date 2024-05-29
         */
        public function pdf($new_datas){
            foreach ($new_datas as $new_data){
                $patient_id                = $new_data['patient_id'];
                $checktime_id              = $new_data['checktime_id'];
                $form_id                   = $new_data['form_id'];
                $patientName               = isset($this->patientDatas['id'][$patient_id]) && !empty($this->patientDatas['id'][$patient_id]) ? '【' . $this->patientDatas['id'][$patient_id]['patient_number'] . '】' . $this->patientDatas['id'][$patient_id]['patient_name'] : "";
                $itemcheckName             = isset($this->itemchecktime_arr[$checktime_id]) && !empty($this->itemchecktime_arr[$checktime_id]) ? $this->itemchecktime_arr[$checktime_id] : '';
                $itemformName              = isset($this->itemform_arr[$form_id]) && !empty($this->itemform_arr[$form_id]) ? $this->itemform_arr[$form_id] : '';
                $new_data['patientName']   = $patientName;
                $new_data['itemcheckName'] = $itemcheckName;
                $new_data['itemformName']  = $itemformName;

                //根据检查点ID 获取对应阶段ID
                $checktime_id               = $new_data['checktime_id'];
                $itemstage_id               = isset($this->itemstage_arr[$checktime_id]) && !empty($this->itemstage_arr[$checktime_id]) ? $this->itemstage_arr[$checktime_id] : 0;
                $itemstage_name             = isset($this->item_researchstage[$itemstage_id]) && !empty($this->item_researchstage[$itemstage_id]) ? $this->item_researchstage[$itemstage_id] : 0;

                $new_data['itemstage_name'] = $itemstage_name;
                $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, 'A4', true, 'UTF-8', false);
                // 设置文档信息
                $pdf->SetCreator("创建者");
                $pdf->SetAuthor('作者');
                $pdf->SetTitle('标题');
                $pdf->SetSubject('项目名');
                $pdf->SetKeywords('关键字');
                //关闭头输出
                $pdf->setPrintHeader(false);
                //关闭尾输出
                $pdf->setPrintFooter(false);
                // 设置默认单间距字体
                $pdf->SetDefaultMonospacedFont('courier');
                // 设置自动分页符
                $pdf->SetAutoPageBreak(TRUE, 5);
                // 设置图像比例因子
                $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
                // 设置首页字体
                $pdf->SetFont('stsongstdlight', '', 12);
                //首页内容
                $pdf->AddPage();
                $pdf->Bookmark('封面页', 0, 0, '', 'B');
                //设置行高
                $pdf->Ln(1.07);
                //设置边距
                $pdf->setCellPaddings(5, 2.44, 5, 0);
                // 设置页边距更小
                $pdf->SetMargins(10, 5, 10);


                //页眉内容
                $html_upper_table = $this->topcontent($new_data);

                $pdf->writeHTMLCell(0, 0, '', '', $html_upper_table, 0, 1, 0, true, '', true);

                //计算中间图片区域的可用高度
                $page_height = $pdf->getPageHeight();
                $bottom_margin = $pdf->getMargins()['bottom'];
                $available_height = $page_height - $pdf->getY() - $bottom_margin;

                //中间识别图片部分
                $key = $new_data['item_id'] . '_' . $new_data['itemsig_id'] . '_' . $new_data['patient_id'] . '_' . $new_data['checktime_id'] . '_' . $new_data['patient_form_id'];

                //获取化验单路径
                $picpathDatas = isset($this->pic_data[$key]) && !empty($this->pic_data[$key]) ? $this->pic_data[$key] : [];
                $i = 0;
                foreach ($picpathDatas as $picpath) {
                   /* // 提取 query 字符串部分
                    $query_string = parse_url($picpath, PHP_URL_QUERY);
                    parse_str($query_string, $query_params);
                    $pic_path = $query_params['path'];*/
                    if($picpath <> '/upload/2022-08-03/5562ea08df706f1_1659504863.webp'){ //手写图片除外
                        $i++;
                        $down_path = APP_PATH . '/data/downloadimg/';
                        // 检查目录是否存在，如果不存在则创建
                        if (!file_exists($down_path)) {
                            mkdir($down_path, 0777, true); // 创建目录，设置权限为0777
                        }
                        $patient_name = $this->patientDatas['id'][$patient_id]['patient_number'];
                        $imgdownpath =  $patient_name.'-'.$itemcheckName.'-'.$itemformName.$i;
                        $FileUploader = $this->LocalService()->imageUploader;
                        $FileUploader->downOssFile($picpath,APP_PATH . '/data/downloadimg/'.$imgdownpath.'.png');//把oss的图片下载到本地服务器
                        $sign_filepath =  $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'] . '/data/downloadimg/' .$imgdownpath.'.png';

                        chmod($sign_filepath, 0777);

                        $image_height = 80; // 设置图片高度为 80
                        $image_top_margin = 20; // 设置图片与上方表格的上边距为 20
                        if ($pdf->getY() + $image_height + $image_top_margin > $available_height) {
                            $pdf->AddPage();
                            $available_height = $page_height - $bottom_margin;
                        }
                        $pdf->Image($sign_filepath, '50', $pdf->getY() + $image_top_margin, 0, $image_height, '', '', 'T', false, 300, '', false, false, 0, false, false, false);

                        $pdf->Ln();

                        // 检查是否需要添加最后一页
                        if ($pdf->getY() + $image_height + $image_top_margin > $available_height) {
                            $pdf->AddPage();
                        }

                    }
                }

                //计算下部表格的可用高度:
                $remaining_height = $page_height - $pdf->getY() - $bottom_margin;
                $html_lower_table_height = $remaining_height;

                //如果下部表格高度超出可用高度,则添加新页面
                if ($remaining_height < $html_lower_table_height) {
                    $pdf->AddPage();
                    $remaining_height = $page_height - $bottom_margin;
                }

                //CS、NCS 内容
                $html_lower_table = $this->cscontent($new_data);
                if(!empty($html_lower_table)) {
                    $pdf->writeHTMLCell(0, $remaining_height - 20, '', $pdf->getY() + 20, $html_lower_table, 0, 1, 0, true, '', true);
                }
                //AE数据
                $html_ae_table = $this->aecontent($new_data);
                if(!empty($html_ae_table)){
                    $pdf->writeHTMLCell(0, $remaining_height - 20, '', $pdf->getY() + 20, $html_ae_table, 0, 1, 0, true, '', true);
                }

                //保存PDF到本地
                $fileName = $new_data['patientName'].'-'.$itemstage_name.'-'.$new_data['itemcheckName'].$new_data['itemformName'].'.pdf';
                $path = APP_PATH . '/data/exportFile/pdf/';

                // 检查目录是否存在，如果不存在则创建
                if (!file_exists($path)) {
                    mkdir($path, 0777, true); // 创建目录，设置权限为0777
                }

                $pdf->Output($path.$fileName, 'F');
                $pdfFilePath = $path.$fileName;
                chmod($pdfFilePath, 0777);
            }

            //删除下载图片文件夹
             $down_pic_path  =  APP_PATH . '/data/downloadimg/';
             $this->DelDirHandle($down_pic_path);

             $zip_path = APP_PATH.'/data/exportFile/zip/';
            // 检查目录是否存在，如果不存在则创建
            if (!file_exists($zip_path)) {
                mkdir($zip_path, 0777, true); // 创建目录，设置权限为0777
            }

            //开始压缩文件
            $apply_title =  $this->item_name.'-'.$this->signatoryName.'-'.$this->create_time;
            $zip_filename = $apply_title.'.zip';
            $this->create_zip($path,$zip_filename,$zip_path);

            //删除pdf文件夹
            $down_pdf_path  =  APP_PATH . '/data/exportFile/pdf/';
            $this->DelDirHandle($down_pdf_path);

            return true;
        }


        /**
         * Notes:头部信息
         * @param
         * @return
         * @author haojinhua
         * @date 2024-05-29
         */
        public function topcontent($new_data){
            $create_user   = $new_data['create_user_id'];
            $create_time   = $new_data['create_time'];
            $UserName      = isset($this->UserNameData[$create_user]) && !empty($this->UserNameData[$create_user]) ? $this->UserNameData[$create_user] : '';
            $user_date     = date('Y-m-d H:i:s',$create_time);
            $html = '<table width="100%"  border="1" align="center" cellspacing="0" style="text-align:center;" class="table1">';
            $html .='
                <tr>
                    <td>项目</td>
                    <td>中心</td>
                    <td>受试者</td>
                    <td>阶段-检查点</td>
                    <td>表单</td>       
                    <td>操作人/时间</td>
                </tr>';
            $html .='
                <tr>
                    <td>'.$this->item_name.'</td>
                    <td>'.$this->signatoryName.'</td>
                    <td>'.$new_data['patientName'].'</td>
                    <td>'.$new_data['itemstage_name'].'-'.$new_data['itemcheckName'].'</td>
                    <td>'.$new_data['itemformName'].'</td>       
                    <td>'.$UserName.'/'.$user_date.'</td>
                </tr>';

            $html.='</table>';
            return $html;
        }


        /**
         * Notes: 中间cs 和 ncs 部分内容
         * @param
         * @return
         * @author haojinhua
         * @date 2024-05-29
         */
        public function cscontent($new_data){
            $key = $new_data['item_id'] . '_' . $new_data['itemsig_id'] . '_' . $new_data['patient_id'] . '_' . $new_data['checktime_id'] . '_' . $new_data['form_id'];
            $patient_checktime_formDatas = isset($this->patient_checktime_form_data[$key]) && !empty($this->patient_checktime_form_data[$key]) ? $this->patient_checktime_form_data[$key] : [];

            if(!empty($patient_checktime_formDatas)){
                $html = '<table width="100%"  border="1" align="center" cellspacing="0" style="text-align:center;" class="table1">';
                $html .='<tr>
                                <td>指标名称</td>
                                <td>单位</td>
                                <td>结果</td>
                                <td>最小值</td>
                                <td>最大值/正常值</td>  
                                <td>下限</td>
                                <td>上限</td>         
                                <td>cs/ncs</td>
                            </tr>';
                foreach ($patient_checktime_formDatas as $patient_checktime_form){
                    if(!in_array($patient_checktime_form['is_normal_type'],[2,3])){
                        continue;
                    }
                    $is_normal_type = $patient_checktime_form['is_normal_type'] == 2 ? 'CS' : 'NCS';
                    $html.='
                        <tr>
                            <td>'.$patient_checktime_form['item_name'].'</td>
                            <td>'.$patient_checktime_form['item_unit'].'</td>
                            <td>'.$patient_checktime_form['result'].'</td>
                            <td>'.$patient_checktime_form['item_min_val'].'</td>
                            <td>'.$patient_checktime_form['item_max_val'].'</td>                
                            <td>'.$patient_checktime_form['min_range'].'</td>                
                            <td>'.$patient_checktime_form['max_range'].'</td>                
                            <td>'.$is_normal_type.'</td>
                        </tr>
                    ';
                }

                $html.='</table>';
                return $html;
            }
        }


        /**
         * Notes:AE部分的数据
         * @param
         * @return
         * @author haojinhua
         * @date 2024-05-30
         */
        public function aecontent($new_data){
             $patient_id = $new_data['patient_id'];
             $item_id = $new_data['item_id'];
             $patientae_arr = isset($this->item_sae_data[$item_id][$patient_id]) && !empty($this->item_sae_data[$item_id][$patient_id]) ? $this->item_sae_data[$item_id][$patient_id] : [];
            if(!empty($patientae_arr)){
                $html = '<table width="100%"  border="1" align="center" cellspacing="0" style="text-align:center;" class="table1">';
                $html .='<tr>
                                <td>指标</td>
                                <td>测定值</td>
                                <td>取值范围</td>
                                <td>单位</td>
                                <td>临床意义</td>  
                                <td>AE判断</td>                        
                            </tr>';
                $aeTypeArr = ['0'=>'未选择','1'=>'非AE与研究疾病有关','2'=>'非AE与病史有关','3'=>'非AE与合并用药有关','4'=>'非AE其他原因','5'=>'属于已有AE','6'=>'属于新增AE'];
                foreach ($patientae_arr as $aeinfo){
                        if(!empty($aeinfo)){
                            $reference_range = $aeinfo['reference_range_min'].'~'.$aeinfo['reference_range_max'];
                            $is_normal_type  = $aeinfo['is_normal_type'];
                            switch ($is_normal_type){
                                case  0;
                                    $is_normal = '';
                                    break;
                                case  1;
                                    $is_normal = '正常';
                                    break;
                                case  2;
                                    $is_normal = 'CS';
                                    break;
                                case  3;
                                    $is_normal = 'NCS';
                                    break;
                            }
                            $aetype  = $aeTypeArr[$aeinfo['ae_type']];
                            $html.='
                            <tr>
                                <td>'.$aeinfo['item_name'].'</td>
                                <td>'.$aeinfo['result'].'</td>
                                <td>'.$aeinfo['result'].'</td>
                                <td>'.$reference_range.'</td>
                                <td>'.$aeinfo['unit'].'</td>                
                                <td>'.$is_normal.'</td>                                      
                                <td>'.$aetype.'</td>                                      
                            </tr>
                    ';
                        }
                }

                $html.='</table>';
                return $html;
            }
        }




    /**
     * Notes:要压缩的文件夹路径/要生成的压缩包名称
     * @param
     * @return
     * @author haojinhua
     * @date 2024-05-30
     */
    public function create_zip($path,$filename,$zip_path)
    {
        $zip = new \ZipArchive();
        if($zip->open($filename, \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
            $this->addFileToZip($zip,$path);
            //关闭处理的zip文件
            if ($zip->close() !== TRUE) {
                echo "无法关闭压缩包";die;
            }
            $zipname = $filename;
            // 4. 将生成的压缩包移动到指定的文件夹中
            if (!rename($zipname, $zip_path . $zipname)) {
                echo "无法移动文件";die;
            }
        }
    }

    /***
     * Notes:递归写入压缩包
     * @param
     * @return
     * @author
     * @date 2024-05-30
     */
    public function addFileToZip($zip, $path) {
        $files = scandir($path);
        foreach ($files as $filename) {
            // 忽略当前目录和上一级目录
            if ($filename == '.' || $filename == '..') {
                continue;
            }
            $fullPath = $path . $filename;
            if (is_dir($fullPath)) {
                $this->addFileToZip($zip, $fullPath);
            } else {
                // 使用文件名本身作为相对路径
                $relativePath = $filename;
                chmod($fullPath, 0777);
                // 将文件添加到压缩包中
                $zip->addFile($fullPath, $relativePath);
            }
        }
    }


    /**
     * Notes:删除文件夹
     * @param
     * @return
     * @author haojinhua
     * @date 2024-05-30
     */
    public function  DelDirHandle($path)
    {
        //如果是目录则继续
        if(is_dir($path)){
            //扫描一个文件夹内的所有文件夹和文件并返回数组
            $p = scandir($path);
            foreach($p as $val){
                //排除目录中的.和..
                if($val !="." && $val !=".."){
                    //如果是目录则递归子目录，继续操作
                    if(is_dir($path.'/'.$val)){
                        //子目录中操作删除文件夹和文件
                        $this->DelDirHandle($path.'/'.$val.'/');
                        //目录清空后删除空文件夹
                        @rmdir($path.'/'.$val.'/');
                    }else{
                        //如果是文件直接删除
                        unlink($path.'/'.$val);
                    }
                }
            }
            rmdir($path);
        }
        return true;
    }


    }

