<?php

namespace Application\Controller\item;

use Application\Service\Extension\Helper\EdcHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Common\EventEnum;
use Application\Common\RedisEnum;
use Application\Common\StatusCode;
use Application\Form\item\FormForm;
use Application\Form\item\ItemFormModel;
use Application\Form\item\patient\PatientFormModel;
use Application\Service\DB\Db;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\FormViewFormatter;
use Application\Service\Extension\Formatter\ItemFormFormatter;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\DataHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Uploader\adapter\Oss;
use Application\Service\Extension\Validator\ValidatorApplication;
use Application\Service\Logs;
use Exception;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\Sql\Predicate\In;
use Laminas\Db\Sql\Predicate\Like;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Select;
use Laminas\Db\Sql\Sql;
use Laminas\Json\Json;
use Laminas\View\Model\JsonModel;
use Symfony\Component\ExpressionLanguage\Expression;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\ArrayUtils\MergeRemoveKey;

/**
 * 项目表单
 * 这是字典项表单的子类
 * @author TOOM1996 <1023150697@qq.com>
 */
class FormController extends \Application\Controller\FormController
{
    public const FORM_VALIDATOR = 'ItemForm';
    public const LOG_TARGET = 'ItemForm';
    private function addLog($eventId)
    {
        if (!is_int($eventId)) {
            $eventId = $this->validator->attributes['id'];
            $remark = '编辑项目表单';
            $operate = Logs::OPERATE_EDIT;
        } else {
            $operate = Logs::OPERATE_CREATE;
            $remark = '新增项目表单';
        }

        $this->LocalService()->log->saveFileLog(
            $eventId,
            self::LOG_TARGET . '.form',
            $this->validator->attributes,
            $operate,
            $remark,
            $this->validator->attributes['item_id']
        );
    }

    /**
     * 项目表单列表
     * @actionUrl /item/form
     * @analysis TIMES
     * @return JsonModel
     * @throws Exception
     */
    public function indexAction(): JsonModel
    {
        $this->validator->attach(
            [['item_id'], 'required']
        );
        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        // 表单类型id
        $form_group_id = $this->params()->fromPost('form_group_id', '');
        // 表单tpye
        $form_type = $this->params()->fromPost('form_type', '');
        // 表单检索条件
        $formWhereArr = ['is_del' => 0, 'item_id' => $this->validator->attributes['item_id']];
        if($form_group_id) $formWhereArr['group_id'] = $form_group_id;
        if($form_type !== '') $formWhereArr['type'] = $form_type;

        $data = $this->LocalService()->itemForm->fetchAllWithPagination([
            'columns' => ['id as parent', 'id', 'group_id', 'name', 'type', 'order', 'item_id', 'gco_pool'],
            'order' => ['order ASC'],
            'where' => $formWhereArr
        ]);

        Formatter::format($data['data'], new ItemFormFormatter());

        return $this->RenderApiJson()->Success($data['data'], 'OK', [
            'total' => $data['count']
        ]);
    }

    /**
     * 表单设置 - 表单内容
     * @url http://xxx.com/item/form/create
     * @return JsonModel
     * @throws Exception
     */
    public function createAction(): JsonModel
    {
        $this->validator->setAttributesLabels([
            'group_id' => '表单类型',
            'type' => '类型',
            'is_required' => '是否必填',
            'can_patient_write' => '受试者能否填写',
            'finish_condition' => '完成条件',
            'show_type' => '对齐方式',
        ]);
        $this->validator->attach(
            [[], 'form', 'config' => self::FORM_VALIDATOR],
            [['item_id', 'type', 'is_required', 'can_patient_write', 'finish_condition', 'show_type'], 'required'],
            [['item_id'], 'exist', 'targetClass' => $this->LocalService()->itemInfo, 'targetAttribute' => ['id', 'is_mainitem' => 0]],
//            [['reference_file'], 'required', 'value' => '[]'],
            [['group_id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryFormGroup, 'targetAttribute' => 'id'],
            [['group_id'], 'function', 'targetClass' => FormForm::class, 'method' => 'invalidGroupId'],
            [['name'], 'function', 'targetClass' => FormForm::class, 'method' => 'invalidCreateName'],
            [['checklist_id'], 'function', 'targetClass' => FormForm::class, 'method' => 'invalidCheckListId'],
            [['var_name'], 'function', 'targetClass' => FormForm::class, 'method' => 'validVarName'],
            [['gco_pool'], 'function', 'targetClass' => FormForm::class, 'method' => 'validGcoPool'],
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        //获取表单类型Code值
        $new_group_code = '';
        if(!empty($this->validator->attributes['group_id'])){
            $new_group_code = $this->LocalService()->dictionaryFormGroup->getOneFieldVal('code',[
                'is_del' => 0,
                'id' => $this->validator->attributes['group_id']
            ]);
        }

        //判断该表单下【是否存在开启CS/AE的表单内容】、【是否为常规类介入报告下的病变部位、支架、球囊表单】，存在的话 不可编辑
        if($this->validator->attributes['id']){
            $oldForm = $this->LocalService()->itemForm->fetchOne(['where'=> [
                'id' => $this->validator->attributes['id'],
            ],'columns'=>['name','var_name']]);
            $old_form_name = !is_null($oldForm['name']) && $oldForm['name'] != '' ? $oldForm['name'] : '';
            $old_form_var = !is_null($oldForm['var_name']) && $oldForm['var_name'] != '' ? $oldForm['var_name'] : '';
            $new_form_name = isset($this->validator->attributes['name']) && !is_null($this->validator->attributes['name']) && $this->validator->attributes['name'] != '' ? $this->validator->attributes['name'] : '';
            $new_form_var = isset($this->validator->attributes['var_name']) && !is_null($this->validator->attributes['var_name']) && $this->validator->attributes['var_name'] != '' ? trim($this->validator->attributes['var_name']) : '';
            $startCSAEfield = $this->LocalService()->itemFormField->getCount([
                'is_del' => 0,
                'is_csae' => 1,
                'form_id' => $this->validator->attributes['id']
            ]);
            if(!empty($startCSAEfield)){
                if($old_form_name != $new_form_name || $old_form_var != $new_form_var){
                    return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'该表单下有表单内容已开启CS/AE，不可再编辑表单名称和变量名');
                }
                //获取表单检查项分类ID
                $this->validator->attributes['checklist_id'] = $this->LocalService()->itemCheckname->getOneFieldVal('category_id',[
                    'is_del' => 0,
                    'form_id' => $this->validator->attributes['id']
                ]);
                $this->validator->attributes['checklist_id'] = !empty($this->validator->attributes['checklist_id']) ? $this->validator->attributes['checklist_id'] : 0;
            }

            //是否为常规类介入报告下的病变部位、支架、球囊表单，是的话，变量名不可编辑
            $new_collectcategory = '';
            if(!empty($this->validator->attributes['info_collect_type'])){
                $new_collectcategory = $this->LocalService()->collectCategory->getOneFieldVal('category_code',[
                    'is_del' => 0,
                    'id' => $this->validator->attributes['info_collect_type']
                ]);
            }
            
            if($new_collectcategory == 'InterventionReport' && $new_group_code == 'GCO' && in_array($old_form_var,['JROT','INRB','BAL']) && $new_form_var != '' && $old_form_var != $new_form_var){
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'【介入报告】表单下【病变部位（JROT）、支架（INRB）、球囊（BAL）】的表单变量名为固定信息，不可再编辑！');
            }
            unset($new_collectcategory);
            unset($oldForm);
            unset($old_form_name);
            unset($old_form_var);
            unset($new_form_name);
            unset($new_form_var);
            unset($startCSAEfield);
        }

        //检查类表单只可选择 非【常规识别】类检查项
        if(!empty($this->validator->attributes['checklist_id']) && $new_group_code == 'CHECKCATE'){
            $checkCategoryForm = $this->LocalService()->dictionaryCheckcategory->getOneFieldVal('is_form',[
                'is_del' => 0,
                'id' => $this->validator->attributes['checklist_id']
            ]);
            if($checkCategoryForm == 1){
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'该表单类型只可选择非【常规识别】类检查项表单，请调整所选检查项表单！');
            }
            unset($checkCategoryForm);
        }
        unset($new_group_code);

        $model = new FormForm($this->validator);

        if ($this->validator->attributes['id']) {
            $model->editForm();
            $this->addLog(null);
        } else {
            $this->addLog($model->createForm());
        }

        return $this->RenderApiJson()->Success([]);
    }

