<?php

namespace Application\Service\Extension\Events;

use Application\Common\DictionaryVarNameEnum;
use Application\Common\EventEnum;
use Application\Common\EventEnumV2;
use Application\Form\item\patient\PatientFormModel;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;

class FormEventHandler
{
    private function h(): SDMHelper
    {
        return SDMHelper::app();
    }

    // 从CM列表进行编辑
    public function afterEventCmFormEdit(&$owner)
    {
        /** @var PatientFormModel $owner */
        $owner->h()->log->setTraceAttach("在CM列表中提交了数据, 修改用药原因为`" . SDMHelper::app()->form->field->getMedicalTakeName($owner->CMINDCVal) . '`');
        $originCmindcStatus = $owner->originCMINDCVal;
        if (in_array($originCmindcStatus, [1, 2]) && $owner->CMINDCVal != $originCmindcStatus) {
            $owner->h()->log->setTraceAttach("由受试者新增AE修改成了{$owner->CMINDCVal}, 所以将所有关联的AE数据断开关系。");
            if ($originCmindcStatus == 1) {
                SDMHelper::app()->ae->discardCMNewAE($owner->contentPrimaryKey);
            } elseif ($originCmindcStatus == 2) {
                SDMHelper::app()->ae->deleteAllCMListIsAlreadyAE($owner->contentPrimaryKey);
            }
        }

        // 判断时间
        Laminas::$serviceManager->patientFormContentCm->update(['update_user_id' => Laminas::$serviceManager->identity->getId(), 'update_time' => time(), 'status' => 1, 'cmindc_status' => $owner->CMINDCVal], ['content_id' => $owner->contentPrimaryKey]);
    }

    private array $executeFormGroupFunc = [
        FormGroup::NORMAL_OCR => [
            ['updateShareForm'],
            ['removeTempStorage'],
        ],
    ];

    private array $executeFormTypeFunc = [
        Form::FORM_TYPE_MULTI => [
            ['handleMultiForm']
        ],
    ];

    /**
     * event - 表单提交之后
     * @param $owner
     * @throws \Exception
     */
    public function eventAfterSubmitPatientForm(&$owner)
    {
        /** @var PatientFormModel $owner */
        $this->CMINDCForm($owner);
        if (isset($this->executeFormGroupFunc[SDMHelper::app()->form->getGroupId($owner->formId)])) {
            foreach ($this->executeFormGroupFunc[SDMHelper::app()->form->getGroupId($owner->formId)] as $func) {
                $this->{current($func)}($owner);
            }
        }

        if (isset($this->executeFormTypeFunc[SDMHelper::app()->form->getType($owner->formId)])) {
            foreach ($this->executeFormTypeFunc[SDMHelper::app()->form->getType($owner->formId)] as $func) {
                $this->{current($func)}($owner);
            }
        }

        // 修复 暂存数据之后再填写可能会重复的问题
        if (SDMHelper::app()->form->getGroupId($owner->formId) == FormGroup::NORMAL_OCR && SDMHelper::app()->form->getType($owner->formId) == Form::FORM_TYPE_SINGLE) {
            $tempVal = SDMHelper::app()->formContent->getTempStorage($owner->patientId, $owner->checktimeId, $owner->formId);
            if ($tempVal) {
                $val = StringHelper::jsonDecode($tempVal);
                $val['data']['id'] = $owner->contentPrimaryKey;
                SDMHelper::app()->formContent->setTempStorage($val, $owner->patientId, $owner->checktimeId, $owner->formId);
            }
        }


    }

