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

namespace Application\Service\DB\Ocr;
use Application\Service\Extension\Helper\StringHelper;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Stdlib\ArrayUtils;
use Application\Common\Com;
class Rawlock extends \Application\Service\DB\AbstractDb
{
    public function __construct($dbAdapter, ContainerInterface $container)
    {
        $this->tableName = 'yikeen_ocr_rawlock';
        parent::__construct($dbAdapter, $container);
    }

    /**
     * Notes: 获取指定条件下的锁定数据
     * User: lltyy
     * DateTime: 2023/5/18 8:56
     *
     * @param $where
     * @return array[]
     */
    public function fetchLockByRaw($where,$columns){
        $datas = [];
        //获取指定条件下的锁定数据
        $cond = [
            'where'=>$where,
            'columns'=>$columns,
            'order'=>['raw_id']
        ];
        $lockdatas = $this->fetchAll($cond);
        if(!empty($lockdatas)){
            foreach($lockdatas as &$lockdata) {
                $raw_id = $lockdata['raw_id'];
                $datas[$raw_id] = $lockdata;
            }
        }
        unset($cond);
        unset($lockdatas);
        return $datas;
    }

    /**
     * Notes: 获取指定条件下的匹配的日期
     * User: lltyy
     * DateTime: 2023/6/27 14:27
     * @param int $patient_id //受试者ID
     * @param $where
     * @param int $return_type//返回数据类型【0 最早的日期 1 指标对应的数据】
     * @return array
     */
    public function fetchLockDateByMate($patient_id,array $where,$return_type=0,$columns=[]){
        $return_type = isset($return_type) && !empty($return_type) ? $return_type : 0;

        //获取受试者的入组日期以及入组时间7天之前的日期
        $group_date = $pre_group_date = '';
        $patient_group_date = $this->LocalService()->ocrSigpatient->getOneFieldVal('group_date',[
            'id' => $patient_id,
        ]);
        if(!is_null($patient_group_date) && !empty($patient_group_date)){
            $group_date = $this->LocalService()->ocrSigpatient->getTrueGroupDate($patient_group_date);
        }
        if(!empty($group_date)){
            $pre_group_date = date('Y-m-d',strtotime('-7 days',strtotime($group_date.' 00:00:00')));
        }
        $group_date_int = $group_date != '' ? intval((str_replace('-','',$group_date))) : 0;
        $pre_group_date_int = $pre_group_date != '' ? intval((str_replace('-','',$pre_group_date))) : 0;

        //获取指定条件下的锁定数据
        if(empty($columns)){
            $columns = ['raw_date','keyword_id'];
            if($return_type == 1){
                $columns = ['id'=>'raw_id','raw_name','annex_id','raw_range','raw_min','raw_max','raw_result','raw_date','keyword_id'];
            }
        }
        $cond = [
            'where'=>$where,
            'columns'=>$columns,
            'order'=>['raw_date','id']
        ];
        $lockdatas = $this->fetchAll($cond);
        $date_datas = [
            'after'=>[],//大于等于入组日期7天前 的数据
            'pre'=>[],//小于入组日期7天前的数据
            'null'=>[]//无日期数据
        ];
        if(!empty($lockdatas)){
            $rawNameDatas = [];
            if($return_type == 1){
                $where['id'] = $where['raw_id'];
                unset($where['raw_id']);
                $rawNameDatas = $this->LocalService()->ocrRawdata->fetchCol('raw_name',ArrayUtils::merge($where, [
                    'is_lock' => 1,
                ]));
            }
            $keyword_parent_arr = $this->LocalService()->ocrKeyword->fetchCol('parent_id','is_del = 0 and parent_id > 0');
            foreach($lockdatas as $lockKey=>&$lockdata) {
                $raw_date = !is_null($lockdata['raw_date']) && $lockdata['raw_date'] != '' ? $lockdata['raw_date'] : '';

                $raw_date_int = 0;
                $valiDate = $this->LocalService()->ocrOcrannex->validAnnexDate($raw_date);
                if(in_array($valiDate['code'],[200,60012])){
                    $raw_date_int = $valiDate['date'] != '' ? intval($valiDate['date']) : 0;
                }

                $keyword_id = $lockdata['keyword_id'];
                $keyword_parent = isset($keyword_parent_arr[$keyword_id]) && !empty($keyword_parent_arr[$keyword_id]) ? $keyword_parent_arr[$keyword_id] : 0;
                if($keyword_parent > 0){
                    $keyword_id = $keyword_parent;
                }
                if($return_type == 1) {
                    $raw_id = $lockdata['id'];
                    $lockdata['mate_name'] = $lockdata['raw_name'];
                    $lockdata['raw_name'] = isset($rawNameDatas[$raw_id]) && !empty($rawNameDatas[$raw_id]) ? $rawNameDatas[$raw_id] : '';
                }

                if(!empty($raw_date_int)){
                    if(!empty($group_date_int)){
                        //大于等于入组日期7天前 的数据
                        if($raw_date_int >= $pre_group_date_int){
                            $date_datas['after'][$keyword_id][] = $lockdata;
                        }

                        //小于入组日期7天前的数据
                        if($raw_date_int < $pre_group_date_int){
                            $date_datas['pre'][$keyword_id][] = $lockdata;
                        }
                    }else{
                        $date_datas['after'][$keyword_id][] = $lockdata;
                    }
                }else{
                    $date_datas['null'][$keyword_id][] = $lockdata;
                }
                unset($lockdatas[$lockKey]);
            }
            unset($keyword_parent_arr);
            unset($rawNameDatas);
        }
        unset($cond);
        unset($lockdatas);

        $datas = [];
        //大于等于入组日期7天前 的数据
        if(!empty($date_datas['after'])){
            foreach($date_datas['after'] as $afterKeywordId=>$afterDatas){
                if($return_type == 0){
                    $datas[$afterKeywordId] = $afterDatas[0]['raw_date'];
                }
                if($return_type == 1){
                    $datas[$afterKeywordId] = $afterDatas;
                }
            }
        }
        unset($date_datas['after']);

        //小于入组日期7天前的数据
        if(!empty($date_datas['pre'])){
            foreach($date_datas['pre'] as $preKeywordId=>$preDatas){
                krsort($preDatas);
                if($return_type == 0){
                    if(!isset($datas[$preKeywordId]) || empty($datas[$preKeywordId])){
                        $datas[$preKeywordId] = $preDatas[0]['raw_date'];
                    }
                }
                if($return_type == 1){
                    $datas[$preKeywordId] = isset($datas[$preKeywordId]) && !empty($datas[$preKeywordId]) ? $datas[$preKeywordId] : [];
                    $datas[$preKeywordId] = array_merge($datas[$preKeywordId],$preDatas);
                }
            }
        }
        unset($date_datas['pre']);

        //无日期的数据
        if(!empty($date_datas['null'])){
            foreach($date_datas['null'] as $nullKeywordId=>$nullDatas){
                if($return_type == 0){
                    if(!isset($datas[$nullKeywordId]) || empty($datas[$nullKeywordId])){
                        $datas[$nullKeywordId] = $nullDatas[0]['raw_date'];
                    }
                }
                if($return_type == 1){
                    $datas[$nullKeywordId] = isset($datas[$nullKeywordId]) && !empty($datas[$nullKeywordId]) ? $datas[$nullKeywordId] : [];
                    $datas[$nullKeywordId] = array_merge($datas[$nullKeywordId],$nullDatas);
                }
            }
        }
        unset($date_datas['null']);

        return $datas;
    }