    /**
     * 表单设置 - 编辑
     * @actionUrl /item/form/view
     * @return JsonModel
     */
    public function viewAction(): JsonModel
    {
        $validator = new ValidatorApplication();

        $query = $this->LocalService()->itemForm->fetchOne([
            'columns' => [
                new Expression('GCO_pool as gco_pool'), 'id', 'group_id', 'name', 'type', 'order', 'is_required', 'checklist_id', 'finish_condition',
                'is_show', 'is_patient', 'show_type', 'reference_file', 'rdg_type', 'var_name', 'can_patient_write',
                'expression', 'except_checktime', 'is_handwritten_signature', 'ds_stage', 'guide', 'is_using_score', 'is_through_process_do',
                'info_collect_type', 'is_patient_general_info','identification_edit', 'is_export','is_more_sdv'
            ],
            'where' => ['id' => $validator->attributes['id']]
        ]) ?: ['order' => $this->getOrder()];

        Formatter::format($query, new FormViewFormatter());

        //查询检查类（ocr识别）的id
        $group_id_arr = $this->LocalService()->dictionaryFormGroup->fetchCol('id','is_del = 0 and code in ("CHECKCATE","GCO")');
        $group_id_arr = !empty($group_id_arr) ? array_values($group_id_arr) : [];
        //查询项目表单设置下所有的
        $checklist_where = [
            'is_del' => 0,
            new Operator('checklist_id', Operator::OP_GT, 0),
            'group_id' => StringHelper::toArray($group_id_arr),
        ];
        if(!empty($validator->attributes['item_id'])){
            $checklist_where['item_id'] = $validator->attributes['item_id'];
        }

        if(!empty($validator->attributes['id'])){
            $checklist_where[] = new Operator('id', Operator::OP_NE, $validator->attributes['id']);
        }
        $checklistid = $this->LocalService()->itemForm->fetchCol('checklist_id',$checklist_where);
        $checklistid = array_unique($checklistid);
        $FormFileDatas = $this->getFieldConfig(self::FORM_VALIDATOR);
        foreach ($FormFileDatas['form'] as &$formField){
            if($formField['prop'] == 'checklist_id'){
                foreach ($formField['options'] as &$options) {
                    $options['color'] = 'none';
                    if (in_array($options['value'], $checklistid)) {
                        $options['color'] = 'red';
                    }
                }
            }
        }

        return $this->RenderApiJson()->Success($query, 'OK', [
            'FormFileData' => ($FormFileDatas)
        ]);
    }

    protected function getOrder()
    {
        return ($this->LocalService()->itemForm->getCount(['item_id' => $this->validator->attributes['item_id']]) + 1) * 10;
    }

    /**
     * 删除表单
     * @doc https://www.showdoc.com.cn/p/2ed2ef0a8894ed47b8226d6daed08634
     * @return JsonModel
     * @throws Exception
     */
    public function delAction(): JsonModel
    {
        $validator = new ValidatorApplication();
        $this->validator->attach(
            [['id'], 'required'],
            [['id'], 'exist', 'targetClass' => $this->LocalService()->itemForm, 'targetAttribute' => ['id']],
            [['id'], 'function', 'targetClass' => FormForm::class, 'method' => 'invalidDeleteId']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $this->LocalService()->itemForm->update([
            'is_del' => 1
        ], [
            'id' => $validator->attributes['id']
        ]);

        $this->LocalService()->itemFormField->update([
            'is_del' => 1
        ], [
            'form_id' => $validator->attributes['id']
        ]);

        return $this->RenderApiJson()->Success();
    }

    /**
     * 表单的预览
     * @actionUrl /item/form/preview
     * @analysis REQUEST_TIMES,RESPONSE_TIME[max=200]
     */
    public function previewAction()
    {
        $id = $this->params()->fromPost('id');

        // 预览场景
        $viewScenario = $this->params()->fromPost('scenario', 'default');

        if (!$id) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '请传入正确的参数');
        }

        $condition = ['id' => $id];

        if ($viewScenario == Form::SCENARIO_PREVIEW_USING_SCORE) {
            $condition['is_using_score'] = '1';
        }

        $header = [];
        // 逻辑核查返回表头信息
        if ($viewScenario == Form::SCENARIO_PREVIEW_LOGIC_CHECK) {
            $header = $this->getPreviewHeader();
        }
        $query = $this->LocalService()->itemForm->fetchOne([
            'where' => $condition
        ]);

        $groupData = $this->LocalService()->dictionaryFormGroup->fetchOne([
            'where' => ['id' => $query['group_id']]
        ]);

        $this->validator->attributes['form_id'] = $id;
        $model = new PatientFormModel($this->validator);
        $model->contentPrimaryKey = (int)$this->validator->attributes['content_id'];

        $isLock = function() use ($query, $model) {
            if ($query['group_id'] == FormGroup::CHECK_OCR) {
                return $model->getAnnexLock();
            }

            if ($query['group_id'] == FormGroup::NORMAL_OCR) {
                return (bool)Laminas::$serviceManager->patientFormContent->fetchOne([
                        'where' => [
                            'patient_id' => $this->validator->attributes['patient_id'],
                            'form_id' => $this->validator->attributes['form_id'],
                            'checktime_id' => $this->validator->attributes['checktime_id'],
                            'is_del' => 0,
                        ]
                    ])['is_lock'] ?? false;
            }

            return false;
        };

        $isContentLock = function () use ($isLock, $query) {

            if ($query['group_id'] == FormGroup::NORMAL_OCR) {
                $isLock();
            }

            return Laminas::$serviceManager->patientFormLock->getIsLock([
                'form_id' => $this->validator->attributes['form_id'],
                'patient_id' => $this->validator->attributes['patient_id'],
                'item_id' => $this->validator->attributes['item_id'],
                'checktime_id' => $this->validator->attributes['checktime_id'],
                'itemsig_id' => $this->validator->attributes['itemsig_id'],
                'is_del' => 0
            ]);
        };

        $attachConfig = [
            'type' => $viewScenario === Form::SCENARIO_PREVIEW_LOGIC_CHECK && $query['group_id'] == FormGroup::CHECK_OCR ? 0 : $query['type'], // 表单类型 0:一对一; 1:一对多;
            'group_id' => $query['group_id'],
            'expression' => (bool)$query['expression'], // 是否有表单公式
            'group' => $groupData['code'] ?? '', // 表单标识
            'show_type' => $query['show_type'] ?: 'right', // label 显示的样式
            'is_lock' => $isLock(), // ocr类的表单是否锁定
            'is_waiting_unlock' => in_array($query['group_id'], [FormGroup::CHECK_OCR, FormGroup::NORMAL_OCR]) && $model->getAnnexIsWaitingUnlock(), // ocr类的表单是否正在申请解锁
            'is_show_reset_btn' => !($isContentLock === true) && $model->isShowResetBtn(), // 是否展示重置表单按钮 // 锁定的表单不展示重置按钮
            'guide' => $model->getGuide(),
            // 表单内容是否锁了
            // 是不是没用了。。。。
            'is_content_lock' => $isContentLock(),
            'is_using_score' => call_user_func(function () use ($model) {
                return intval($model->getItemFormData()['is_using_score']);
            }),
            'header' => $header ?: [],
            'info_collect_type' => (bool)$query['info_collect_type'],
            'identification_edit' => (int)$query['identification_edit'],

            // 是否失活
            'is_inactive' => call_user_func(function () {
                return array_sum(ArrayHelper::getColumn(Laminas::$serviceManager->patientForm->fetchAll([
                        'where' => [
                            'is_del' => 0,
                            'patient_id' => $this->validator->attributes['patient_id'],
                            'checktime_id' => $this->validator->attributes['checktime_id'],
                            'form_id' => $this->validator->attributes['id']
                ]]), 'is_inactive')) > 0;
            })
        ];


