<?php

namespace Application\Service\Extension\Middleware\components;

use Application\Common\EventEnum;
use Application\Form\item\patient\PatientFormModel;
use Application\Service\DB\Dictionary\Form;
use Application\Service\DB\Dictionary\FormField;
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\Helper\ValidatorHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Middleware\BaseMiddlewareComponent;
use Application\Service\Extension\Uploader\adapter\Oss;
use Exception;
use Laminas\Stdlib\ArrayUtils;

/**
 * 预处理返回的数据
 * @property PatientFormModel $owner
 */
class PreProcessResponse extends BaseMiddlewareComponent
{
    private array $_shareField = [];

    private ?array $sharePool = null;

    private ?array $shareFields = null;

    private function _getHelper(): SDMHelper
    {
        return SDMHelper::app();
    }

    /**
     * 一对多可能会少参数, 补一下。
     */
    protected function initializeRequestParams()
    {

    }

    function execute()
    {
        // 将分值处理成int类型
        if (isset($this->responseValue['score'])) {
            $this->responseValue['score'] =  intval($this->responseValue['score']);
        }

        if ($this->owner->event == EventEnum::EVENT_FORM_CONTENT_CREATE) {
            $this->eventCreate();
        }

        if ($this->owner->event == EventEnum::EVENT_FORM_CONTENT_VIEW) {
            $this->eventView();
        }
    }

    private function eventCreate()
    {

    }

    /**
     * @throws Exception
     */
    private function eventView()
    {
        // 预览共享图片的处理
        $this->eventViewHandleShareImage();

        // 未锁定的共享图片的表单数据处理
        $this->eventViewHandleShareFormUnlock();

        // 预览CM列表
        $this->viewCMList();

        $this->manageProcessDetail();
    }

    public function manageProcessDetail()
    {
        // 进度管理
        if ($this->owner->formId && $this->h()->form->getIsCMINDCForm($this->owner->formId) === true && $this->owner->scenario == null) {
            $cmId = SDMHelper::app()->form->getCMINDCId($this->owner->formId);

            // 受试者新增AE 和 属于已有AE 要在进度管理这里显示成其他
            if (isset($this->responseValue[$cmId]) && is_numeric($this->responseValue[$cmId]) && $this->responseValue[$cmId] <= 2) {
                $CMINDC4Id = Laminas::$serviceManager->collectMedicaltake->fetchOne(['where' => ['english' => 'CMINDC4']])['id'];
                $this->responseValue[$cmId] = $CMINDC4Id;
            }
        }
    }

    /**
     * 处理操作人和操作时间
     */
    private function viewCMList()
    {
        if ($this->owner->scenario == $this->owner::SCENARIO_CM_LIST) {
            foreach ($this->responseValue as &$value) {
                $value['operated_at'] = date('Y-m-d H:i:s', $this->h()->formContent->getUpdateTime($value['id']));
                $value['operate_user'] = SDMHelper::app()->user->getRealName($this->h()->formContent->getUpdateUserId($value['id']));
            }
        }
    }

    /**
     * 处理共享图片字段
     * @throws Exception
     */
    private function eventViewHandleShareImage()
    {
        if (!$this->owner->formId) {
            return;
        }

        if ($this->_getHelper()->form->getGroupId($this->owner->formId) != FormGroup::NORMAL_OCR) {
            return;
        }

//        if ($this->h()->form->getType($this->owner->formId) == Form::FORM_TYPE_MULTI) {
//            return;
//        }

        $this->shareFields = Laminas::$serviceManager->itemFormField->fetchOne(['where' => ['type' => FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE, 'is_del' => 0, 'form_id' => $this->owner->formId]]);
        $this->sharePool = ArrayHelper::getColumn(SDMHelper::app()->form->getGcoGroupForm($this->owner->formId), 'id');

        if ($this->h()->form->getType($this->owner->formId) == Form::FORM_TYPE_MULTI && $this->owner->scenario === $this->owner::SCENARIO_VIEW_SHARE_FORM_UNLOCK) {
            $this->_handleData($this->responseValue);
        } elseif ($this->h()->form->getType($this->owner->formId) == Form::FORM_TYPE_SINGLE) {
            $this->_handleData($this->responseValue);
        }
    }

    private function _handleData(&$responseData)
    {
        if (!isset($responseData['id']) && $this->h()->form->getType($this->owner->formId) == Form::FORM_TYPE_SINGLE) {
            $responseData['id'] = '';
        }
        // 如果是从项目图库进去的, 则不显示图片数据
        if (in_array($this->owner->formId, $this->sharePool)) {
            $fields = Laminas::$serviceManager->itemFormField->fetchAll([
                'where' => ['form_id' => $this->sharePool, 'type' => FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE]
            ]);

            $query = Laminas::$serviceManager->patientFormContentImg->fetchAll([
                'order' => ['id ASC'],
                'where' => ['field_id' => ArrayHelper::getColumn($fields, 'id'), 'patient_id' => $this->owner->patientId, 'is_del' => 0, 'checktime_id' => $this->owner->checktimeId]
            ]);
            $r = [];

            foreach ($query as $image) {
                $this->_shareField[] = $image['id'];
                $r[] = [
                    'name' => $image['img_name'],
                    'url' => Oss::getUploadDomain() . $image['img_src'],
                ];
            }

            // 如果是从项目图库进去的, 则不显示图片数据
            if ($this->owner->scenario !== $this->owner::SCENARIO_VIEW_SHARE_FORM_UNLOCK) {
                $responseData[$this->shareFields['id']] = $r;
            }
        }
    }

