<?php

namespace Application\Service\DB\Item;

use Application\Service\Extension\Helper\StringHelper;
use Interop\Container\ContainerInterface;
use Application\Service\Extension\Helper\SDMHelper;
use Laminas\Db\Sql\Predicate\Between;
use Laminas\Db\Sql\Predicate\IsNull;
use Laminas\Db\Sql\Predicate\NotIn;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Where;
use Laminas\Stdlib\ArrayUtils;

class PatientFormContentImg extends \Application\Service\DB\AbstractDb
{
    // 化验单
    const IMG_TYPE_CHECKIMG = 1;

    // 计划外检查
    const IMG_TYPE_OUTPLANCHECK = 2;

    // 普通表单
    const IMG_TYPE_NORMAL = 3;

    public function __construct($dbAdapter, ContainerInterface $container)
    {
        if (!$this->tableName) {
            $this->tableName = 'yikeen_item_patient_form_content_img';
        }

        parent::__construct($dbAdapter, $container);
    }


    /**
     * Notes:附件更新
     * User: lltyy
     * DateTime: 2023/5/30 11:00
     *
     */
    public function scanAnnex($arr = []){
        //项目
        $item_id_arr = [];
        $item_id = isset($arr['item_id']) && !empty($arr['item_id']) ? $arr['item_id'] : 0;
        if(!empty($item_id)){
            $item_id_arr = [$item_id];
        }
        //中心
        $itemsig_id_arr = [];
        $itemsig_id = isset($arr['itemsig_id']) && !empty($arr['itemsig_id']) ? $arr['itemsig_id'] : 0;
        if(!empty($itemsig_id)){
            $itemsig_id_arr = [$itemsig_id];
        }
        //患者
        $patient_id_arr = [];
        $patient_id = isset($arr['patient_id']) && !empty($arr['patient_id']) ? $arr['patient_id'] : 0;
        if(!empty($patient_id)){
            $patient_id_arr = [$patient_id];
        }
        //附件
        $annex_arr = [];
        $annex_id = isset($arr['annex_id']) && !empty($arr['annex_id']) ? $arr['annex_id'] : 0;
        if(!empty($annex_id)){
            $annex_arr = [$annex_id];
        }

        //更新附件信息
        $info_where = [
            'is_del' => 0,
            'is_lock' => 0,
        ];
        if(!empty($itemsig_id_arr)){
            $info_where['itemsig_id'] = StringHelper::toArray($itemsig_id_arr);
        }
        if(!empty($patient_id_arr)){
            $info_where['patient_id'] = StringHelper::toArray($patient_id_arr);
        }
        if(!empty($annex_arr)) {
            $info_where['annex_id'] = StringHelper::toArray($annex_arr);
        }
        $medical_annex_arr = $this->LocalService()->medicalOcrdata->fetchAnnexData($info_where);
        unset($medical_annex_arr['mate_id']);
        unset($medical_annex_arr['no_mate_id']);
        unset($medical_annex_arr['black_id']);

        $annex_where = [
            'is_del' => 0,
            'is_lock' => [0, 3],
            'through_process_do_type' => [1, 2, 3],
        ];

        if(!empty($item_id_arr)){
            $annex_where['item_id'] = StringHelper::toArray($item_id_arr);
        }
        if(!empty($itemsig_id_arr)){
            $annex_where['itemsig_id'] = StringHelper::toArray($itemsig_id_arr);
        }
        if(!empty($patient_id_arr)){
            $annex_where['patient_id'] = StringHelper::toArray($patient_id_arr);
        }
        if(!empty($annex_arr)) {
            $annex_where['id'] = StringHelper::toArray($annex_arr);
        }
        $annex_bool = true;
        $annex_page = 0;
        $annex_limit = 100;
        $last_annex_id = 0;
        while ($annex_bool) {
            $annex_page++;
            echo "AnnexPAGE {$annex_page}：" . PHP_EOL;
            $last_annex_id = $this->updateAnnexCount($annex_where.' and id > '.$last_annex_id,$annex_limit,0,$medical_annex_arr);
            if(!$last_annex_id) $annex_bool = false;
        }
        unset($item_id_arr);
        unset($itemsig_id_arr);
        unset($patient_id_arr);
        unset($annex_arr);
        unset($medical_annex_arr);
    }