    /**
     * Notes: 获取中心下检查项的匹配信息
     * User: lltyy
     * DateTime: 2023/6/27 14:27
     * @param int $sig_id //中心ID
     * @param int $keyword_id //检查项ID
     * @param int $select_type //查询数据类型【0 所有数据 1 第一批数据 2 第二批数据】
     * @return array
     */
    public function fetchPatientByMate($sig_id,$keyword_id=0,$select_type=0){
        $return_type = isset($return_type) && !empty($return_type) ? $return_type : 0;

        //获取检查项信息
        $keyword_parent_arr = $keyword_name_arr = [];
        $keyword_parent = 0;
        $keyword_cond = [
            'where'=>'is_del = 0',
            'columns'=>['id','parent_id','keyword_name'],
            'order'=>['parent_id','keyword_order','id']
        ];
        $keywordDatas = $this->LocalService()->ocrKeyword->fetchAll($keyword_cond);
        unset($keyword_cond);
        if(!empty($keywordDatas)){
            foreach($keywordDatas as $keywordKey=>$keywordData){
                $keywordData_id = $keywordData['id'];
                $keywordData_parent = $keywordData['parent_id'];
                $keyword_parent_arr[$keywordData_id] = $keywordData_parent;
                if(!empty($keyword_id) && $keyword_id == $keywordData_id){
                    $keyword_parent = !empty($keywordData_parent) ? $keywordData_parent : $keyword_id;
                }

                if(empty($keywordData_parent)){
                    $keyword_name_arr[$keywordData_id] = $keywordData['keyword_name'];
                }
                unset($keywordDatas[$keywordKey]);
            }
        }
        unset($keywordDatas);

        //获取中心下患者信息
        $patient_arr = [];
        $patient_where = [
            'is_del' => 0,
            'pid' => $sig_id,
            new Operator('have_status', Operator::OP_LTE, 1),
        ];
        if($select_type == 2){
            $patient_where[] = new Operator('id', Operator::OP_GTE, 18017);
        }
        $sigPatientDatas = $this->LocalService()->ocrSigpatient->fetchDataById($patient_where,['id','group_date']);
        if(!empty($sigPatientDatas)){
            foreach($sigPatientDatas as &$sigPatientData){
                $group_date = $this->LocalService()->ocrSigpatient->getTrueGroupDate($sigPatientData['group_date']);
                $pre_group_date = $group_date != '' ? date('Y-m-d',strtotime('-7 days',strtotime($group_date.' 00:00:00'))) : '';
                $after_group_date = $group_date != '' ? date('Y-m-d',strtotime('+7 days',strtotime($group_date.' 00:00:00'))) : '';
                $sigPatientData['date_int'] = $group_date != '' ? intval((str_replace('-','',$group_date))) : 0;
                $sigPatientData['pre_date_int'] = $pre_group_date != '' ? intval((str_replace('-','',$pre_group_date))) : 0;
                $sigPatientData['after_date_int'] = $after_group_date != '' ? intval((str_replace('-','',$after_group_date))) : 0;
            }
            $patient_arr = array_keys($sigPatientDatas);
        }

        //获取锁定信息
        $lock_where = [
            'is_del' => 0,
            'sig_id' => $sig_id,
        ];
        if(!empty($patient_arr)){
            $lock_where['patient_id'] = StringHelper::toArray($patient_arr);
        }else{
            $lock_where = 'id < 0';
        }

        $lock_cond = [
            'where'=>$lock_where,
            'columns'=>['raw_date','sig_id','patient_id','keyword_id'],
            'order'=>['raw_date','id']
        ];
        $lockDatas = $this->fetchAll($lock_cond);
        $patient_num_arr = $sig_lockpatient_arr = $patient_have_check = [];
        if(!empty($lockDatas)){
            foreach($lockDatas as $lockData){
                $lock_sig = $lockData['sig_id'];
                $lock_patient = $lockData['patient_id'];
                $sig_lockpatient_arr[$lock_sig][$lock_patient] = $lock_patient;

                //患者入组时间
                $patient_date = isset($sigPatientDatas[$lock_patient]) && isset($sigPatientDatas[$lock_patient]['date_int']) && !empty($sigPatientDatas[$lock_patient]['date_int']) ? $sigPatientDatas[$lock_patient]['date_int'] : 0;
                //患者入组时间前7天
                $patient_pre_date = isset($sigPatientDatas[$lock_patient]) && isset($sigPatientDatas[$lock_patient]['pre_date_int']) && !empty($sigPatientDatas[$lock_patient]['pre_date_int']) ? $sigPatientDatas[$lock_patient]['pre_date_int'] : 0;
                //患者入组时间后7天
                $patient_after_date = isset($sigPatientDatas[$lock_patient]) && isset($sigPatientDatas[$lock_patient]['after_date_int']) && !empty($sigPatientDatas[$lock_patient]['after_date_int']) ? $sigPatientDatas[$lock_patient]['after_date_int'] : 0;

                $lock_keyword = $lockData['keyword_id'];
                $lock_keyword_parent = isset($keyword_parent_arr[$lock_keyword]) && !empty($keyword_parent_arr[$lock_keyword]) ? $keyword_parent_arr[$lock_keyword] : 0;
                if(!empty($lock_keyword_parent)){
                    $lock_keyword = $lock_keyword_parent;
                }
                $patient_have_check[$lock_patient][$lock_keyword] = $lock_keyword;


                //获取采集时间【年月日】
                $lockData['raw_date'] = !is_null($lockData['raw_date']) && $lockData['raw_date'] != '' ? $lockData['raw_date'] : '';
                $raw_time = 0;
                $valiDate = $this->LocalService()->ocrOcrannex->validAnnexDate($lockData['raw_date']);
                if(in_array($valiDate['code'],[200,60012])){
                    $raw_time = $valiDate['date'] != '' ? intval($valiDate['date']) : 0;
                }
                $arr_key = 'after';//7天后
                if($raw_time != 0){
                    if($patient_date != 0){
                        if($raw_time == $patient_date){
                            $arr_key = 'now';//当天
                        }else{
                            if($raw_time >= $patient_pre_date && $raw_time <= $patient_after_date){
                                $arr_key = 'in';//7天内
                            }else{
                                if($raw_time < $patient_pre_date){
                                    $arr_key = 'pre';//7天前
                                }
                            }
                        }
                    }
                }

                //重组数据数组
                if($keyword_parent == 0 || $keyword_parent == $lock_keyword){
                    $patient_num_arr[$lock_keyword]['have'][$lock_patient] = $lock_patient;
                    $patient_num_arr[$lock_keyword][$arr_key][$lock_patient] = $lock_patient;
                }
            }

            foreach($patient_num_arr as $mate_word=>$patient_num_data){
                $in_datas = isset($patient_num_data['in']) && !empty($patient_num_data['in']) ? $patient_num_data['in'] : [];//7天内
                $now_datas = isset($patient_num_data['now']) && !empty($patient_num_data['now']) ? $patient_num_data['now'] : [];//当天
                $after_datas = isset($patient_num_data['after']) && !empty($patient_num_data['after']) ? $patient_num_data['after'] : [];//7天后
                $pre_datas = isset($patient_num_data['pre']) && !empty($patient_num_data['pre']) ? $patient_num_data['pre'] : [];//7天前

                //去除其他数组中7天内的数据
                if(!empty($in_datas)){
                    foreach($in_datas as $in_data_patient){
                        if(isset($now_datas[$in_data_patient])){
                            unset($now_datas[$in_data_patient]);
                            unset($patient_num_arr[$mate_word]['now'][$in_data_patient]);
                        }
                        if(isset($after_datas[$in_data_patient])){
                            unset($after_datas[$in_data_patient]);
                            unset($patient_num_arr[$mate_word]['after'][$in_data_patient]);
                        }
                        if(isset($pre_datas[$in_data_patient])){
                            unset($pre_datas[$in_data_patient]);
                            unset($patient_num_arr[$mate_word]['pre'][$in_data_patient]);
                        }
                    }
                }

                //去除其他数组中当天的数据
                if(!empty($now_datas)){
                    foreach($now_datas as $now_data_patient){
                        if(isset($after_datas[$now_data_patient])){
                            unset($after_datas[$now_data_patient]);
                            unset($patient_num_arr[$mate_word]['after'][$now_data_patient]);
                        }
                        if(isset($pre_datas[$now_data_patient])){
                            unset($pre_datas[$now_data_patient]);
                            unset($patient_num_arr[$mate_word]['pre'][$now_data_patient]);
                        }
                    }
                }

                //去除其他数组中7天后的数据
                if(!empty($after_datas)){
                    foreach($after_datas as $after_data_patient){
                        if(isset($pre_datas[$after_data_patient])){
                            unset($pre_datas[$after_data_patient]);
                            unset($patient_num_arr[$mate_word]['pre'][$after_data_patient]);
                        }
                    }
                }
            }
        }

        $lack_check_arr = [];
        if(!empty($keyword_name_arr) && !empty($patient_arr)){
            foreach($patient_arr as $patient_id){
                $lock_keyword_arr = isset($patient_have_check[$patient_id]) && !empty($patient_have_check[$patient_id]) ? $patient_have_check[$patient_id] : [];
                $lock_keyword_arr = array_values($lock_keyword_arr);
                foreach($keyword_name_arr as $keyword_name_id=>$keyword_name){
                    if(!in_array($keyword_name_id,$lock_keyword_arr)){
                        $lack_check_arr[$patient_id][] = $keyword_name;
                    }
                }
            }
        }
        unset($keyword_name_arr);

        $arr = [
            'mate_patient'=>$patient_num_arr,
            'patient_num'=>count($patient_arr),
            'lock_patient'=>$sig_lockpatient_arr,
            'lack_check'=>$lack_check_arr
        ];
        if(!empty($keyword_parent)){
            $arr['mate_patient'] = isset($patient_num_arr[$keyword_parent]) && !empty($patient_num_arr[$keyword_parent]) ? $patient_num_arr[$keyword_parent] : [];
            $arr['keyword_parent'] = $keyword_parent;
            unset($arr['patient_num']);
        }
        return $arr;
    }