    /**
     * 处理合并用药
     * @param $owner
     * @throws \Exception
     */
    private function CMINDCForm(&$owner)
    {
        /** @var PatientFormModel $owner */
        if ($versionData = ArrayHelper::index($owner->h()->form->getVersionData($owner->formId), 'var_name')) {
            // TODO: add date condition
            if (isset($versionData[DictionaryVarNameEnum::COLLECT_MEDICAL_TAKE_CMINDC])) { // && $owner->h()->form->getCreatedAt($owner->formId) >= strtotime('2024-06-01')

                // 用药原因
                $owner->CMINDCVal = $owner->postData[$versionData[DictionaryVarNameEnum::COLLECT_MEDICAL_TAKE_CMINDC]['id']];

                $status = 0;

                // 选中了其他要入到CM判断中, 现在空的也要加进去
                if (in_array($owner->event,[EventEnum::EVENT_FORM_CONTENT_EDIT,EventEnum::EVENT_FORM_CONTENT_CREATE]) && $owner->CMINDCVal != '' && ((Laminas::$serviceManager->collectMedicaltake->fetchOne(['where' => ['id' => $owner->CMINDCVal]])['english'] ?? false) != 'CMINDC4')) {
                    // 其他的选项要入到已判断内
                    $status = 1;
                }

                $has = Laminas::$serviceManager->patientFormContentCm->fetchOne([
                    'where' => [
                        'content_id' => $owner->contentPrimaryKey,
                        'is_del' => 0
                    ]
                ]);

                if (!$has) {
                    $owner->h()->log->setTraceAttach("将当前数据存入CM表, 状态为 `$status`。");
                    $con = [
                        'content_id' => $owner->contentPrimaryKey,
                        'form_id' => $owner->formId,
                        'sign_id' => $owner->itemsigId,
                        'patient_id' => $owner->patientId,
                        'item_id' => $owner->itemId,
                    ];
                    if ($status === 1) {
                        $con['status'] = 1;
                        // 已判断才有这个值
                        $con['cmindc_status'] = $owner->CMINDCVal;
                    }
                    Laminas::$serviceManager->patientFormContentCm->insert($con);
                } else {
                    $isUpdate = true;
                    $owner->originCMINDCVal = $has['cmindc_status'];
                    if ($owner->CMINDCVal == '') {
                        // 受试者新增AE变成了空值
                        if ($has['cmindc_status'] == 1) {
                            SDMHelper::app()->ae->discardCMNewAE($owner->contentPrimaryKey);
                        } elseif ($has['cmindc_status'] == 2) {
                            SDMHelper::app()->ae->deleteAllCMListIsAlreadyAE($owner->contentPrimaryKey);
                        }
//                        SDMHelper::app()->ae->flushCMINDCContent($owner->contentPrimaryKey);
                    } elseif (SDMHelper::app()->form->field->compareMedicalTake($owner->CMINDCVal, 'CMINDC4') === true && in_array($has['cmindc_status'], [1, 2])) {
                        // 如果cm判断那面是 受试者新增AE 或者 受试者已有AE. 进度管理用药原因改成其他的话, CM状态是不变的
                        $isUpdate = false;
                        $owner->postData[$versionData[DictionaryVarNameEnum::COLLECT_MEDICAL_TAKE_CMINDC]['id']] = $has['cmindc_status'];
                        // 二次修改表单内容
                        Laminas::$serviceManager->patientFormContent->update(['data' => json_encode($owner->postData)], ['id' => $owner->contentPrimaryKey]);
                    }

                    if ($isUpdate === true) {
                        Laminas::$serviceManager->patientFormContentCm->update([
                            'update_user_id' => Laminas::$serviceManager->identity->getId(), 'update_time' => time(), 'cmindc_status' => $owner->CMINDCVal,
                            'status' => $status
                        ], ['content_id' => $owner->contentPrimaryKey]);
                    }
                }
            }
        }
    }

    /**
     * 处理常规类识别表单。
     * @param $owner
     * @throws \Exception
     */
    private function updateShareForm(PatientFormModel &$owner)
    {
        if (SDMHelper::app()->form->getGroupId($owner->formId) != FormGroup::NORMAL_OCR) {
            return;
        }

        //始终可编辑 也要更改 解锁已更新的状态
//        if (SDMHelper::app()->form->getIdentificationEdit($owner->formId) == 2) {
//            return;
//        }

        // 如果是锁定的表单提交, 就单个变更颜色
        if (SDMHelper::app()->form->getIsShareFormLock($owner->formId, $owner->patientId, $owner->checktimeId) && SDMHelper::app()->form->getIdentificationEdit($owner->formId) == 1) {
            return;
        }

        // 通过逻辑核查更改的数据 也要只更新当前表单的颜色
        if ($owner->event === EventEnumV2::getVal(EventEnumV2::EVENT_FORM_CONTENT_EDIT_BY_LOGIC_REPLY)) {
            return;
        }

        $forms = $owner->h()->form->getGcoGroupForm($owner->formId);
        $shareGcoPool = $owner->h()->form->getGcoPool($owner->formId);
        foreach ($forms as $form) {
            if ($form['id'] == $owner->formId) {
                continue;
            }
            $owner->h()->log->setTraceAttach("当前是识别类表单, 同时也改变了当前检查点下的表单`{$owner->h()->form->getName($form['id'])}`的填写状态。");
            $owner->_updateRelationStatus($form['id']);
        }

        // 是否已经解锁
        $key = "SHARE_FORM_IS_UNLOCK_NOT_UPDATED:{$owner->itemId}";
        $hashKey = "{$owner->patientId}:{$owner->checktimeId}:{$shareGcoPool}";
        if (Laminas::$serviceManager->redisExtend->getRedisInstance()->hGet($key, $hashKey)) {
            Laminas::$serviceManager->redisExtend->getRedisInstance()->hDel($key, $hashKey);
            Laminas::$serviceManager->redisExtend->getRedisInstance()->hSet("SHARE_FORM_IS_UNLOCK_IS_UPDATED:{$owner->itemId}", $hashKey, 1);
        }
    }

