<?php
/**
 *
 * @author：llbjj
 * @DateTime：2022/5/6 10:57
 * @Description：
 *
 */

namespace Application\Service\DB\Item;

use Application\Service\Extension\Helper\StringHelper;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Predicate\Operator;


class Downpicture extends \Application\Service\DB\AbstractDb
{
    public function __construct($dbAdapter, ContainerInterface $container)
    {
        $this->tableName = 'yikeen_item_downpicture';
        parent::__construct($dbAdapter, $container);
    }

    public $batchNumber = 300;

     //没有数据返回值
    const NO_DATA = '67001';
    /**
     * Notes : 处理数据
     * @param $item_id
     * @param $itemsig_id
     * @param $patient_id
     * @return bool
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:13
     */
    public function HandleData($data)
    {
        $itemsig_id = $data['itemsig_id'];
        $item_id = $data['item_id'];
        $patient_id = $data['patient_id'];
        $hashvalue = $data['hashvalue'];
        $start_time = $data['start_time'];
        $end_time = $data['end_time'];
        $checktime_ids = $data['checktime_ids'];
        $form_id = $data['form_id'];
        $f_id = $data['id'];
        //项目名称
        $iteninfoWhere['where'] = [
            'id' => $item_id,
            'is_del' => 0,
        ];
        $iteninfoWhere['columns'] = ['name','number','fid'];
        $iteminfo = $this->LocalService()->itemInfo->fetchOne($iteninfoWhere);

        $signDatas = $this->LocalService()->itemSignatory->fetchCol('number',[
            'is_del' => 0,
            'item_id' => $iteminfo['fid']
        ]);

        $signId = $this->LocalService()->itemSignatory->fetchCol('signatory_id',[
            'is_del' => 0,
            'item_id' => $iteminfo['fid'],
        ]);

        $signName = [];
        foreach($signId as $k=>$v){
            $info_name = $this->LocalService()->signatoryInfo->fetchOne([
                'where'=> [
                    'id' => $v,
                    'is_del' => 0,
                ],
                'columns'=>['info_name']
            ]);
            $signName[$k] = $info_name['info_name'];
        }
        //查询当前项目表单
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $whereArr['columns'] = ['id', 'name', 'type', 'code','rdg_type','group_id'];
        $data = $this->LocalService()->itemForm->fetchAll($whereArr);
        $formdata = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $formdata[$v['id']] = $v;
            }
        }
        //筛选图片
        $fileWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($itemsig_id)) $fileWhere['where']['itemsig_id'] = $itemsig_id;
        if(!empty($patient_id)) $fileWhere['where']['patient_id'] = $patient_id;
        if(!empty($start_time)) $fileWhere['where'][] = new Operator('create_time', Operator::OP_GT, $start_time);
        if(!empty($end_time)) $fileWhere['where'][] = new Operator('create_time', Operator::OP_LT, $end_time);
        if(!empty($checktime_ids)) $fileWhere['where']['checktime_id'] = explode(',',$checktime_ids);
        if(!empty($form_id)) $fileWhere['where']['form_id'] = $form_id;
        $fileWhere['columns'] = ['id','img_name','img_src','patient_id','checktime_id','itemsig_id','form_id','create_time','content_id'];
        $fileWhere['order'] = ['itemsig_id','patient_id'];
        $annexData = $this->LocalService()->patientFormContentImg->fetchAll($fileWhere);