    /**
     * Notes:化验单 - 数据去重【调用 yikeen_ocr_rawlock_end】
     * User: lltyy
     * DateTime: 2023/5/26 15:26
     *
     */
    public function scanUniqueData(){
        $where = 'is_del = 0 and pid > 0 and have_status <= 1';
        $bool = true;
        $page = 0;
        $limit = 100;
        $last_id = 0;
        while ($bool) {
            $page++;
            echo "rawUniquePAGE {$page}：" . PHP_EOL;
            $last_id = $this->mateUniqueData($where. ' and id > ' . $last_id, $limit,0);
            if(!$last_id) $bool = false;
        }
    }

    /**
     * Notes: 获取指定条件下的匹配的日期
     * User: lltyy
     * DateTime: 2023/6/27 14:27
     * @param int $patient_id //受试者ID
     * @param $where
     * @param int $return_type//返回数据类型【0 最早的日期 1 指标对应的数据】
     * @return array
     */
    public function mateUniqueData($where,$limit,$offset){
        $patient_cond = [
            'where'=>$where,
            'columns'=>['id'],
            'order'=>['id']
        ];
        if(!empty($limit) || !empty($offset)){
            $patient_cond['limit'] = $limit;
            $patient_cond['offset'] = $offset;
        }
        $patientDatas = $this->LocalService()->ocrSigpatient->fetchAll($patient_cond);
        unset($patient_cond);
        $last_id = 0;
        if(!empty($patientDatas)){
            foreach($patientDatas as $patientKey=>$patientData){
                $last_id = $patientData['id'];
                $datas = [];
                if(!empty($datas)){
                    foreach($datas as $dataKeyword=>$data_infos){
                        $saveDate = [];
                        foreach($data_infos as $data_key=>$data){
                            $data_raw_date = !is_null($data['raw_date']) && $data['raw_date'] != '' ? $data['raw_date'] : '';
                            $save_data = $data;
                            if($data_key == 0){
                                $save_data['info_type'] = 1;
                                $this->LocalService()->ocrRawlockunique->save($save_data);
                                if($data_raw_date != ''){
                                    $saveDate[] = $data_raw_date;
                                }
                            }else{
                                if(($data_raw_date != '' && !in_array($data_raw_date,$saveDate)) || $data_raw_date == ''){
                                    $save_data['info_type'] = 2;
                                    $this->LocalService()->ocrRawlockunique->save($save_data);
                                    $saveDate[] = $data_raw_date;
                                }
                            }
                            unset($data_raw_date);
                            unset($save_data);
                            unset($data_infos[$data_key]);
                            unset($datas[$dataKeyword][$data_key]);
                        }
                        unset($saveDate);
                        unset($datas[$dataKeyword]);
                    }
                }
                unset($datas);
                unset($patientDatas[$patientKey]);
            }
        }
        unset($patientDatas);

        return $last_id;
    }
}