        $attachConfig['is_show_select_btn'] = 0;//是否显示选择病例库附按钮【0 不显示 1 显示】
        $gcoAnnexFieldId = 0;//共享图片表单内容ID
        if ($query['group_id'] == FormGroup::NORMAL_OCR) {//常规类（识别）
            //判断该患者是否为病例库患者
            if(isset($this->validator->attributes['patient_id']) && !empty($this->validator->attributes['patient_id']) && $attachConfig['is_lock'] != 1){
                $collectPatient = $this->LocalService()->patient->getOneFieldVal('collect_patient_id',[
                    'is_del' => 0,
                    'id' => $this->validator->attributes['patient_id'],
                ]);
                $collectPatient = !empty($collectPatient) ? $collectPatient : 0;
                if(!empty($collectPatient)){
                    //获取该表单下共享图片表单内容字段
                    $gcoAnnexFieldId = $this->LocalService()->itemFormField->getOneFieldVal('id',[
                        'is_del' => 0,
                        'form_id' => $id,
                        'type' => FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE
                    ]);
                    if(!empty($gcoAnnexFieldId)){
                        $attachConfig['is_show_select_btn'] = 1;
                    }
                }
                unset($collectPatient);
            }

            $sharePool = ArrayHelper::getColumn(SDMHelper::app()->form->getGcoGroupForm($id), 'id');
            $fields = Laminas::$serviceManager->itemFormField->fetchAll([
                'where' => ['form_id' => $sharePool, 'type' => FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE]
            ]);

            $queryImages = Laminas::$serviceManager->patientFormContentImg->fetchAll([
                'order' => ['id ASC'],
                'where' => ['field_id' => ArrayHelper::getColumn($fields, 'id'), 'patient_id' => $this->validator->attributes['patient_id'], 'is_del' => 0, 'checktime_id' => $this->validator->attributes['checktime_id']]
            ]);


            $r = [];

            foreach ($queryImages as $image) {
                $r[] = [
                    'name' => $image['img_name'],
                    'url' => Oss::getUploadDomain() . $image['img_src'],
                    'collect_annex_id' => $image['collect_annex_id']
                ];
            }
            $attachConfig['share_images'] = $r;
        }