    /**
     * Notes: 获取指定条件下的识别结果数据 与 指标关键字匹配，存入匹配信息表
     * User: lltyy
     * DateTime: 2023/4/25 10:16
     *
     * @param $where
     * @return array
     */
    public function updateAnnexCount($where,$limit=0,$offset=0,&$medical_count_arr){
        //获取指定条件下的识别结果数据
        $cond = [
            'where'=>$where,
            'columns'=>['id','is_lock'],
            'order'=>['id']
        ];
        if(!empty($limit)){
            $cond['limit'] = $limit;
            $cond['offset'] = $offset;
        }
        $datas = $this->fetchAll($cond);
        $last_annex_id = 0;
        if(!empty($datas)){
            foreach($datas as $dataKey=>$data){
                $data_id = $data['id'];
                $last_annex_id = $data_id;
                $mate_count = isset($medical_count_arr['mate_count']) && isset($medical_count_arr['mate_count'][$data_id]) && !empty($medical_count_arr['mate_count'][$data_id]) ? $medical_count_arr['mate_count'][$data_id] : 0;
                $act_count = isset($medical_count_arr['act_count']) && isset($medical_count_arr['act_count'][$data_id]) && !empty($medical_count_arr['act_count'][$data_id]) ? $medical_count_arr['act_count'][$data_id] : 0;
                $no_mate_count = isset($medical_count_arr['no_mate_count']) && isset($medical_count_arr['no_mate_count'][$data_id]) && !empty($medical_count_arr['no_mate_count'][$data_id]) ? $medical_count_arr['no_mate_count'][$data_id] : 0;
                $black_count = isset($medical_count_arr['black_count']) && isset($medical_count_arr['black_count'][$data_id]) && !empty($medical_count_arr['black_count'][$data_id]) ? $medical_count_arr['black_count'][$data_id] : 0;
                unset($medical_count_arr['mate_count'][$data_id]);
                unset($medical_count_arr['act_count'][$data_id]);
                unset($medical_count_arr['no_mate_count'][$data_id]);
                unset($medical_count_arr['black_count'][$data_id]);

                $save_data = [
                    'id'=>$data_id,
                    'act_count'=>$act_count,
                    'mate_count'=>$mate_count,
                    'no_mate_count'=>$no_mate_count,
                    'black_count'=>$black_count
                ];
                $save_data['is_lock'] = 0;
                //将弃用的附件下的识别数据变为弃用状态
                if((empty($mate_count) && (!empty($black_count) || !empty($no_mate_count))) || $data['is_lock'] == 2) {
                    $save_data['is_lock'] = 2;
                    $lose_where = 'annex_type = 2 and id = '.$data_id;
                    $this->loseAnnexData($lose_where,0);
                }
                //锁定数据
                if($data['is_lock'] == 1){
                    $save_data['is_lock'] = 1;
                    $lock_where = [
                        'annex_type' => 2,
                        'id' => $data_id,
                    ];
                    $this->lockAnnexData($lock_where,0);
                }
                $this->save($save_data);
                unset($save_data);
                unset($datas[$dataKey]);
            }
        }
        unset($cond);
        unset($datas);
        return $last_annex_id;
    }


