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

namespace Application\Service\DB\Medical;
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 Matewhite extends \Application\Service\DB\AbstractDb
{
    public function __construct($dbAdapter, ContainerInterface $container)
    {
        $this->tableName = 'yikeen_medical_matewhite';
        parent::__construct($dbAdapter, $container);
    }

    /**
     * Notes: 添加新匹配信息
     * User: llbjj
     * DateTime: 2023/6/9 13:54
     *
     * @param array $params
     */
    public function addNewMateData(array $params) {

        // 删除之前匹配上的指标
        $this->upDelState([
            'ocrdata_id' => $params['ocrdata_id']
        ]);

        $medicalData = $this->LocalService()->medicalOcrdata->fetchOne([
            'where' => [
                'id' => $params['ocrdata_id'],
                'is_del' => 0
            ],
            'columns' => ['id','annex_id', 'itemsig_id', 'patient_id', 'medical_name']
        ]);


        //获取黑/白名单数据
        $wordDatas = $this->LocalService()->dictionaryMedicalword->wordNameData('is_del = 0');
        $white_word_arr = isset($wordDatas['white_word']) && !empty($wordDatas['white_word']) ? $wordDatas['white_word'] : [];

        $addData = [
            'annex_id' => $medicalData['annex_id'],
            'itemsig_id' => $medicalData['itemsig_id'],
            'patient_id' => $medicalData['patient_id'],
            'ocrdata_id' => $medicalData['id'],
            'medical_name' => $medicalData['medical_name'],
            'white_word' => json_encode($white_word_arr,true),
            'mate_white' => json_encode($params['mate_white']),
            'is_del' => 0
        ];

        $this->save($addData);
    }


    /**
     * Notes:获取指定的医嘱名称数据 与 黑/白名单关键字匹配，存入匹配信息表
     * User: lltyy
     * DateTime: 2023/5/26 15:00
     *
     * @param $where//条件
     * @param int $limit
     * @param int $offset
     * @param $white_word_arr//白名单
     * @param array $black_word_arr//黑名单
     * @param array $black_white_word_arr//黑名单下白名单
     * @return int
     */
    public function mateWordData($where,$limit=0,$offset=0,&$white_word_arr,&$black_word_arr=[],&$black_white_word_arr=[],&$drug_arr=[],&$takeDatas=[]){
        //获取指定条件下的医嘱数据
        $medicalCond = [
            'where'=>$where,
            'columns'=>['id','annex_id','itemsig_id','patient_id','medical_name','ocr_start_date','ocr_end_date'],
            'order'=>['id']
        ];
        if(!empty($limit) || !empty($offset)){
            $medicalCond['limit'] = $limit;
            $medicalCond['offset'] = $offset;
        }
        $medicalDatas = $this->LocalService()->medicalOcrdata->fetchAll($medicalCond);
        $last_medical_id = 0;
        if(!empty($medicalDatas)){
            $delete_arr = $delete_mate_arr = [];
            foreach($medicalDatas as $medicalKey=>$medical_info){
                $last_medical_id = $medical_info['id'];
                $medical_info_name = trim($medical_info['medical_name']);
                if(empty($medical_info_name)){
                    $delete_arr[] = $medical_info['id'];
                    unset($medicalDatas[$medicalKey]);
                }
                $delete_mate_arr[] = $medical_info['id'];
            }
            $medicalDatas = array_values($medicalDatas);

            //删除原匹配数据
            $this->LocalService()->medicalOcrdata->update(['mate_type'=>0, 'is_lock'=>0,'drug_id'=>0,'unit_id'=>0,'way_id'=>0,'times_id'=>0,'is_dispensary'=>0],[
                'is_del' => 0,
                'id' => $delete_mate_arr,
            ]);
            $this->upDelState([
                'is_del' => 0,
                'ocrdata_id' => StringHelper::toArray($delete_mate_arr)
            ],1);
            $this->LocalService()->medicalMateblack->upDelState([
                'is_del' => 0,
                'ocrdata_id' => StringHelper::toArray($delete_mate_arr)
            ],1);
            $this->LocalService()->medicalMatedrug->upDelState([
                'is_del' => 0,
                'ocrdata_id' => StringHelper::toArray($delete_mate_arr)
            ],1);
            unset($delete_mate_arr);

            //删除不符合要求的数据
            if(!empty($delete_arr)){
                $this->LocalService()->medicalOcrdata->upDelState([
                    'is_del' => 0,
                    'id' => StringHelper::toArray($delete_arr)
                ],1);
            }
            unset($delete_arr);

            if(!empty($medicalDatas)) {
                $delete_str_arr = ["↑","↓","#","！","~","*","☑","★","◆","。",".","(",")","（","）","?",":","：","√","？","^","<",">","|","、","《","》","，",",","{","}","[","]","【","】","+","--","=","～"];
                foreach ($medicalDatas as $medicalDataKey=>&$medicalData) {
                    $medical_id = $medicalData['id'];
                    $medical_name = trim($medicalData['medical_name']);
                    $mate_medical_name = trim($medicalData['ocr_start_date']).trim($medicalData['medical_name']);
                    $mate_medical_name = str_replace($delete_str_arr,'',$mate_medical_name);
                    $medicalData['mate_medical_name'] = $mate_medical_name;

                    $mate_type = 0;

                    //已匹配上白名单的词
                    $white_word = [];
                    if(!empty($white_word_arr)){
                        foreach($white_word_arr as $white_word_str){
                            if(strpos($mate_medical_name,$white_word_str) !== false){
                                $white_word[] = $white_word_str;
                            }
                        }
                    }
                    if (!empty($white_word)) {
                        //保存匹配白名单数据
                        $save_data = [
                            'annex_id' => $medicalData['annex_id'],
                            'itemsig_id' => $medicalData['itemsig_id'],
                            'patient_id' => $medicalData['patient_id'],
                            'ocrdata_id' => $medical_id,
                            'medical_name' => $medical_name,
                            'white_word' => json_encode($white_word_arr),
                            'mate_white' => json_encode($white_word)
                        ];
                        $matewhite_id = $this->save($save_data);
                        unset($save_data);

                        //已匹配上黑名单的词
                        $black_word = [];
                        if(!empty($black_word_arr)){
                            foreach($black_word_arr as $black_word_str){
                                if(strpos($mate_medical_name,$black_word_str) !== false){
                                    $black_word[] = $black_word_str;
                                }
                            }
                        }
                        if (!empty($black_word)) {
                            //已匹配上黑名单下的白名单词
                            $black_white_word = [];
                            if(!empty($black_white_word_arr)){
                                foreach($black_white_word_arr as $black_white_word_str){
                                    if(strpos($mate_medical_name,$black_white_word_str) !== false){
                                        $black_white_word[] = $black_white_word_str;
                                    }
                                }
                            }
                            if (empty($black_white_word)) {
                                $mate_type = 2;
                                //保存匹配白名单与黑名单匹配数据
                                $save_black = [
                                    'annex_id' => $medicalData['annex_id'],
                                    'itemsig_id' => $medicalData['itemsig_id'],
                                    'patient_id' => $medicalData['patient_id'],
                                    'ocrdata_id' => $medical_id,
                                    'white_id' => $matewhite_id,
                                    'medical_name' => $medical_name,
                                    'black_word' => json_encode($black_word_arr),
                                    'mate_black' => json_encode($black_word)
                                ];
                                $this->LocalService()->medicalMateblack->save($save_black);
                                unset($save_black);
                            } else {
                                $mate_type = 1;
                            }
                            unset($black_white_word);
                        } else {
                            $mate_type = 1;
                        }
                        unset($black_word);
                    }
                    unset($white_word);
                    unset($medical_name_arr);

                    //更新日期
                    $medical_date = trim($medicalData['ocr_start_date']);
                    $medical_date = $this->LocalService()->ocrRawdata->replaceRawdata($medical_date,1);
                    $medical_date = $medical_date != '' ? $medical_date : '';
                    //更新日期
                    $end_date = trim($medicalData['ocr_end_date']);
                    $end_date = $this->LocalService()->ocrRawdata->replaceRawdata($end_date,1);
                    $end_date = $end_date != '' ? $end_date : '';

                    //获取匹配的药物名称
                    $drug_id = $dosage_unit = $dosage_way = $dosage_times = $is_dispensary = 0;
                    if($mate_type == 1){
                        $drug_id = $this->LocalService()->medicalMatedrug->mateDrugdata($medicalData,$drug_arr);

                        if(!empty($drug_id)){
                            //剂量单位
                            if(!empty($takeDatas[1])){
                                foreach($takeDatas[1] as $takeData_one){
                                    if(empty($dosage_unit) && strpos($medical_name,$takeData_one['name']) !== false){
                                        $dosage_unit = $takeData_one['id'];
                                        break;
                                    }
                                    if(empty($dosage_unit) && !empty($takeData_one['english']) && strpos($medical_name,$takeData_one['english']) !== false){
                                        $dosage_unit = $takeData_one['id'];
                                        break;
                                    }
                                }
                            }

                            //给药途径
                            if(!empty($takeDatas[2])){
                                foreach($takeDatas[2] as $takeData_two){
                                    if(empty($dosage_way) && strpos($medical_name,$takeData_two['name']) !== false){
                                        $dosage_way = $takeData_two['id'];
                                        break;
                                    }
                                    if(empty($dosage_way) && !empty($takeData_two['english']) && strpos($medical_name,$takeData_two['english']) !== false){
                                        $dosage_way = $takeData_two['id'];
                                        break;
                                    }
                                }
                            }

                            //给药频率
                            if(!empty($takeDatas[3])){
                                foreach($takeDatas[3] as $takeData_three){
                                    if(empty($dosage_times) && strpos($medical_name,$takeData_three['name']) !== false){
                                        $dosage_times = $takeData_three['id'];
                                        break;
                                    }
                                    if(empty($dosage_times) && !empty($takeData_three['english']) && strpos($medical_name,$takeData_three['english']) !== false){
                                        $dosage_times = $takeData_three['id'];
                                        break;
                                    }
                                }
                            }

                            //出院带药
                            if(!empty($takeDatas[4])){
                                foreach($takeDatas[4] as $takeData_four){
                                    if(empty($is_dispensary) && strpos($medical_name,$takeData_four['name']) !== false){
                                        $is_dispensary = $takeData_four['id'];
                                        break;
                                    }
                                    if(empty($is_dispensary) && !empty($takeData_four['english']) && strpos($medical_name,$takeData_four['english']) !== false){
                                        $is_dispensary = $takeData_four['id'];
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    $this->LocalService()->medicalOcrdata->update(['mate_type' => $mate_type,'medical_date'=>$medical_date,'end_date'=>$end_date,'drug_id'=>$drug_id,'unit_id'=>$dosage_unit,'way_id'=>$dosage_way,'times_id'=>$dosage_times,'is_dispensary'=>$is_dispensary], 'id = ' . $medical_id);
                    unset($medicalDatas[$medicalDataKey]);
                }
            }
        }
        unset($medicalCond);
        unset($medicalDatas);

        return $last_medical_id;
    }

    /**
     * Notes: 获取指定条件下的匹配的数据
     * User: lltyy
     * DateTime: 2023/4/25 10:16
     *
     * @param $where
     * @return array
     */
    public function fetchMedicalMatedata($where,$return_type = 0){
        $datas = [];
        if(empty($return_type)){
            $columns = ['id','ocrdata_id','mate_white'];
        }
        if($return_type == 1){
            $columns = ['id','ocrdata_id'];
        }
        //获取指定条件下的识别结果数据
        $cond = [
            'where'=>$where,
            'columns'=>$columns,
            'order'=>['id']
        ];
        $matedatas = $this->fetchAll($cond);
        if(!empty($matedatas)){
            foreach($matedatas as &$matedata) {
                $medical_id = $matedata['ocrdata_id'];
                if(empty($return_type)) {
                    $mate_white = !empty($matedata['mate_white']) ? json_decode($matedata['mate_white'], true) : [];
                    $datas[$medical_id] = $mate_white;
                }
                if($return_type == 1){
                    $datas[$medical_id] = $matedata['id'];
                }
            }
        }
        unset($cond);
        unset($matedatas);
        return $datas;
    }


    /**
     * Notes:识别医嘱数据 - 匹配
     * User: lltyy
     * DateTime: 2023/5/12 14:51
     *
     */
    public function scanMedical($where='') {
        //获取黑/白名单数据
        $wordDatas = $this->LocalService()->dictionaryMedicalword->wordNameData('is_del = 0');
        $white_word_arr = isset($wordDatas['white_word']) && !empty($wordDatas['white_word']) ? $wordDatas['white_word'] : [];
        $black_word_arr = isset($wordDatas['black_word']) && !empty($wordDatas['black_word']) ? $wordDatas['black_word'] : [];
        $black_white_word_arr = isset($wordDatas['black_white_word']) && !empty($wordDatas['black_white_word']) ? $wordDatas['black_white_word'] : [];
        unset($wordDatas);

        //获取药物数据
        $drugDatas = $this->LocalService()->dictionaryDrug->fetchAll(['where'=>'is_del = 0','columns'=>['id','name','drug_word'],'order'=>['category_type','drug_order']]);
        if(!empty($drugDatas)){
            $delete_str_arr = ["↑","↓","#","！","~","*","☑","★","◆","。",".","(",")","（","）","?",":","：","√","？","^","<",">","|","、","《","》","，",",","{","}","[","]","【","】","+","--","=","～"];
            $delete_name_arr = ['钠注射液','物注射液','颗粒','注射液','注射','胶囊','片'];
            foreach($drugDatas as &$drugData){
                $mate_drug_name = $drugData['name'];
                if(!empty($delete_name_arr)){
                    foreach($delete_name_arr as $delete_name){
                        if(strpos($mate_drug_name,$delete_name) !== false){
                            $delete_index = strpos($mate_drug_name,$delete_name);
                            $mate_drug_name = substr_replace($mate_drug_name,'',$delete_index);
                            unset($delete_index);
                        }
                    }
                }

                $mate_drug_name = mb_substr($mate_drug_name,0,8);
                if(strpos($mate_drug_name,'(') !== false){
                    $delete_index = strpos($mate_drug_name,'(');
                    $mate_drug_name = substr_replace($mate_drug_name,'',$delete_index);
                    unset($delete_index);
                }
                if(strpos($mate_drug_name,'（') !== false){
                    $delete_index = strpos($mate_drug_name,'（');
                    $mate_drug_name = substr_replace($mate_drug_name,'',$delete_index);
                    unset($delete_index);
                }
                $mate_drug_name = str_replace($delete_str_arr,'',$mate_drug_name);
                $mate_drug_word = json_decode($drugData['drug_word'],true);
                $drugData['mate_drug_name'] = $mate_drug_name;
                $drugData['mate_keyword_arr'] = $mate_drug_word;
                unset($drugData['drug_word']);
            }
            unset($delete_str_arr);
            unset($delete_name_arr);
        }

        //获取剂量单位、给药途径、给药频率、出院带药关键词数据
        $takeDatas = [
            1=>[],
            2=>[],
            3=>[],
            4=>[]
        ];
        $allTakeDatas = $this->LocalService()->dictionaryTake->fetchAll(['where'=>'is_del = 0','columns'=>['id','english','name','take_type'],'order'=>['take_order']]);
        if(!empty($allTakeDatas)){
            foreach($allTakeDatas as $allTakeKey=>&$allTakeData) {
                $take_key = $allTakeData['take_type'];
                unset($allTakeData['take_type']);
                $takeDatas[$take_key][] = $allTakeData;
                unset($allTakeDatas[$allTakeKey]);
            }
        }
        unset($allTakeDatas);

        $annex_where = [
            'is_del' => 0,
            'is_lock' => [0, 3],
            'through_process_do_type' => [1, 2, 3],
        ];
        if(empty($where)){
            $where = [
                'is_del' => 0,
                'is_lock' => 0,
            ];
            //$where = 'is_del = 0 and is_lock = 0 and mate_type = 1 and drug_id = 0';
        }

        //匹配黑白名单、药物【5979】
        $sig_id_arr = [];
        if(!empty($sig_id_arr)){
            $where['itemsig_id'] = StringHelper::toArray($sig_id_arr);
            $annex_where['itemsig_id'] = StringHelper::toArray($sig_id_arr);
        }
        //获取附件日期格式
        $annexDateTypeArr = $this->LocalService()->patientFormContentImg->fetchCol('through_process_do_date',$annex_where);

        $bool = true;
        $page = 0;
        $limit = 1000;
        $last_medical_id = 0;
        while ($bool) {
            $page++;
            echo "medicalPAGE {$page}：" . PHP_EOL;
            $last_medical_id = $this->mateWordData(ArrayUtils::merge($where, [
                new Operator('id', Operator::OP_GT, $last_medical_id)
            ]),$limit,0,$white_word_arr,$black_word_arr,$black_white_word_arr,$drugDatas,$takeDatas);
            if(!$last_medical_id) $bool = false;
        }
        unset($white_word_arr);
        unset($black_word_arr);
        unset($black_white_word_arr);
        unset($drugDatas);
        unset($takeDatas);
    }

}