    public function removeTempStorage(PatientFormModel &$owner)
    {
        if (SDMHelper::app()->form->getIdentificationEdit($owner->formId) == 2 && SDMHelper::app()->form->getType($owner->formId) == Form::FORM_TYPE_SINGLE) {
            SDMHelper::app()->formContent->removeTempStorage($owner->patientId, $owner->checktimeId, $owner->formId);
        } else if (SDMHelper::app()->form->getIdentificationEdit($owner->formId) == 2 && SDMHelper::app()->form->getType($owner->formId) == Form::FORM_TYPE_MULTI) {

            $isLock = SDMHelper::app()->form->getIsShareFormLock($owner->formId, $owner->patientId, $owner->checktimeId);
            // 锁定后展示的是列表的数据
            if ($isLock) {
                return;
            }

            $allData = SDMHelper::app()->formContent->getMultiTempStorage($owner->patientId, $owner->checktimeId, $owner->formId);
            SDMHelper::app()->formContent->removeTempStorage($owner->patientId, $owner->checktimeId, $owner->formId);

            $originTempData = [];
            foreach ($allData ?: [] as $v) {
                $d = StringHelper::jsonDecode($v)['data'];
//                $d['id'] = $v['id'];
                $originTempData[] = $d;
            }

            foreach ($originTempData as  &$tempData) {
                $contentId = $tempData['content_id'];
                $insertData = $tempData;

                // 新增
                if (!$owner->postData['id']) {
                    $insertData = $tempData;
                } else if ($owner->postData['id'] && $contentId == $owner->postData['id']) { // edit
                    $insertData = $owner->postData;
                }

                SDMHelper::app()->formContent->setMultiTempStorage(...[[
                    'data' => ArrayHelper::merge($insertData, ['content_id' => $contentId]),
                    'create_user_id' => Laminas::$serviceManager->identity->getId(),
                    'create_time' => time(),
                    'source' => 'processManage', // 来自于进度管理
                ], $owner->patientId, $owner->checktimeId, $owner->formId]);
            }

            if (!$originTempData || !$owner->postData['id']) {
                SDMHelper::app()->formContent->setMultiTempStorage(...[[
                    'data' => ArrayHelper::merge($owner->postData, [
                        'content_id' => $owner->contentPrimaryKey,
                        'id' => $owner->contentPrimaryKey,
                    ]),
                    'create_user_id' => Laminas::$serviceManager->identity->getId(),
                    'create_time' => time(),
                    'source' => 'processManage' // 来自于进度管理
                ], $owner->patientId, $owner->checktimeId, $owner->formId]);
            }
        }
    }

    /**
     * 不知道干啥的, 让我调的
     * @param $owner
     */
    private function handleMultiForm(&$owner)
    {
        /** @var PatientFormModel $owner */
        //异步处理访视进度情况信息
        Laminas::$serviceManager->swTaskClient->send([
            'svName' => 'projectPatientworkbatch',
            'methodName' => 'multipleUpdateData',
            'params' => [
                'item_id' => $owner->itemId,
                'patient_id' => $owner->patientId,
                'checktime_id' => $owner->checktimeId,
                'form_id' => $owner->formId,
                'operate_type'=>11,
                'content_id'=>!empty($owner->contentPrimaryKey) ? [$owner->contentPrimaryKey] : [],
                'user_id' => Laminas::$serviceManager->identity->getId()
            ]
        ]);
        //Laminas::$serviceManager->itemConfirm->closeconfirm($owner->itemId, $owner->patientId, $owner->checktimeId, $owner->formId, true, $owner->contentPrimaryKey);
    }
}