    /**
     * Notes:附件 - 弃用
     * User: lltyy
     * DateTime: 2023/5/25 9:37
     *
     * @param string $where//条件
     * @param int $execute_type//执行类型【0 只执行有传递条件的数据 1 传递条件基础上增加弃用条件】
     * @return int
     */
    public function loseAnnexData($where,$execute_type=0){
        $count = 0;
        //获取有匹配数无黑名单数无未匹配数据的附件ID
        if(!empty($execute_type)){
            if(!empty($where)){
                if($where instanceof Where) {
                    $where->equalTo('is_del', 0);
                    $where->equalTo('mate_count', 0);
                    $where->greaterThan('no_mate_count', 0);
                    $where->equalTo('black_count', 0);
                }
            }else{
                $where = 'is_del = 0 and mate_count = 0 and no_mate_count > 0 and black_count = 0';
            }
        }
        if(empty($where)){
            $where = 'id < 0';
        }
        $medical_annex_arr = $this->fetchCol('id',$where);
        $medical_annex_arr = array_values($medical_annex_arr);
        if(!empty($medical_annex_arr)){
            $this->LocalService()->medicalOcrdata->update(['is_lock'=>2],[
                'is_del' => 0,
                'annex_id' => StringHelper::toArray($medical_annex_arr),
            ]);
            $this->LocalService()->medicalLock->upDelState([
                'is_del' => 0,
                'annex_id' => StringHelper::toArray($medical_annex_arr),
            ]);

            //更新附件状态为弃用
            $this->update(['is_lock'=>2],[
                'is_del' => 0,
                'annex_id' => StringHelper::toArray($medical_annex_arr),
            ]);
        }
        unset($execute_type);
        unset($where);
        unset($medical_annex_arr);

        return $count;
    }

    /**
     * Notes:附件 - 锁定
     * User: lltyy
     * DateTime: 2023/5/25 9:37
     *
     * @param string $where//条件
     * @param int $execute_type//执行类型【0 只执行有传递条件的数据 1 传递条件基础上增加弃用条件】
     * @return int
     */
    public function lockAnnexData($where='',$execute_type=0){
        $count = 0;

        //获取有匹配数无黑名单数无未匹配数据的附件ID
        if(!empty($execute_type)){
            if(!empty($where)){
                if($where instanceof Where) {
                    $where->equalTo('is_del', 0);
                    $where->equalTo('mate_count', 0);
                    $where->greaterThan('no_mate_count', 0);
                    $where->equalTo('black_count', 0);
                }
            }else{
                $where = 'is_del = 0 and mate_count = 0 and no_mate_count > 0 and black_count = 0';
            }
        }

        if(empty($where)){
            $where = 'id < 0';
        }

        $medical_annex_arr = $this->fetchCol('id',$where);
        $medical_annex_arr = array_values($medical_annex_arr);
        if(!empty($medical_annex_arr)){//医嘱
            //获取附件下已匹配的内容数据
            $detail_where = [
                'is_del' => 0,
                'annex_id' => StringHelper::toArray($medical_annex_arr),
            ];
            $detail_cond = [
                'where'=> ArrayUtils::merge($detail_where, [
                    'mate_type' => 1,
                    new Operator('drug_id', Operator::OP_GT, 0)
                ]),
                'columns'=>['id','sig_id','patient_id','annex_id','medical_name','medical_date','end_date','drug_name','drug_id','dosage_id','dosage_num','dosage_unit','times_id','is_dispensary','medical_type'],
                'order'=>['id']
            ];
            $medicalDatas = $this->LocalService()->ocrMedical->fetchAll($detail_cond);
            if(!empty($medicalDatas)){
                //获取已匹配数据
                $medicalMateDatas = $this->LocalService()->medicalMatewhite->fetchMedicalMatedata($detail_where,0);
                //获取锁定数据
                $medicalLockDatas = $this->LocalService()->medicalLock->fetchLockByMedical($detail_where,['id','ocrdata_id']);
                if(!empty($medicalMateDatas)){
                    foreach($medicalDatas as &$medicalData){
                        $medical_id = $medicalData['id'];
                        unset($medicalData['id']);
                        $medicalData['id'] = isset($medicalLockDatas[$medical_id]) && !empty($medicalLockDatas[$medical_id]) ? $medicalLockDatas[$medical_id]['id'] : 0;
                        $medicalData['ocrdata_id'] = $medical_id;
                        $this->LocalService()->medicalLock->save($medicalData);
                    }
                }
                unset($medicalMateDatas);
            }

            //更新附件为锁定
            $this->update(['is_lock'=>1,'black_count'=>0,'no_mate_count'=>0],$where);
        }
        unset($execute_type);
        unset($where);
        unset($medical_annex_arr);

        return $count;
    }