        //获取表单内容对应的项目检查项结果信息
        $fieldItemCheckInfo = [];
        if(isset($this->validator->attributes['item_id']) && !empty($this->validator->attributes['item_id']) && isset($this->validator->attributes['patient_id']) && !empty($this->validator->attributes['patient_id']) && isset($this->validator->attributes['checktime_id']) && !empty($this->validator->attributes['checktime_id']) && isset($this->validator->attributes['form_id']) && !empty($this->validator->attributes['form_id'])){
            $fieldItemCheckInfo = $this->LocalService()->itemFormField->fetchFieldVisitData([
                'item_id'=>$this->validator->attributes['item_id'],
                'patient_id'=>$this->validator->attributes['patient_id'],
                'checktime_id'=>$this->validator->attributes['checktime_id'],
                'form_id'=>$id
            ]);
        }
        return $this->RenderApiJson()->Success(ArrayHelper::merge($attachConfig, call_user_func(function() use ($viewScenario, $id, $isLock, $query,$fieldItemCheckInfo,$gcoAnnexFieldId) {
            $model = $this->LocalService()->itemForm->setLogicErrorId($_POST['error_id'] ?? false)->setPreviewScenario($viewScenario);
            if ($isLock() && $viewScenario === $model::SCENARIO_PREVIEW_LOGIC_CHECK && $query['group_id'] != FormGroup::NORMAL_OCR) {
                $model->renderAnnexLockForm = true;
            }
            $configData = $model->getPreviewConfig($id);
            //登陆人是否有异常值判断的权限 有的话才显示 没有的话不显示这部分信息 也就不能操作
            $roleid_arr        = [];
            $role_id           = 0;
            $user_id           = $this->LocalService()->identity->getId();
            $signatory_user_id = $this->LocalService()->signatoryUser->findsignatoryUser($user_id);
            $module_id         = $this->LocalService()->adminMenu->getOneFieldVal('id', 'is_del = 0 and icon="points"'); //异常值判断菜单ID
            $module_id         = !empty($module_id) ? $module_id : 0;
            //查询role_id
            $item_id = $this->validator->attributes['item_id'];
            $fid     = 0;
            if(!empty($item_id)){
                $fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', 'id=' . $item_id);
            }
            if (!empty($fid)) {
                $item_id = $fid;
            }
            if(!empty($signatory_user_id) && !empty($this->validator->attributes['itemsig_id']) && !empty($module_id)){
                $role_where = [
                    'is_del' => 0,
                    'item_id' => $item_id,
                    'signatory_user' => $signatory_user_id,
                    'item_sign_id' => $this->validator->attributes['itemsig_id'],
                ];
                $role_id = $this->LocalService()->roleSignatoryRelation->getOneFieldVal('role_id',$role_where);
                $role_id = !empty($role_id) ? $role_id : 0;
                $roleid_arr = $this->LocalService()->realRolemodulerelation->fetchCol('role_id',[
                    'module_id' => $module_id,
                    'look_write' => 1,
                ]);
            }

            if(!empty($roleid_arr) && in_array($role_id,$roleid_arr)){ //有异常值判断的操作权限才可显示数据并操作
                //查询化验单指标信息
                $resultchangeDatas = $this->getResultchange($this->validator->attributes['error_id'],$this->validator->attributes['patient_id'],$this->validator->attributes['checktime_id']);
                $resultchangeDatas = !empty($resultchangeDatas) ? $resultchangeDatas : [];
                $configData['resultchange'] = $resultchangeDatas;
            }
            // 质疑沟通需要加一个参数
            if ($viewScenario == 'question' && $configData) {
                $pushIsCheck = function (&$item) {
                    foreach ($item as &$value) {
                        if (!isset($value['prop'])) {
                            foreach ($value as &$vum) {
                                $vum['is_check'] = false;
                                $vum['disabled'] = true;
                            }
                        } else {
                            $value['is_check'] = false;
                            $value['disabled'] = true;
                        }
                    }
                };

                foreach ($configData as &$config) {
                    $pushIsCheck($config);
                }
            }

            //表单内容名称后增加对应检查项及结果显示
            $configData['gco_img_field_prop'] = '';//共享病例库附件表单内容字段
            $is_show_abnormalJudgeField = 0;//是否展示异常判断表结构
            if(!empty($configData)){

                foreach($configData as $configKey=>$configDataInfo){
                    if(is_array($configDataInfo) && !empty($configDataInfo)){
                        if($configKey == 'form'){
                            foreach($configDataInfo as $formKey=>$formField){
                                if(isset($formField['field_id'])) {
                                    $configData[$configKey][$formKey]['visitInfo'] = [];
                                    if (isset($fieldItemCheckInfo[$formField['field_id']]) && !empty($fieldItemCheckInfo[$formField['field_id']])) {
                                        $configData['form'][$formKey]['visitInfo'] = $fieldItemCheckInfo[$formField['field_id']];
                                        // 匹配
                                        $defVal = $model->pregLabel($formField['field_id']);
                                        // 防止数据类型不匹配的问题
                                        if ($defVal) {
                                            $configData['form'][$formKey]['default'] = $model->pregLabel($formField['field_id']);
                                        }
                                        unset($defVal);
                                    }
                                    if($formField['field_id'] == $gcoAnnexFieldId && !empty($gcoAnnexFieldId)){
                                        $configData['gco_img_field_prop'] = isset($formField['prop']) && !empty($formField['prop']) ? $formField['prop'] : '';//共享病例库附件表单内容字段
                                    }
                                    if(isset($formField['is_csae']) && $formField['is_csae'] == 1){
                                        $is_show_abnormalJudgeField = 1;
                                    }
                                }
                            }
                        }else{
                            foreach($configDataInfo as $formKey1=>$formFields){
                                if(is_array($formFields) && !empty($formFields)){
                                    foreach($formFields as $formFieldKey=>$formFieldInfo){
                                        if(isset($formFieldInfo['field_id'])){
                                            $configData[$configKey][$formKey1][$formFieldKey]['visitInfo'] = [];
                                            if(isset($fieldItemCheckInfo[$formFieldInfo['field_id']]) && !empty($fieldItemCheckInfo[$formFieldInfo['field_id']])){
                                                $configData[$configKey][$formKey1][$formFieldKey]['visitInfo'] = $fieldItemCheckInfo[$formFieldInfo['field_id']];
                                                // 匹配
                                                $defVal1 = $model->pregLabel($formFieldInfo['field_id']);
                                                // 防止数据类型不匹配的问题
                                                if ($defVal1) {
                                                    $configData[$configKey][$formKey1][$formFieldKey]['default'] = $model->pregLabel($formFieldInfo['field_id']);
                                                }
                                                unset($defVal1);
                                            }
                                            if($formFieldInfo['field_id'] == $gcoAnnexFieldId && !empty($gcoAnnexFieldId)){
                                                $configData['gco_img_field_prop'] = isset($formFieldInfo['prop']) && !empty($formFieldInfo['prop']) ? $formFieldInfo['prop'] : '';//共享病例库附件表单内容字段
                                            }
                                            if(isset($formFieldInfo['is_csae']) && $formFieldInfo['is_csae'] == 1){
                                                $is_show_abnormalJudgeField = 1;
                                            }

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //增加异常判断表结构
            $configData['childForm'] = [];
            if($is_show_abnormalJudgeField == 1){
                $normalTypeForm = [
                    'type'=>'Radio',
                    'label'=>'异常值判断',
                    'placeholder'=>'请选择异常值判断',
                    'radios' => [
                        [
                            'label' => '正常',
                            'value' => '1'
                        ],
                        [
                            'label' => 'CS',
                            'value' => '2'
                        ],
                        [
                            'label' => 'NCS',
                            'value' => '3'
                        ]
                    ],
                    'prop'=>'normal_type'
                ];
                if($isLock() || (!$isLock() && $viewScenario != 'previewShareFormUnlock')){
                    $normalTypeForm['disabled'] = true;
                }
                $configData['childForm'] = [$normalTypeForm];
                unset($normalTypeForm);
            }
            // 生成表单令牌 存储进redis 设置过期时间
            $only_keys1 = bin2hex(random_bytes(32));
            $only_keys2 = bin2hex(random_bytes(32));
            $redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
            $redis->setex($only_keys1,3600,1);   //一小时
            $redis->setex($only_keys2,3600,1);   //15分钟
            $configData['only_keys1'] = $only_keys1;
            $configData['only_keys2'] = $only_keys2;
            unset($is_show_abnormalJudgeField);
            return $configData;
        })));
        unset($fieldItemCheckInfo);
        unset($gcoAnnexFieldId);
    }

    /**
     * Notes: 查询指标信息
     * @param
     * @return
     * @author haojinhua
     * @date 2024-08-29
     */
    public function getResultchange($error_id,$patient_id,$checktime_id){
        //echo $error_id.'=='.$patient_id.'=='.$checktime_id;die;
        $resultchangeDatas = [];
        if(!empty($error_id) && !empty($patient_id) && !empty($checktime_id)){
            //查询prop字段
            $prop = $this->LocalService()->itemPatientFormLogicErrorPointer->getOneFieldVal('prop',[
                'error_id' => $error_id,
                'patient_id' => $patient_id,
                'checktime_id' => $checktime_id,
            ]);
            //查询multi_id字段 查询对应指标
            $multi_id = $this->LocalService()->itemPatientFormLogicErrorPointer->getOneFieldVal('multi_id',[
                'error_id' => $error_id,
                'patient_id' => $patient_id,
                'checktime_id' => $checktime_id,
            ]);
            $multi_id = !empty($multi_id) ? $multi_id : 0;
            if(!empty($prop)){
                $n_prop = explode('-',$prop);
                if(in_array('normal_type',$n_prop)){
                    $form_filed_id = !empty($n_prop[0]) ? $n_prop[0] : 0;
                    $item_checkname_id = $this->LocalService()->itemCheckname->getOneFieldVal('id',[
                        'form_filed_id' => $form_filed_id,
                        'is_del' => 0,
                    ]);
                    $change_where['where'] = [
                        'item_checkname_id' => $item_checkname_id,
                        'patientformcontent_id' => $multi_id,
                        'is_del' => 0,
                    ];
                }else{
                    if(!empty($multi_id)){
                        $change_where['where'] = [
                            'id' => $multi_id,
                        ];
                    }
                }
            }
            // 修复$change_where没有值会报错的问题
            if (!$change_where) {
                return;
            }
            $resultchangeDatas = $this->LocalService()->itemIdentificationresultchange->fetchOne($change_where);
            //print_r($resultchangeDatas);die;
            if(!empty($resultchangeDatas)){
                $checktimeId = $resultchangeDatas['checktime_id'];
                $checkNameInfo = $this->LocalService()->itemChecktime->fetchOne(['where'=> [
                    'is_del' => 0,
                    'id' => $checktimeId,
                ]]);
                $is_del = !empty($checkNameInfo) ? $checkNameInfo['is_del']: 0;
                if($is_del == 9){
                    $check_name = $this->LocalService()->itemPatientchecktime->getpatientTestsummaryNam($resultchangeDatas['patient_id']);
                }else{
                    $check_name = !empty($checkNameInfo) ? $checkNameInfo['check_name']: 0;
                }
                $resultchangeDatas['check_name'] = $check_name;
                $resultchangeDatas['item_min_val'] = $resultchangeDatas['reference_range_min'];
                $resultchangeDatas['item_max_val'] = $resultchangeDatas['reference_range_max'];
                $resultchangeDatas['up_annex_date'] = !empty($resultchangeDatas['collect_date']) ? date('Y-m-d',$resultchangeDatas['collect_date']) : '';
            }

        }
        $resultchangeDatas = !empty($resultchangeDatas) ? $resultchangeDatas : [];

        return $resultchangeDatas;
    }

    /**
     * 逻辑核查预览header
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    private function getPreviewHeader(): array
    {
        $sql = new Sql(Laminas::$app->getServiceManager()->get('dbAdapter'));
        $select = (new Select())
            ->from(['s' => Laminas::$serviceManager->itemSignatory->getTableName()])
            ->join(['i' => Laminas::$serviceManager->signatoryInfo->getTableName()], 'i.id = s.signatory_id', ['info_name'], Select::JOIN_LEFT)
            ->where([
                's.id' => $this->validator->attributes['itemsig_id']
            ]);

        $statement = $sql->prepareStatementForSqlObject($select);
        $resultSet = new ResultSet();
        $resultSet->initialize($statement->execute())->toArray();

        $signName = $resultSet->initialize($statement->execute())->toArray()[0]['info_name'] ?? '';

        return [
            'item_name' => Laminas::$serviceManager->itemInfo->fetchOne(['where' => ['id' => $this->validator->attributes['item_id']]])['name'] ?? '',
            'sign_name' => $signName,
            'checktime_name' => Laminas::$serviceManager->itemChecktime->fetchOne(['where' => ['id' => $this->validator->attributes['checktime_id']]])['check_name'] ?? '',
            'patient_name' => call_user_func(function () {
                $query = Laminas::$serviceManager->patient->fetchOne(['where' => ['id' => $this->validator->attributes['patient_id']]]);
                $isHide = Laminas::$serviceManager->patientattrs->fetchOne([
                    'where' => ['item_id' => $this->validator->attributes['item_id'], 'attr_field' => 'name']
                ])['is_hide'];
                return ("【{$query['patient_number']}】 " . ($isHide ? '' : $query['patient_name'])) ?? '';
            }),
        ];
    }

    /**
     * 获取脱离表单配置
     * @url xxx.com/v1/item/form/outPreview
     * @return JsonModel
     * @throws Exception
     */
    public function outPreviewAction(): JsonModel
    {
        $this->validator->attach(
            [['item_id'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $model = new ItemFormModel($this->validator);

        return $this->RenderApiJson()->Success($model->getOutFormPreview());
    }

    /**
     * 获取脱离表单配置V2, 现在必须多传递一个受试者状态。用来填写不同的表单。
     * @url xxx.com/v2/item/form/outPreview
     * @return JsonModel
     * @throws Exception
     */
    public function outPreviewV2Action(): JsonModel
    {
        $this->validator->attach(
            [['item_id', 'patient_status', 'patient_id'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $model = new ItemFormModel($this->validator);

        return $this->RenderApiJson()->Success($model->getOutFormPreview('v2'));
    }


    /**
     * 提交脱落数据
     * @url xxx.com/v1/item/form/createOutForm
     * @return JsonModel
     * @throws Exception
     */
    public function createOutFormAction(): JsonModel
    {
        $this->validator->attach(
            [['patient_id', 'item_id', 'form_id'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        Db::beginTransaction();

//            Laminas::$serviceManager->patientFormContent->save($condition);
        $this->validator->attributes['checktime_id'] = $this->LocalService()->itemChecktime->getOutCheckTimeId($this->validator->attributes['item_id']);

        $postData = DataHelper::handleFormData($this->validator->attributes, $this->params()->fromPost('form_id'));
        // 修改表单完成状态
        $model = new PatientFormModel($this->validator);
        $model->setScenario($model::SCENARIO_OUT_FORM);

        // 删除数据
        if (
            isset($this->validator->attributes['is_del']) &&
            isset($this->validator->attributes['id']) &&
            $this->validator->attributes['is_del'] == 1
        ) {
            if ($model->getAnnexLock() === true) {
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '删除失败。当前表单已被锁定。');
            }

            // 判断的是主项目是否开启edc
            if (EdcHelper::isEdc(SDMHelper::app()->item->getFid($this->validator->attributes['item_id'])) && SDMHelper::app()->setAttributes(['content_id' => $this->validator->attributes['id']])->formContent->getIsEdcLock()) {
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '当前试验总结类表单已在edc被锁定，无法删除!');
            }

            // 修改表单完成状态
            $content = Laminas::$serviceManager->patientFormContent->fetchOne([
                'where' => ['id' => $this->validator->attributes['id']]
            ]);
            $this->delete();
            //记录删除日志
            $model->logger->setEvent(EventEnum::EVENT_FORM_CONTENT_FLUSH)->setPostOriginData($content)->setPostData($this->validator->attributes)->setContentId($this->validator->attributes['id'])->flush();
            Db::commit();
            
            //异步处理访视进度情况信息
            Laminas::$serviceManager->swTaskClient->send([
                'svName' => 'projectPatientworkbatch',
                'methodName' => 'multipleUpdateData',
                'params' => [
                    'item_id' => $this->validator->attributes['item_id'],
                    'patient_id' => $this->validator->attributes['patient_id'],
                    'checktime_id' => $this->validator->attributes['checktime_id'],
                    'form_id' => $this->validator->attributes['form_id'],
                    'operate_type'=>12,
                    'content_id'=>!empty($this->validator->attributes['id']) ? [$this->validator->attributes['id']] : [],
                    'user_id' => Laminas::$serviceManager->identity->getId()
                ]
            ]);
            return $this->RenderApiJson()->Success();
        }

        $reason = $this->validator->attributes['reason'];
        if(!empty($reason)){
            $reason_res = [];
            $reason_datas = json_decode($reason,true);
            foreach ($reason_datas as $reason_data){
                $reason_res[] = [
                    'filed_id'=>$reason_data['filed_id'],
                    'modify_reason'=>$reason_data['modify_reason'],
                ];
            }
            unset($reason_datas);
            $reason = json_encode($reason_res,true);
        }
        $postData['note'] = $reason;
        unset($postData['reason']);
        if ($this->validator->attributes['id']) {
            $model->editForm($postData);
        } else {
            $model->createForm($postData);
        }

        Db::commit();
        return $this->RenderApiJson()->Success();

    }

    private function delete()
    {
        Laminas::$serviceManager->patientFormContent->update(['is_del' => 1], ['id' => $this->validator->attributes['id']]);
        Laminas::$serviceManager->itemPatientworkannex->update(['is_del' => 1], [
            'form_id' => $this->validator->attributes['form_id'],
            'item_id' => $this->validator->attributes['item_id'],
            'patient_id' => $this->validator->attributes['patient_id'],
            'itemsig_id' => $this->validator->attributes['itemsig_id'],
        ]);
        Laminas::$serviceManager->itemIdentificationresultchange->update(['is_del' => 1], [
            'form_id' => $this->validator->attributes['form_id'],
            'item_id' => $this->validator->attributes['item_id'],
            'patient_id' => $this->validator->attributes['patient_id'],
            'itemsig_id' => $this->validator->attributes['itemsig_id'],
        ]);

        $error_where = [
            'is_del' => 0,
            'form_id' => $this->validator->attributes['form_id'],
            'item_id' => $this->validator->attributes['item_id'],
            'patient_id' => $this->validator->attributes['patient_id'],
            'checktime_id' => $this->validator->attributes['checktime_id'],
        ];
        //关闭质疑
        $errors = Laminas::$serviceManager->itemPatientFormLogicError->fetchAll([
            'where'=>$error_where,
        ]);
        if(!empty($errors)){
            foreach ($errors as $error) {
                SDMHelper::app()->logic->setQuery('数据已移除', $error['id'], $this->validator->attributes['item_id']);
                SDMHelper::app()->logic->closeError($error['id']);
            }
        }
    }

    public function viewOutFormAction(): JsonModel
    {
        $this->validator->attach(
            [['patient_id', 'item_id', 'form_id'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $outCheckTimeId = $this->LocalService()->itemChecktime->getOutCheckTimeId($this->validator->attributes['item_id']);

        if (!$outCheckTimeId) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '未找到对应的受试者状态检查点.');
        }

        $data = $this->LocalService()->patientFormContent->fetchOne([
                'columns' => ['data', 'id'],
                'where' => [
                    'patient_id' => $this->validator->attributes['patient_id'],
                    'item_id' => $this->validator->attributes['item_id'],
                    'form_id' => $this->validator->attributes['form_id'],
                    'is_del' => 0,
                    'checktime_id' => $outCheckTimeId
                ]
            ]) ?? [];

        // 生成表单令牌 存储进redis 设置过期时间
        $only_keys1 = bin2hex(random_bytes(32));
        $redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
        $redis->setex($only_keys1,3600,1);
        if ($data) {
            $attach = StringHelper::jsonDecode($data['data']);

            $attach['id'] = $data['id'];
            $attach['is_complete'] = (new ItemFormModel($this->validator))->getIsComplete($this->validator->attributes['form_id'], $this->LocalService()->itemChecktime->getOutCheckTimeId($this->validator->attributes['item_id']));
            $attach['status_color'] = (intval($attach['is_complete']) ? 1 : 3);

            foreach ($attach as $field => &$v) {
                if (stripos($v, '[') !== false) {
                    $v = json_decode($v, true);
                }

                if (stripos($field, 'attach') !== false) {
                    if (!$v) {
                        $v = '[]';
                    }
                }
            }
            unset($data['data']);
            unset($attach['old_data_str']);
            unset($attach['sdtx']);
            return $this->RenderApiJson()->Success(ArrayHelper::merge($data, $attach),'OK',['only_keys1' => $only_keys1]);
        }

        return $this->RenderApiJson()->Success($data,'OK',['only_keys1' => $only_keys1]);
    }

    public function viewOutFormV2Action(): JsonModel
    {
        $this->validator->attach(
            [['patient_id', 'item_id', 'form_id', 'patient_status'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $data = $this->LocalService()->patientFormContent->fetchOne([
                'columns' => ['data', 'id'],
                'where' => [
                    'patient_id' => $this->validator->attributes['patient_id'],
                    'item_id' => $this->validator->attributes['item_id'],
                    'form_id' => $this->validator->attributes['form_id'],
                    'is_del' => 0
                ]
            ]) ?? [];

        if ($data) {
            $attach = json_decode($data['data'], true);
            $attach['id'] = $data['id'];

            foreach ($attach as $field => &$v) {
                if (stripos($v, '[') !== false) {
                    $v = json_decode($v, true);
                }

                if (stripos($field, 'attach') !== false) {
                    if (!$v) {
                        $v = '[]';
                    }
                }
            }
            unset($data['data']);
            unset($attach['old_data_str']);
            return $this->RenderApiJson()->Success(ArrayHelper::merge($data, $attach));
        }

        return $this->RenderApiJson()->Success();
    }

    /**
     * 获取单个id表单数据
     * @url xxx.com/v1/item/form/detail
     * @return JsonModel
     * @throws Exception
     */
    public function detailAction(): JsonModel
    {
        if(!$this->validator->attributes['form_id']) {
            // 未传递表单id，则通过content获取对应的form_id
            $this->validator->attributes['form_id'] = $this->LocalService()->patientFormContent->getOneFieldVal('form_id', [
                'id' => $this->validator->attributes['id']
            ]);
        }

        $model = new PatientFormModel();
        $model->setPostValues($this->validator->attributes);

        $data = [];
        if ($this->validator->attributes['id'] < 100 && $this->validator->attributes['id'] != '') {
            // 识别类的一对多
            $key = RedisEnum::PATIENT_FORM_TEMP_STORAGE . md5("{$this->validator->attributes['patient_id']}{$this->validator->attributes['checktime_id']}{$this->validator->attributes['form_id']}");
            $val = StringHelper::jsonDecode(Laminas::$serviceManager->redisExtend->getRedisInstance()->lRange($key, $this->validator->attributes['id'] - 1, $this->validator->attributes['id'] + 1)[0], true);
            $val['data']['id'] =  intval($this->validator->attributes['id']);
            $data = $val['data'];
        } else {
            //判断表单是否是AE表单
            $formGroup = Laminas::$serviceManager->itemForm->getOneFieldVal('group_id',"id = ".$this->validator->attributes['form_id']);
            $content = [];
            if($formGroup == 5){
                $content = Laminas::$serviceManager->itemPatientAeContent->fetchOne([
                    'where' => ['id' => $this->params()->fromPost('id')]
                ]);
            }
            $data = $model->viewById($this->params()->fromPost('id'),$content);
        }
        if ($data) {
            $data['childData'] = isset($data['childData']) && !empty($data['childData']) ? StringHelper::jsonDecode($data['childData'],true) : [];
            if(!empty($data['childData'])){
                //获取该表单锁定状态
                $contentLockState = $this->LocalService()->patientFormContent->getOneFieldVal('is_lock',[
                    'is_del' => 0,
                    'patient_id' => $this->validator->attributes['patient_id'],
                    'checktime_id' => $this->validator->attributes['checktime_id'],
                    'form_id' => $this->validator->attributes['form_id']
                ]);

                //获取 patientFormContent 表的ID
                $patient_formcontent_id = 0;
                if(!empty($contentLockState)){
                    if(isset($data['id']) && !empty(isset($data['id']))){
                        $patient_formcontent_id = $data['id'];
                    }
                }else{
                    if(isset($data['content_id']) && !empty($data['content_id'])){
                        $patient_formcontent_id = $data['content_id'];
                    }
                }

                $patientInfo = Laminas::$serviceManager->patient->fetchOne(['where'=> [
                    'id' => $this->validator->attributes['patient_id'],
                ],'columns'=>['item_id','itemsig_id']]);
                $this->validator->attributes['item_id'] = !empty($patientInfo) ? $patientInfo['item_id'] : 0;
                $this->validator->attributes['itemsig_id'] = !empty($patientInfo) ? $patientInfo['itemsig_id'] : 0;
                $aeResults = Laminas::$serviceManager->itemCsae->fetchCheckFieldAeData([
                    'item_id'=>$this->validator->attributes['item_id'],
                    'itemsig_id'=>[$this->validator->attributes['itemsig_id']],
                    'patient_id'=>[$this->validator->attributes['patient_id']],
                    'form_id'=>[$this->validator->attributes['form_id']],
                    'type'=>1
                ]);
                $aeResultArr = isset($aeResults[$patient_formcontent_id]) && !empty($aeResults[$patient_formcontent_id]) ? $aeResults[$patient_formcontent_id] : [];
                unset($patientInfo);
                unset($aeResults);

                //===========有质疑可以编辑异常值判断===============
                $childerrorDatas = [];
                if(!empty($patient_formcontent_id)){
                    $childerror = $this->LocalService()->itemPatientFormLogicErrorPointer->fetchAll([
                        'where'=> [
                            'multi_id' => $patient_formcontent_id,
                        ],
                        'columns'=>['error_id','prop']
                    ]);
                    $childerrorDatas = ArrayHelper::index($childerror,'prop');
                }
                //===========*有质疑可以编辑异常值判断===============

                foreach($data['childData'] as $data_judge_key=>$data_judge){
                    $data_judge_field = isset($data_judge['field_id']) && !empty($data_judge['field_id']) ? $data_judge['field_id'] : 0;
                    if(empty($data_judge_field) && strpos($data_judge_key, "-") === false){
                        $data_judge_field = $data_judge_key;
                    }
                    $data['childData'][$data_judge_key]['field_id'] = $data_judge_field;
                    $data['childData'][$data_judge_key]['normal_type'] = !empty($data_judge['normal_type']) ? $data_judge['normal_type'] : '';
                    $data['childData'][$data_judge_key]['parentProp'] = $data_judge_key;
                    $data['childData'][$data_judge_key]['aeResultList'] = [];
                    if($data_judge['normal_type'] == 2){
                        $data['childData'][$data_judge_key]['aeResultList'] = isset($aeResultArr[$data_judge_field]) && isset($aeResultArr[$data_judge_field]['show_ae']) && !empty($aeResultArr[$data_judge_field]['show_ae']) ? $aeResultArr[$data_judge_field]['show_ae'] : [];
                    }
                    $data['childData'][$data_judge_key]['disabled'] = false;
                    if(!empty($childerrorDatas) && (isset($childerrorDatas[$data_judge_key]) || isset($childerrorDatas[$data_judge_key.'-normal_type']))){
                        if($model->scenario === 'progressManage'){
                            $data['childData'][$data_judge_key]['disabled'] = true;
                        }else{
                            $index_id = isset($childerrorDatas[$data_judge_key.'-normal_type']['error_id']) ? $childerrorDatas[$data_judge_key.'-normal_type']['error_id'] : 0;
                            $errorResult = $this->LocalService()->itemPatientFormLogicError->getOneFieldVal('id',[
                                'is_closed' => 0,
                                'id' => $index_id,
                            ]);
                            $data['childData'][$data_judge_key]['disabled'] = $errorResult  ? false : true;
                        }

                    }else{
                        if($model->scenario === 'progressManage'){
                            $data['childData'][$data_judge_key]['disabled'] = true;
                        }else{
                            $data['childData'][$data_judge_key]['disabled'] = !empty($contentLockState) ? true : false;
                        }

                    }
                    unset($data_judge_field);

                }
                unset($aeResultArr);
                unset($contentLockState);
                unset($patient_formcontent_id);
            }
        }

        // 生成表单令牌 存储进redis 设置过期时间
        $only_keys1 = bin2hex(random_bytes(32));
        $redis = Laminas::$serviceManager->redisExtend->getRedisInstance();
        $redis->setex($only_keys1,3600,1);   //一小时
        return $this->RenderApiJson()->Success($data,'OK',[
            'annexData' => $model->getAnnexData(),
            'report_type' => call_user_func(function () use ($model) {
                $categoryId = $model->getItemFormData()['checklist_id'] ?? false;
                return $model->getReportType($categoryId);
            }),
            'change_lock' => $model->getAnnexLock(),
            'only_keys1'=>$only_keys1
        ]);
    }



    public function getannexdataAction()
    {
        if(!$this->validator->attributes['form_id']) {
            // 未传递表单id，则通过content获取对应的form_id
            $this->validator->attributes['form_id'] = $this->LocalService()->patientFormContent->getOneFieldVal('form_id', [
                'id' => $this->validator->attributes['id']
            ]);
        }
        $model = new PatientFormModel();
        $model->setPostValues($this->validator->attributes);
        $model->contentPrimaryKey = $this->validator->attributes['id'];
        $annexData = $model->getAnnexData();

        return $this->RenderApiJson()->Success($annexData,'OK',[
            'report_type' => call_user_func(function () use ($model) {
                $categoryId = $model->getItemFormData()['checklist_id'] ?? false;
                return $model->getReportType($categoryId);
            }),
            'change_lock' => $model->getAnnexLock(),
        ]);
    }

    public function getanneximgAction()
    {
        $content_id = $this->validator->attributes['id'];

        $anneximgDatas = $this->LocalService()->itemPatientworkannex->fetchAll([
            'where'=>['is_del'=>0,'formcontent_id'=>$content_id],
            'columns'=>['annex_title','annex_path']
        ]);

        foreach ($anneximgDatas as $k=>&$v){
            $v['annex_path'] = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/common/showPic?path='.$v['annex_path'];
        }
        return $this->RenderApiJson()->Success($anneximgDatas,'OK');
//        if(!$this->validator->attributes['form_id']) {
//            // 未传递表单id，则通过content获取对应的form_id
//            $this->validator->attributes['form_id'] = $this->LocalService()->patientFormContent->getOneFieldVal('form_id', [
//                'id' => $this->validator->attributes['id']
//            ]);
//        }
//
//        $model = new PatientFormModel();
//        $model->setPostValues($this->validator->attributes);
//
//
//        $content = [];
//        $data = $model->viewById($this->params()->fromPost('id'),$content);
//
//        $version = $this->LocalService()->itemForm->getPreviewConfig($this->validator->attributes['form_id'],true);

    }

    /**
     * 表单数据锁定, 用于edc同步
     * @url xxx.com/v1/item/form/lock
     */
    public function lockAction(): JsonModel
    {
        $this->validator->attach(
            [['form_id', 'patient_id', 'item_id', 'itemsig_id', 'checktime_id', 'content_id', 'is_ae'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }
        // 判断的是主项目是否开启edc
        if (EdcHelper::isEdc(SDMHelper::app()->item->getFid($this->validator->attributes['item_id'])) && SDMHelper::app()->setAttributes(['content_id' => $this->validator->attributes['content_id']])->formContent->getIsEdcLock()) {
            throw new InvalidArgumentException('此表单在EDC已锁定, 无法提交。');
        }
        $conditions = [
            'form_id' => $this->validator->attributes['form_id'],
            'patient_id' => $this->validator->attributes['patient_id'],
            'item_id' => $this->validator->attributes['item_id'],
            'itemsig_id' => $this->validator->attributes['itemsig_id'],
            'checktime_id' => $this->validator->attributes['checktime_id'],
            'content_id' => $this->validator->attributes['content_id'],
            'is_ae' => $this->validator->attributes['is_ae']
        ];

        $content = Laminas::$serviceManager->patientFormContent->fetchOne([
            'where' => ['id' => $this->validator->attributes['content_id']]
        ]);

        if ($content['is_del'] == 1) {
            throw new InvalidArgumentException('当前表单已删除，操作无效。');
        }

        Laminas::$serviceManager->patientFormContent->lock($this->validator->attributes['content_id']);

        $isLock = Laminas::$serviceManager->patientFormLock->fetchOne([
            'where' => $conditions
        ]);

        if ($isLock) {
            $conditions['is_del'] = 0;
            $conditions['id'] = $isLock['id'];
        }

        Laminas::$serviceManager->patientFormLock->save($conditions);

        //异步处理访视进度情况信息
        $form_content_arr = [$this->validator->attributes['content_id']];
        Laminas::$serviceManager->swTaskClient->send([
            'svName' => 'projectPatientworkbatch',
            'methodName' => 'multipleUpdateData',
            'params' => [
                'item_id' => $this->validator->attributes['item_id'],
                'itemsig_id' => $this->validator->attributes['itemsig_id'],
                'patient_id' => $this->validator->attributes['patient_id'],
                'checktime_id' => $this->validator->attributes['checktime_id'],
                'form_id' => $this->validator->attributes['form_id'],
                'operate_type'=>11,
                'content_id'=>!empty($form_content_arr) ? $form_content_arr : [],
                'user_id' => Laminas::$serviceManager->identity->getId()
            ]
        ]);
        unset($form_content_arr);

        return $this->RenderApiJson()->Success();
    }

    /**
     * 表单数据解锁, 用于edc同步
     * @url xxx.com/v1/item/form/unlock
     */
    public function unlockAction()
    {
        $this->validator->attach(
            [['form_id', 'patient_id', 'item_id', 'itemsig_id', 'checktime_id'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $model = new PatientFormModel($this->validator);

        $lockId = $model->getPatientFormLockData()['id'] ?? false;
        $contentId = $model->getPatientFormLockData()['content_id'] ?? 0;

        if (!$lockId) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '这个表单没锁定把');
        }

        Laminas::$serviceManager->patientFormLock->update(['is_del' => 1], ['id' => $lockId]);

        //异步处理访视进度情况信息
        
        $form_content_arr = !empty($contentId) ? [$contentId] : [];
        Laminas::$serviceManager->swTaskClient->send([
            'svName' => 'projectPatientworkbatch',
            'methodName' => 'multipleUpdateData',
            'params' => [
                'item_id' => $this->validator->attributes['item_id'],
                'itemsig_id' => $this->validator->attributes['itemsig_id'],
                'patient_id' => $this->validator->attributes['patient_id'],
                'checktime_id' => $this->validator->attributes['checktime_id'],
                'form_id' => $this->validator->attributes['form_id'],
                'operate_type'=>11,
                'content_id'=>!empty($form_content_arr) ? $form_content_arr : [],
                'user_id' => Laminas::$serviceManager->identity->getId()
            ]
        ]);
        unset($form_content_arr);

        return $this->RenderApiJson()->Success();
    }

    /**
     * 预览评分功能表单
     * @return JsonModel
     * @throws Exception
     */
    public function scoreFormPreviewAction(): JsonModel
    {
        $formId = $this->params()->fromPost('form_id');

        $query = Laminas::$serviceManager->itemForm->fetchOne([
            'where' => ['id' => $formId, 'is_using_score' => 1]
        ])['id'];

        return $this->RenderApiJson()->Success(Laminas::$serviceManager->itemForm->getPreviewConfig($query));
    }

    /**
     * 获取所有评分功能表单
     * @return JsonModel
     * @throws Exception
     */
    public function scoreFormListAction(): JsonModel
    {
        $itemId = $this->params()->fromPost('item_id');

        $query = Laminas::$serviceManager->itemForm->fetchAll([
            'columns' => ['id', 'name'],
            'where' => ['item_id' => $itemId, 'is_using_score' => 1],
            'order' => ['order DESC']
        ]);

        return $this->RenderApiJson()->Success($query);
    }



    /**
     * Notes: 一对多表单删除后质疑历史数据的处理
     * @param
     * @return
     * @author haojinhua
     * @date 2024-09-23
     */
    public function processedAction(){
         $multi_id = $error_id_arr = [];
         // 1 所有表单类型为 一对多的类型的并且非常规识别类的表单ID
         $form_id = $this->LocalService()->itemForm->fetchCol('id','is_del = 0 and type = 1 and group_id <> 10');
         if(!empty($form_id)){
             //查询所有已经删除的主键ID  这个ID就等于yikeen_item_patient_form_logic_error 表中的multi_id
             $multi_id = $this->LocalService()->patientFormContent->fetchCol('id','is_del = 1 and form_id in('.implode(',',$form_id).')');
         }

         if(!empty($multi_id)){
             //查询对应的所有未关闭的质疑信息
             $error_id_arr = $this->LocalService()->itemPatientFormLogicError->fetchCol('id','is_report = 0 and is_closed = 0 and multi_id in('.implode(',',$multi_id).')');
         }

         if(!empty($error_id_arr)){
             $item_idarr = $this->LocalService()->itemPatientFormLogicError->fetchCol('item_id','is_report = 0');
             foreach ($error_id_arr as $error_id){
                 $itemId = isset($item_idarr[$error_id]) && !empty($item_idarr[$error_id]) ? $item_idarr[$error_id] : 0;
                 //处理质疑信息
                 $this->LocalService()->itemPatientFormLogicErrorQuery->save([
                     'content' => '数据已删除',
                     'error_id' => $error_id,
                     'platform' => 2,
                     'is_reply' => 1,
                     'pointer_id' => 0,
                     'item_id' => $itemId,
                     'create_user_id' => 0 // 系统
                 ]);
                 // 删除质疑
                 $this->LocalService()->itemPatientFormLogicError->update(['is_closed' => 1, 'is_del' => 1], ['id' => $error_id]);
                 $this->LocalService()->itemPatientFormLogicErrorQuery->update(['is_del' => 1], ['error_id' => $error_id]);
                 $this->LocalService()->itemPatientFormLogicErrorLog->update(['is_closed' => 1], ['error_id' => $error_id]);
                 $this->LocalService()->itemPatientFormLogicErrorPointer->update(['is_del' => 1], ['error_id' => $error_id]);
             }
         }

         die;
    }

    public function itemFormSourceAction() : JsonModel
    {
        $patient_id = $this->params()->fromPost('patient_id', 0);
        $item_form_source_set = $this->params()->fromPost('item_form_source_set', '');
        $searchName = $this->params()->fromPost('searchName', '');  // 检索关键字

        $result = [];

        if (!empty($item_form_source_set)) {
            [$form_id, $form_field_id, $checktimeIds] = explode('|', $item_form_source_set);

            $isDrugShareImg = true;
            $formFieldName = '医嘱药物名称';
            if($form_id != -1) {
                // 获取表单字段
                $formFieldName = $this->LocalService()->itemFormField->getOneFieldVal('name', ['id' => $form_field_id, 'is_del' => 0, 'form_id' => $form_id]);

                $isDrugShareImg = $this->LocalService()->itemFormField->validDrugShareImg($form_field_id);
            }

            // 表单结构数据
            $FormFileData = [
                [
                    'label' => '访视检查点',
                    'prop' => 'checktime_id'
                ],
                [
                    'label' => $formFieldName,
                    'prop' => $form_field_id
                ]
            ];

            // 获取表单数据
            $tableSv = 'patientFormContent';
            $searchColumn = ['id', 'data'];

            $itemPatientFormContentWhere = ['is_del' => 0, 'patient_id' => $patient_id];
            if($checktimeIds) $itemPatientFormContentWhere[] =  new In('checktime_id', implode(',', $checktimeIds));
            if($isDrugShareImg) {
                // 获取所有的共享的表单id集合
                $sharePoolFormIdList = $form_id == -1
                    ? $this->LocalService()->itemForm->fetchCol('id', ['info_collect_type' => $form_field_id, 'is_del' => 0]) // 获取相同收集类型的表单id集合
                    : ArrayHelper::getColumn(SDMHelper::app()->form->getGcoGroupForm($form_id), 'id'); // 获取同一个分组下的共享表单id集合

                $itemPatientFormContentWhere = ArrayUtils::merge($itemPatientFormContentWhere, [
                   // 'info_type' => 1,
                   'is_lock' => 1,
                   empty($sharePoolFormIdList) ? 'id < 0' : new In('form_id', $sharePoolFormIdList)
                ]);

                if($searchName != '') {
                    $itemPatientFormContentWhere[] = new Like('name', '%'.$searchName.'%');
                }

                $tableSv = 'doctoradviceOriginal';
                $searchColumn = ['id', 'name', 'checktime_id', 'dosage_num', 'dosage_unit'];
            }else {
                $itemPatientFormContentWhere['form_id'] = $form_id;
                if($searchName != '') {
                    $itemPatientFormContentWhere[] = new Like(new \Laminas\Db\Sql\Predicate\Expression("JSON_EXTRACT(data, '$.\"".$form_field_id."\"')"), '%'.$searchName.'%');
                }
            }

            $itemPatientFormContentList = $this->LocalService()->{$tableSv}->fetchAllWithPagination([
                'where' => $itemPatientFormContentWhere,
                'columns' => $searchColumn
            ]);

            if(!empty($itemPatientFormContentList['data'])) {
                $item_id = $this->LocalService()->patient->getOneFieldVal('item_id', ['id' => $patient_id]);
                $checktimeNameList = $this->LocalService()->itemChecktime->fetchCol('check_name', ['item_id' => $item_id, 'is_del' => 0]);

                // 获取药物单位
                $dosageUnitList = $isDrugShareImg ? $this->LocalService()->collectMedicaltake->fetchCol('full_name', ['take_type' => 2, 'is_del' => 0]) : [];

                foreach ($itemPatientFormContentList['data'] as &$content) {
                    if($isDrugShareImg) {
                        $content[$form_field_id] = $content['name'] . '/' . $content['dosage_num'] . $dosageUnitList[$content['dosage_unit']];
                        $contentData = &$content;
                    }else {
                        $contentData = Json::decode($content['data'], true);
                    }

                    $result[] = [
                        'id' => $content['id'],
                        $form_field_id => $contentData[$form_field_id],
                        'checktime_id' => &$checktimeNameList[$contentData['checktime_id']]
                    ];
                }
            }
        }
        return $this->RenderApiJson()->Success($result, '', [
            'FormFileData' => $FormFileData ?? [],
            'total' => $itemPatientFormContentList['count'] ?? 0
        ]);
    }

    /**
     * Notes: 合并用药获取药物对应的用药原因默认值
     * User: lltyy
     * DateTime: 2025/7/31 9:53
     *
     * @return mixed
     */
    public function getdrugcmAction(){
        if($this->request->isPost()){
            $item_id = $this->params()->fromPost('item_id',0);//副项目ID
            $item_id = empty($item_id) ? 0 : $item_id;
            $drug_name = $this->params()->fromPost('keyword','');//药物名称
            $drug_name = empty($drug_name) ? '' : trim($drug_name);

            $cm_id = '';
            if(!empty($item_id) && $drug_name != ''){
                //获取该项目下的设置的用药原因默认信息
                $cm_english = '';
                $cmDrugDatas = $this->LocalService()->projectCmdrugset->fetchAll([
                    'where'=>['is_del'=>0,'item_id'=>$item_id],
                    'columns'=>['cm_english','drug_name']
                ]);
                if(!empty($cmDrugDatas)){
                    foreach($cmDrugDatas as $cmDrugDataKey=>$cmDrugData){
                        $cmDrugData_drug_arr = json_decode($cmDrugData['drug_name'],true);
                        if(in_array($drug_name,$cmDrugData_drug_arr)){
                            $cm_english = $cmDrugData['cm_english'];
                        }
                        unset($cmDrugData_drug_arr);
                        unset($cmDrugDatas[$cmDrugDataKey]);
                    }
                }
                unset($cmDrugDatas);
                if($cm_english != ''){
                    $cm_id = $this->LocalService()->collectMedicaltake->getOneFieldVal('id',['is_del'=>0,'take_type'=>6,'english'=>$cm_english]);
                    $cm_id = !empty($cm_id) ? $cm_id : '';
                }
            }
            return $this->RenderApiJson()->success(['CMINDC100'=>$cm_id]);
        }else{
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'非法请求');
        }
    }

}