//        $annexData = [];
        $formidArr = explode(',',$form_id);
        //查询附件
        $uploadFormId = $this->LocalService()->itemFormField->fetchCol('form_id',[
            'is_del' => 0,
            'item_id' => $item_id,
            'type' => 13,
        ]);
        if(!empty($uploadFormId)){
            $formUploadRelation = [];
            foreach($uploadFormId as $k=>$v){
                if(!empty($formidArr) && !empty($form_id) && !in_array($v,$formidArr)) {
                    unset($uploadFormId[$k]);
                    continue;
                }
                $rule = $this->LocalService()->itemForm->setPreviewScenario('share')->getPreviewConfig($v);
                foreach($rule['form'] as $key=>$value){
                    if($value['type'] == 'UploadFile'){
                        $formUploadRelation[$v][] = $value['prop'];
                    }
                }
                unset($rule);
            }
            if(!empty($uploadFormId)){
                $uploadFormId = implode(',',$uploadFormId);
                $contentWhere['where'] = [
                    'is_del' => 0,
                    'item_id' => $item_id,
                ];
                if(!empty($itemsig_id)) $contentWhere['where']['itemsig_id'] = $itemsig_id;
                if(!empty($patient_id)) $contentWhere['where']['patient_id'] = $patient_id;
                if(!empty($start_time)) $contentWhere['where'][] = new Operator('create_time', Operator::OP_GT, $start_time);
                if(!empty($end_time)) $contentWhere['where'][] = new Operator('create_time', Operator::OP_LT, $end_time);
                if(!empty($checktime_ids)) $contentWhere['where']['checktime_id'] = explode(',',$checktime_ids);;
                if(!empty($uploadFormId)) $contentWhere['where']['form_id'] = $uploadFormId;
                $contentDatas = $this->LocalService()->patientFormContent->fetchAll($contentWhere);
                if(!empty($contentDatas)){
                    foreach($contentDatas as $vv){
                        $jsonData = json_decode($vv['data'],true);
                        if(!empty($jsonData) && isset($formUploadRelation[$vv['form_id']])){
                            $tmp['content_id'] = $vv['id'];
                            $tmp['patient_id'] = $vv['patient_id'];
                            $tmp['checktime_id'] = $vv['checktime_id'];
                            $tmp['itemsig_id'] = $vv['itemsig_id'];
                            $tmp['form_id'] = $vv['form_id'];
                            $tmp['create_time'] = $vv['create_time'];
                            $tmp['id'] = 0;

                            foreach($formUploadRelation[$vv['form_id']] as $relation){
                                if($jsonData[$relation]){
                                    $uploadInfo = json_decode($jsonData[$relation],true);
                                    foreach($uploadInfo as $uploadInfok=>$uploadInfov){
                                        $tmp['img_name'] = $uploadInfov['name'];
                                        $tmp['img_src'] = $uploadInfov['url'];
                                        $annexData[] = $tmp;
                                    }
                                }
                            }
                        }
                    }
                }
            }

        }

        if(empty($annexData)) return self::NO_DATA;

        //获取受试者
        $patientWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($itemsig_id)) $patientWhere['where']['itemsig_id'] = $itemsig_id;
        $patientWhere['columns'] = ['id','patient_name','patient_number'];
        $patientDatas = $this->LocalService()->patient->fetchAll($patientWhere);

        $patientInfo = [];
        foreach($patientDatas as $vv){
            $patientInfo[$vv['id']] = $vv;
        }
        unset($patientDatas);

        $FileUploader = $this->LocalService()->imageUploader;

        $checktimeDatas = $this->getItemchecktime($item_id);

        $stageDatas = $this->getItemstage($item_id);

        $batchnumber = 1;

        $count = 0;

        $nowitemsigID = '';

        //查询所有的检查点表单关联
        $contentDatas = $this->LocalService()->itemCheckcontent->fetchAll(['where'=> [
            'item_id' => $item_id,
            'is_del' => 0,
        ],'columns'=>['check_id','form_id']]);
        $content = [];
        foreach($contentDatas as $k=>$v){
            $content[$v['check_id']][] = $v['form_id'];
        }
        unset($contentDatas);

        $imgDatas = [];

        $sign = [];