    /**
     * Notes: 获取信息
     * User: lltyy
     * DateTime: 2024/8/15 10:26
     *
     * @param array $arr
     * @return array
     */
    public function fetchDataNum($arr = []){
        $noitem_id = isset($arr['noitem_id']) && !empty($arr['noitem_id']) ? trim($arr['noitem_id'],',') : 0;//去除项目ID 字符串
        $item_id = isset($arr['item_id']) && !empty($arr['item_id']) ? trim($arr['item_id'],',') : 0;//项目ID 字符串
        $itemsig_id = isset($arr['itemsig_id']) && !empty($arr['itemsig_id']) ? trim($arr['itemsig_id'],',') : 0;//项目中心ID 字符串

        $info = [
            'unlockNoOperateNum'=>0,//申请解锁/解锁未更新
            'unlockOperateNum'=>0,//解锁已更新
            'child_item_id'=>[]//副项目IDS
        ];

        $where = [
            'is_del' => 0,
            new NotIn('info_collect_type', [3]),
            new Operator('gco_pool', Operator::OP_NE, ''),
            new Operator('item_id', Operator::OP_GT, 0),
        ];
        if(!empty($item_id)){
            $where['item_id'] = StringHelper::toArray($item_id);
        }
        if(!empty($noitem_id)){
            $where[] = new NotIn('item_id', StringHelper::toArray($noitem_id));
        }
        if(!empty($itemsig_id)){
            $where['itemsig_id'] = StringHelper::toArray($item_id);
        }
        $datas = $this->fetchAll([
            'where'=>$where,
            'columns'=>['item_id','patient_id','checktime_id','form_id','is_lock'],
            'group'=>['item_id','itemsig_id','checktime_id','patient_id','gco_pool'],
            'order'=>['id desc']
        ]);
        unset($where);
        if(!empty($datas)){
            foreach($datas as $key=>$data){
                $color = 0;
                // 1就是有申请解锁的。 绿
                // 2 是解锁未更新 绿
                // 3 是解锁已更新 紫
                $shareGcoPool = SDMHelper::app()->form->getGcoPool($data['form_id']);
                // 申请解锁的原因
                $isWaitingUnlock = $this->LocalService()->redisExtend->getRedisInstance()->hget("UNLOCK_SHARE_FORM:{$data['item_id']}", "{$data['patient_id']}:{$data['checktime_id']}:{$shareGcoPool}");
                if ($isWaitingUnlock) {
                    $color = 1;
                }
                if ($data['is_lock'] == 0) {
                    $status = $this->LocalService()->redisExtend->getRedisInstance()->hGet("SHARE_FORM_IS_UNLOCK_NOT_UPDATED:{$data['item_id']}", "{$data['patient_id']}:{$data['checktime_id']}:{$shareGcoPool}") ? 2 : 0;
                    if (!$status) {
                        $status = $this->LocalService()->redisExtend->getRedisInstance()->hGet("SHARE_FORM_IS_UNLOCK_IS_UPDATED:{$data['item_id']}", "{$data['patient_id']}:{$data['checktime_id']}:{$shareGcoPool}") ? 3 : 0;
                    }
                    $color = $status;
                    unset($status);
                }

                //申请解锁/解锁未更新
                if(in_array($color,[1,2])){
                    $info['unlockNoOperateNum'] += 1;
                }

                //解锁已更新
                if($color == 3){
                    $info['unlockOperateNum'] += 1;
                }

                if(!in_array($data['item_id'],$info['child_item_id']) && (empty($data['is_lock']) || in_array($color,[1,2,3]))){
                    $info['child_item_id'][] = $data['item_id'];
                }

                unset($shareGcoPool);
                unset($isWaitingUnlock);
                unset($color);
                unset($datas[$key]);
            }
        }
        unset($datas);

        return $info;
    }