    /**
     * 处理未锁定的常规识别类表单
     * @throws Exception
     */
    private function eventViewHandleShareFormUnlock(): void
    {
        if (!$this->owner->formId) {
            return;
        }

        if ($this->_getHelper()->form->getGroupId($this->owner->formId) != FormGroup::NORMAL_OCR || $this->owner->scenario !== $this->owner::SCENARIO_VIEW_SHARE_FORM_UNLOCK || !$this->_shareField) {
            return;
        }

        // 一对一是json 一对多是array json
        $method = $this->h()->form->getType($this->owner->formId) == Form::FORM_TYPE_SINGLE ? 'getTempStorage' : 'getMultiTempStorage';
        $tempData = $this->h()->formContent->{$method}($this->owner->patientId, $this->owner->checktimeId, $this->owner->formId);
        $versionData = SDMHelper::app()->form->getVersionData($this->owner->formId);

        // 已锁定的就读锁定的
        if (isset($this->responseValue['id']) && $this->responseValue['id'] && SDMHelper::app()->formContent->getIsLock($this->responseValue['id'])) {
            return;
        }

        // 有暂存的就取暂存的
        if ($tempData) {
            // 一对多
            if (is_array($tempData)) {
                $r = [];
                foreach ($tempData as $k => $tempVal) {
                    $tempVal = StringHelper::jsonDecode($tempVal, true)['data'];
                    $tempVal['id'] = $k + 1;
                    $r[] = $tempVal;
                }

                $this->responseValue = $this->owner->getMultiView('', $r);
                foreach ($this->responseValue as $k => &$val) {
                    $val['id'] = $k + 1; // 防止有0的数据
                }
                $this->owner->totalCount = count($r);
            } else {
                $this->responseValue = StringHelper::jsonDecode($tempData)['data'];
            }

            if (isset($this->responseValue['scoreStr']) && is_string($this->responseValue['scoreStr'])) {
                $this->responseValue['scoreStr'] = StringHelper::jsonDecode($this->responseValue['scoreStr']);
            }
            return;
        }


        // 一对一锁定过了, 就不要取识别数据。
        if ($this->responseValue['id'] && $method === 'getTempStorage' && Laminas::$serviceManager->patientFormContentUpdatedLog->fetchOne([
                'where' => [
                    'content_id' => $this->responseValue['id'],
                    'event' => EventEnum::EVENT_LOCK_SHARE_FORM_CONTENT
                ]
            ])) {
            return;
        }

        // 未保存过数据就从识别数据中读取
        $query = Laminas::$serviceManager->itemPatientformimgcontent->fetchAll([
            'columns' => ['content'],
            'where' => [
                'annex_id' => $this->_shareField,
                'is_del' => 0
            ]
        ]);

        if ($this->owner->formId) {
            foreach ($query as $v) {
                $content = StringHelper::jsonDecode($v['content']);
                if (isset($content[$this->owner->formId])) {
                    $contentVal = ArrayHelper::index($content[$this->owner->formId], 'id');
                    $fieldVersionData = ArrayHelper::index($versionData, 'id');
                    $appendVal = [];
                    foreach ($contentVal as $fieldId => &$val) {
                        if (in_array($fieldVersionData[$fieldId]['type'], [FormField::FORM_FIELD_TYPE_DATE, FormField::FORM_FIELD_TYPE_DATETIME, FormField::FORM_FIELD_TYPE_DATE_SECOND]) && isset($val['value']) && $val['value'] !== '') {
                            $isValidDate = ValidatorHelper::isLegalDate($val['value']);
                            $appendVal[$fieldId] = $isValidDate === true ? $val['value'] : '';
                        } elseif (isset($val['value']) && $val['value'] !== '') {
                            $appendVal[$fieldId] = $this->h()->form->field->getLabelValue($fieldId, $val['value']);
                        }
                    }

                    // 表单手动填写与识别处理的覆盖规则为:后识别/锁定数据覆盖原数据注:只是覆盖原表单中没填值的字段，不是全部覆盖。
                    // 【SDM，EDC】关于常规（识别）类表单始终可编辑以及表单数据覆盖的需求--美，蒙
                    //https://e.gitee.com/yikeen_project/dashboard?issue=IB9LBJ
                    if (SDMHelper::app()->form->getIdentificationEdit($this->owner->formId) == 2) {
                        $this->responseValue = ArrayUtils::merge(array_filter($appendVal), ArrayHelper::filter($this->responseValue, [null, '']), true);
                        return;
                    }
                    $this->responseValue = ArrayUtils::merge($this->responseValue, array_filter($appendVal), true);
                }
            }
        }
    }
}