//        $countannexData = count($annexData)-1;

        foreach($annexData as $value){

            if(empty($formdata[$value['form_id']])) continue;
            if(!in_array($value['form_id'],$content[$value['checktime_id']])) continue;
            //本批次中心ID
            if(empty($nowitemsigID)) $nowitemsigID = $value['itemsig_id'];
            //如果当前包已满300张图片  或者中心ID不一致则重新生成包
//|| $key == $countannexData
            if($sign[$batchnumber]['count'] == 300 || $nowitemsigID != $value['itemsig_id'] ){
                //打包
                $batchnumber += 1;
                $sign[$batchnumber]['itemsig_id'] = $value['itemsig_id'];
                $sign[$batchnumber]['count'] += 1;
//                $count = 0;
                $nowitemsigID = $value['itemsig_id'];
                $value['batch'] = $batchnumber;
            }else{
                $nowitemsigID = $value['itemsig_id'];
                $sign[$batchnumber]['itemsig_id'] = $value['itemsig_id'];
                $sign[$batchnumber]['count'] += 1;
                $value['batch'] = $batchnumber;
            }
            $imgDatas[] = $value;
        }
        if(empty($sign)) {
            $sign[$batchnumber]['itemsig_id'] = $value['itemsig_id'];
            $sign[$batchnumber]['count'] = $count;
        }
        $this->update(['batch_number'=>$batchnumber],['hashvalue'=>$hashvalue,'f_id'=>0]);
        $childdata['item_id'] = $item_id;
        $childdata['itemsig_id'] = $itemsig_id;
        $childdata['patient_id'] = $patient_id;
        $childdata['start_time'] = $start_time;
        $childdata['end_time'] = $end_time;
        $childdata['checktime_ids'] = $checktime_ids;
        $childdata['f_id'] = $f_id;
        $childdata['hashvalue'] = $hashvalue;

        foreach($sign as $ks => $v){
            $childdata['count'] = $v['count'];
            $childdata['sign_id'] = $v['itemsig_id'];
            $childdata['batch_number'] = $ks;
            $res = $this->LocalService()->itemDownpicture->insert($childdata);
        }


        //查询一对多表单
        $manyForm = $this->LocalService()->itemForm->fetchCol('id',[
            'type' => 1,
            'is_del' => 0,
        ]);

        $rowsNumber = [];

        $rowsIndex = [];
        if(!empty($manyForm)){
            $patientformContentDatas = $this->LocalService()->patientFormContent->fetchAll([
                'where'=> [
                    'form_id' => $manyForm,
                    'is_del' => 0,
                ],
                'columns'=>['patient_id','form_id','checktime_id','id'],
                'order'=>['id']
            ]);

            foreach($patientformContentDatas as $key=>$value){

                $rowsNumberKey = $value['patient_id'].'-'.$value['checktime_id'].'-'.$value['form_id'];

                if(isset($rowsNumber[$rowsNumberKey])){
                    $order = $rowsNumber[$rowsNumberKey] +1;
                    $rowsNumber[$rowsNumberKey] += 1;
                }else{
                    $order = 1;
                    $rowsNumber[$rowsNumberKey] = 1;
                }
                $rowsIndex[$value['patient_id']][$value['checktime_id']][$value['form_id']][$value['id']] = $order;
            }
            unset($patientformContentDatas);
        }

        //受试者 、 检查点 、一对多表单

        //循环下载 更改名称   //查询当前所有的
        foreach($imgDatas as $k=>$v){
            //获取文件后缀
            $pos = strrpos($v['img_src'], ".");//返回/在图片path出现的最后一个位置
            $annex_path = explode('&bucket',$v['img_src']);
            $suffix = substr($annex_path[0], $pos+1);
            //拼接图片名称 【受试者姓名+编号+中心编号+时间戳】

            $fileName = '';
            //获取受试者姓名或编号
            $PatientName = '';

            //受试者编号是否为隐私字段
            $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
                'is_hide' => 0,
                'attr_field' => 'number',
                'is_del' => 0,
                'item_id' => $item_id,
            ]);//获取项目名称

            //受试者姓名是否为隐私字段
            $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
                'is_hide' => 0,
                'attr_field' => 'name',
                'is_del' => 0,
                'item_id' => $item_id,
            ]);//获取项目名称

            if($patientInfo[$v['patient_id']]['patient_name'] != '' && !empty($attrname)){
                $fileName .= '-'.$patientInfo[$v['patient_id']]['patient_name'];
                $PatientName .= '-'.$patientInfo[$v['patient_id']]['patient_name'];
            }
            if($patientInfo[$v['patient_id']]['patient_number'] != '' && !empty($attrnumber)){
                $fileName .= '-'.$patientInfo[$v['patient_id']]['patient_number'];
                $PatientName .= '-'.$patientInfo[$v['patient_id']]['patient_number'];
            }

            $PatientName = trim($PatientName,'-');

            $fileName .= '-'.$signDatas[$v['itemsig_id']].'_'.($k+1);

            $fileName = trim($fileName,'-');

            //拼接后缀名
            $fileName = $fileName.'_'.date('Ymd', $v['create_time']).'.'.$suffix;

            $mkName = $iteminfo['name'].'-'.$v['batch'].'-'.$hashvalue;

            $path = APP_PATH . '/data/downpicture';
            if(file_exists($path) == false)
            {
                mkdir($path, 0777, true);
                chmod($path,0777);
            }
            $sign_name = $signDatas[$v['itemsig_id']];
            if($sign_name != ''){
                $sign_name .= '-'.$signName[$v['itemsig_id']];
            }else{
                $sign_name = $signName[$v['itemsig_id']];
            }

            //创建受试者文件夹
            $path1 = APP_PATH . '/data/downpicture'."/$mkName".'/'.$sign_name.'/'.$PatientName;

            if(file_exists($path1) == false)
            {

                mkdir($path1, 0777, true);
                chmod(APP_PATH . '/data/downpicture'."/$mkName");
                chmod(APP_PATH . '/data/downpicture'."/$mkName".'/'.$sign_name);
                chmod($path1,0777);
            }

            $checkName = $checktimeDatas[$v['checktime_id']]['check_name'];

            if($checktimeDatas[$v['checktime_id']]['stage_id'] != ''){
                $checkName = $stageDatas[$checktimeDatas[$v['checktime_id']]['stage_id']]['stage_name'].'-'.$checkName;
            }

            //创建阶段检查点文件夹
            $path2 = $path1.'/'.$checkName.'/'.$formdata[$v['form_id']]['name'];

            if(file_exists($path2) == false)
            {
                mkdir($path2, 0777, true);
                chmod($path1.'/'.$checkName, 0777);
                chmod($path2,0777);
            }

            if(isset($manyForm[$v['form_id']])){
                if(isset($rowsIndex[$v['patient_id']][$v['checktime_id']][$v['form_id']][$v['content_id']])){
                    $path2 .= '/'.$rowsIndex[$v['patient_id']][$v['checktime_id']][$v['form_id']][$v['content_id']];
                    if(file_exists($path2) == false)
                    {
                        mkdir($path2, 0777, true);
                        chmod($path2,0777);
                    }
                }
            }
            if (preg_match('/\=/', $v['img_src'], $matches, PREG_OFFSET_CAPTURE)) {
                // 获取英文符号后面的内容
                $position = $matches[0][1] + 1; // 索引从0开始，所以需要加1
                $v['img_src'] = substr($v['img_src'], $position); // 截取从符号后的内容
            }

            $result = strstr($v['img_src'], '&style=', true);
            //去除style  例如 img123&style=...

            if($result){
                $res = $FileUploader->downOssFile($result,$path2.'/'.$fileName);
            }else{
                $res = $FileUploader->downOssFile($v['img_src'],$path2.'/'.$fileName);
            }

            chmod($path1.'/'.$fileName,0777);
            if(!isset($imgDatas[$k+1]) || $imgDatas[$k+1]['batch'] != $v['batch']){
                $this->compress($item_id, $hashvalue,$v['batch'],$f_id);
            }

        }
        return true;
    }

    /**
     * Notes :删除文件夹
     * @param $path
     * @return bool
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:12
     */
    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;
    }

    /**
     * Notes :压缩文件夹并下载
     * @param $item_id
     * @param $itemsig_id
     * @return false
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:11
     */
    public function compress(int $item_id,string $hashvalue,$batch,$f_id)
    {
        //项目名称
        $iteninfoWhere['where'] = [
            'id' => $item_id,
            'is_del' => 0,
        ];
        $iteninfoWhere['columns'] = ['name','number','fid'];
        $iteminfo = $this->LocalService()->itemInfo->fetchOne($iteninfoWhere);

        $path1 = APP_PATH . '/data/downpicture'."/".$hashvalue;
        if(file_exists($path1) == false)
        {
            mkdir($path1, 0777, true);
            chmod($path1,0777);
        }

        $mkName = $iteminfo['name'].'-'.$batch.'-'.$hashvalue;

        $path = APP_PATH.'/data/downpicture'.'/'."$mkName";

        if(file_exists($path) == false) return false;

        $filename = APP_PATH . '/data/downpicture'."/$hashvalue/".$iteminfo['name'].'-'.$batch; //想要生成的压缩包

        //开始压缩文件并且下载到本地
        $res = $this->create_zip($path,$filename);
        //删除文件夹
        $this->DelDirHandle($path);

        $this->update(['is_success'=>1],['hashvalue'=>$hashvalue,'batch_number'=>$batch,'f_id'=>$f_id]);

        return true;
    }

    public function getHashValue()
    {
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
        $random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
        $content = uniqid().$random;  // 类似 5443e09c27bf4aB4uT
        return sha1($content);
    }


    /**
     * Notes :要压缩的文件夹路径/要生成的压缩包名称
     * @param $path
     * @param $filename
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:11
     */
    public function create_zip($path,$filename)
    {
        $zip = new \ZipArchive();
        if($zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
            $this->addFileToZip($path, $zip);//调用方法，对要打包的根目录进行操作，并将ZipArchive的对象传递给方法PHP 截取第二个/后数据
            $zip->close(); //关闭处理的zip文件
        }
    }

    /**
     * Notes :递归写入压缩包
     * @param $path
     * @param $zip
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:10
     */
    public function addFileToZip($path,$zip) {
        $handler = opendir($path); //打开当前文件夹由$path指定。

        while (($filename = readdir($handler)) !== false) {

            if ($filename != "." && $filename != "..") {
                //文件夹文件名字为'.'和‘..’，不要对他们进行操作

                if (is_dir($path . "/" . $filename)) {
                    $this->addFileToZip($path . "/" . $filename, $zip);
                } else {
//                    $mkpath = substr($path . "/" . $filename,strpos($path . "/" . $filename,'public')+7);
//                    var_dump($mkpath);die;
                    $url = $path . "/" . $filename;
                    $url = substr($url,stripos($url,"/")+1);
                    $filename_new = substr($url,stripos($url,"/")+1);

                    $absolutely = substr($filename_new,stripos($filename_new,"/")+1);

                    $absolutely = $this->handleaddress($absolutely);

                    $zip->addFile($path . "/" . $filename,$absolutely);
                }
            }
        }
        @closedir($path);
    }


    public function handleaddress($path)
    {
        $address = explode('/',$path);
        $absolutely = substr($path,stripos($path,"/")+1);
        if($address[0] != 'downpicture'){
//            $absolutely = substr($path,stripos($path,"/")+1);
            $absolutely = $this->handleaddress($absolutely);
        }
        return $absolutely;
    }

    /**
     * Notes :返回项目检查点
     * @param $item_id
     * @return array
     * Author:lwl
     * Date:2022/8/3 14:09
     */
    public function getItemchecktime($item_id)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $whereArr['columns'] = ['id', 'check_name', 'stage_id'];
        $whereArr['order'] = 'check_order';
        $data = $this->LocalService()->itemChecktime->fetchAll($whereArr);
        $checktimeDatas = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $checktimeDatas[$v['id']] = $v;
            }
        }
        return $checktimeDatas;
    }

    /**
     * Notes :返回项目阶段
     * @param $item_id
     * @return array
     * Author:lwl
     * Date:2022/8/3 14:09
     */
    public function getItemstage($item_id)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $whereArr['columns'] = ['id', 'stage_name'];
        $whereArr['order'] = 'stage_order';
        $data = $this->LocalService()->itemResearchstage->fetchAll($whereArr);
        $stageDatas = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $stageDatas[$v['id']] = $v;
            }
        }
        return $stageDatas;
    }
}