    /**
     * Notes: 获取人员锁定常规类识别 附件数
     * User: lltyy
     * DateTime: 2024/12/2 8:02
     *
     * @param array $info
     */
    public function getUserImgCount(array $info = []){
        $start_date_time = isset($info['start_date_time']) && !empty($info['start_date_time']) ? $info['start_date_time'] : strtotime(date('Y-m-d').' 00:00:00');
        $end_date_time = isset($info['end_date_time']) && !empty($info['end_date_time']) ? $info['end_date_time'] : strtotime(date('Y-m-d', strtotime('+1 day')).' 00:00:00');
        $item_id_arr = isset($info['item_ids']) && !empty($info['item_ids']) ? $info['item_ids'] : [];
        $info_collect_type_arr = isset($info['info_collect_type']) && !empty($info['info_collect_type']) ? $info['info_collect_type'] : [];
        $where = isset($info['where']) && !empty($info['where']) ? $info['where'] : '';
        $return_type = isset($info['return_type']) && !empty($info['return_type']) ? $info['return_type'] : 0;//返回数据类型 0 人员类型数值 1 人员类型数据
        $arr = [];
        //获取信息
        $where = !empty($where) ? $where : [
            'is_del' => 0,
            'is_lock' => 1,
            new Operator('info_collect_type', Operator::OP_GT, 0),
        ];
        if(!empty($start_date_time) && !empty($end_date_time)){
            $where[] = new Between('update_time', $start_date_time, $end_date_time);
            $where[] = new Operator('update_time', Operator::OP_NE, $end_date_time);
        }
        if(isset($info['info_collect_type'])){
            if(!empty($info_collect_type_arr)){
                $where['info_collect_type'] = $info_collect_type_arr;
            }else{
                $where = [
                    'id' => 0
                ];
            }
        }
        if(isset($info['item_ids'])){
            if(!empty($item_id_arr)){
                $where['item_id'] = $item_id_arr;
            }else{
                $where = [
                    'id' => 0,
                ];
            }
        }

        $datas = $this->fetchAll([
            'where'=>$where,
            'columns'=>['update_time','update_user_id','info_collect_type'],
            'order'=>['id']
        ]);
        unset($where);
        if(!empty($datas)){
            foreach($datas as $dataKey=>$data){
                $data_update = !empty($data['update_user_id']) ? $data['update_user_id'] : 0;
                $data_info_collect_type = !empty($data['info_collect_type']) ? $data['info_collect_type'] : 0;
                $update_add = 0;
                if(!empty($start_date_time) && !empty($end_date_time)) {
                    if (!empty($data_update) && $data['update_time'] >= $start_date_time && $data['update_time'] < $end_date_time) {
                        $update_add = 1;
                    }
                }else {
                    if(!empty($data_update)){
                        $update_add = 1;
                    }
                }
                if($update_add == 1){
                    $arr[$data_update][$data_info_collect_type] = isset($arr[$data_update]) && isset($arr[$data_update][$data_info_collect_type]) && !empty($arr[$data_update][$data_info_collect_type]) ? $arr[$data_update][$data_info_collect_type] : 0;
                    $arr[$data_update][$data_info_collect_type] += 1;
                }else {
                    if($update_add == 1){
                        $arr[$data_update][$data_info_collect_type] = isset($arr[$data_update]) && isset($arr[$data_update][$data_info_collect_type]) && !empty($arr[$data_update][$data_info_collect_type]) ? $arr[$data_update][$data_info_collect_type] : 0;
                        $arr[$data_update][$data_info_collect_type] += 1;
                    }
                }
                unset($update_add);
                unset($data_update);
                unset($datas[$dataKey]);
            }
        }
        unset($datas);

        return $arr;
    }
}
