<?php

namespace Application\Service\Extension\Helper;

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\Exceptions\InvalidArgumentException;
use Application\Service\Extension\Helper\base\BaseHelper;
use Application\Service\Extension\Laminas;
use EasyWeChat\Kernel\Support\Str;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Where;


class PatientHelper extends BaseHelper
{
    public static array $container = [];

    protected ?int $patientId = null;

    /** @var string 受试者patientForm数据 */
    public const HELPER_KEY_FORM = 'PATIENT_FORM';

    public function __construct($config = [])
    {
        parent::__construct($config);
    }


    private function _getCacheData()
    {
       if (!$this->getCache()) {
            $this->setCache(Laminas::$serviceManager->patient->fetchOne(['where' => ['id' => $this->patientId]]));
        }

        return $this->getCache();
    }

    private function _getPatientCacheData()
    {
        if (!$this->getCache(self::HELPER_KEY_FORM)) {
            $this->setCache(Laminas::$serviceManager->patient->fetchOne(['where' => ['id' => $this->patientId]]), self::HELPER_KEY_FORM);
        }

        return $this->getCache(self::HELPER_KEY_FORM);
    }

    public function getPatientNumber(int $patientId = null)
    {
        if ($patientId) {
            $this->patientId = $patientId;
        }
        return $this->_getCacheData()['patient_number'] ?: '';
    }

    public function getPatientName(int $patientId = null)
    {
        if ($patientId) {
            $this->patientId = $patientId;
        }
        return $this->_getCacheData()['patient_name'] ?: '';
    }

    protected function setCache($value, string $helperKey = self::HELPER_KEY_BASE)
    {
        self::$cache[$this->patientId][$helperKey] = $value;
        // TODO: Implement setCache() method.
    }

    protected function getCache(string $helperKey = self::HELPER_KEY_BASE): array
    {
        return self::$cache[$this->patientId][$helperKey] ?? [];
    }

    protected function getCacheKey()
    {
        return self::class;
    }

    private function _getPatientFormData(int $formId, int $checkTimeId): ?array
    {
        if (!$this->getCache(self::HELPER_KEY_FORM)) {
            $condition = [
                'form_id' => $formId,
                'patient_id' => $this->patientId,
//                'itemsig_id' => $this->validator->attributes['itemsig_id'],
                'checktime_id' => $checkTimeId,
                'is_del' => 0
            ];

            $patientFormData = Laminas::$serviceManager->patientForm->fetchOne([
                'where' => $condition
            ]);

            $this->setCache($patientFormData, self::HELPER_KEY_FORM);
        }

        return $this->getCache(self::HELPER_KEY_FORM) ?? null;
    }


    public function getPatientFormId(int $formId, int $checkTimeId, int $patientId = null)
    {
        if ($patientId) {
            $this->patientId = $patientId;
        }

        $val = $this->_getPatientFormData($formId, $checkTimeId);

        return $this->getProperty($val, 'id', '没找到表单对应关系数据。');
    }

    public function getPatientFormIsComplete(int $formId, int $checkTimeId, int $patientId = null)
    {
        if ($patientId) {
            $this->patientId = $patientId;
        }

        $val = $this->_getPatientFormData($formId, $checkTimeId);

        return $this->getProperty($val, 'is_complete', '没找到表单对应关系数据。');
    }

    /**
     * 设置受试者表单完成状态
     * @param int $status
     * @param int $formId
     * @param int $checkTimeId
     * @param int|null $patientId
     * @return mixed|null
     * @throws \Exception
     */
    public function setPatientFormCompleteStatus(int $status, int $formId, int $checkTimeId, int $patientId = null)
    {
        if ($patientId) {
            $this->patientId = $patientId;
        }

        $val = $this->_getPatientFormData($formId, $checkTimeId);

        $id = $this->getProperty($val, 'id', '没找到表单对应关系数据。');

        return Laminas::$serviceManager->patientForm->update(['is_complete' => $status], ['id' => $id]);
    }

    /**
     * 设置受试者表单完成状态, 如果未发现patientForm 就给添加一个
     * @param int $status
     * @param int $formId
     * @param int $checkTimeId
     * @param int|null $patientId
     * @return mixed|null
     * @throws \Exception
     */
    public function setAutoPatientFormCompleteStatus(int $status, int $formId, int $checkTimeId, int $patientId = null)
    {
        if ($patientId) {
            $this->patientId = $patientId;
        }

        $val = $this->_getPatientFormData($formId, $checkTimeId);

        if (!$val) {
            $id = $this->setPatientForm($formId, $checkTimeId, $patientId);
        } else {
            $id = $this->getProperty($val, 'id', '没找到表单对应关系数据。');
        }


        return Laminas::$serviceManager->patientForm->update(['is_complete' => $status], ['id' => $id]);
    }
    /**
     * 获取识别表单字段填写数量
     * @param int $formId
     * @param int $checkTimeId
     * @param int $patientId
     * @return string
     * @throws \Exception
     */
    public function getShareFormFillCount(int $formId, int $checkTimeId, int $patientId): string
    {
        if (SDMHelper::app()->form->getGroupId($formId) != FormGroup::NORMAL_OCR) {
            return '';
        }

        $method = 'fetchOne';
        // 一对多的不展示指标
        if (SDMHelper::app()->form->getType($formId) == Form::FORM_TYPE_MULTI) {
            $method = 'fetchAll';
        }

        $versionData = SDMHelper::app()->form->getVersionData($formId);
        $config = Laminas::$serviceManager->itemForm->getPreviewConfig($formId, true, false);
        $current = 0;
        $total = count($config['generateFields']) - 1;
        $content = Laminas::$serviceManager->patientFormContent->{$method}([
            'columns' => ['id', 'data'],
            'where' => ArrayHelper::filter([
                'form_id' => $formId,
                'is_del' => 0,
                'checktime_id' => $checkTimeId,
                'patient_id' => $patientId,
                'is_lock' => SDMHelper::app()->form->getIdentificationEdit($formId) == 0 ? 1 : null
            ])
        ]) ?: false;

        if ($content === false) {
            if (SDMHelper::app()->form->getType($formId) == Form::FORM_TYPE_MULTI) {
                return "0 / 0";
            }

            $total = count($config['config']['form']) - 1;
            return "$total / $current";
        }

        // 一对多
        if ($method === 'fetchAll') {
            foreach ($content as $item) {
                $data = StringHelper::jsonDecode($item['data']);
                foreach ($config['generateFields'] as $field) {
                    if (isset($data[$field]) && $data[$field] !== '' && (($versionData[$field]['type'] ?? '') != FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE)) {
                        $current++;
                    }
                }
            }
            return $total * count($content) . "/$current";
        } else {
            $total = 0;
            $data = StringHelper::jsonDecode($content['data']);
            foreach ($config['generateFields'] as $field) {
                if (isset($data[$field]) && (($versionData[$field]['type'] ?? '') != FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE)) {
                    if ($data[$field] !== '') {
                        $current++;
                    }
                    $total++;
                }
            }
            return "$total/$current";
        }
    }


    /**
     * 获取AE判断下AE列表有多少AE数据。
     * 包括了受试者tianAE和属于新增AE
     * @return int|void
     */
    public function getAeListCount()
    {
        $csaeCount = 0;
        //获取itemPatientAeContent表中的branch
        $itemPatientAeContents = Laminas::$serviceManager->itemPatientAeContent->fetchAll([
            'where'=> [
                'patient_id' => $this->patientId,
                [
                    'or' => [
                        'ae_type' => 0,
                        new Operator('csae_id', Operator::OP_GT, 0),
                    ]
                ]
            ],
            'columns'=>['ae_type','branch','csae_id']
        ]);
        if(!empty($itemPatientAeContents)){
            $branchArr = [];
            //获取该患者itemCsae表中的csae_id
            $csae_id_arr = Laminas::$serviceManager->itemCsae->fetchCol('id',[
                'is_del' => 0,
                'ae_type' => 6,
                'patient_id' => $this->patientId,
            ]);
            $csae_id_arr = array_values($csae_id_arr);
            foreach($itemPatientAeContents as $itemPatientAeContentKey=>$itemPatientAeContent){
                if($itemPatientAeContent['ae_type'] == 0){
                    $branchArr[$itemPatientAeContent['branch']] = '"'.$itemPatientAeContent['branch'].'"';
                }else{
                    if(in_array($itemPatientAeContent['csae_id'],$csae_id_arr)){
                        $branchArr[$itemPatientAeContent['branch']] = '"'.$itemPatientAeContent['branch'].'"';
                    }
                }
                unset($itemPatientAeContents[$itemPatientAeContentKey]);
            }
            unset($csae_id_arr);

            //获取itemCsaeRelation表中的数据数量
            if(!empty($branchArr)){
                $csaeCount = Laminas::$serviceManager->itemCsaeRelation->getCount([
                    'is_del' => 0,
                    'patient_id' => $this->patientId,
                    'branch' => StringHelper::toArray(array_values($branchArr)),
                ]);
            }
            unset($branchArr);
        }
        unset($itemPatientAeContents);

        return $csaeCount;
    }

    public function setPatientForm(int $formId, int $checkTimeId, int $patientId = null): int
    {
        $query = Laminas::$serviceManager->patientForm->fetchOne([
            'where' => [
                'checktime_id' => $checkTimeId,
                'patient_id' => $patientId,
                'is_del' => 0
            ]
        ]);

        if (!$query) {
            throw new InvalidArgumentException('无法自动补录数据。');
        }

        $model = new PatientFormModel();
        $model->setPostValues([
            'form_id' => $formId,
            'checktime_id' => $checkTimeId,
            'patient_id' => $patientId,
            'item_id' => $query['item_id'],
            'itemsig_id' => $query['itemsig_id'],
            'patientchecktime_id' => $query['patientchecktime_id']
        ]);
        return $model->_updateRelationStatus($formId, 0);
    }

    /**
     * Notes: 获取常规类识别表单完成的字段数量
     * User: lltyy
     * DateTime: 2025/7/25 11:55
     *
     * @param int $formId //表单ID
     * @param int $checkTimeId //项目检查点ID
     * @param int $patientId //患者ID
     * @return int
     * @throws \Exception
     */
    public function getShareFormOverFieldCount(int $formId, int $checkTimeId, int $patientId){
        $over_num = 0;
        if(empty($formId) || empty($checkTimeId) || empty($patientId)){
            return $over_num;
        }
        //获取常规类识别表单完成的字段数量
        if (SDMHelper::app()->form->getGroupId($formId) == FormGroup::NORMAL_OCR) {
            //获取患者访视填写的常规类识别表单信息
            $content_where = [
                'is_del'=>0,
                'patient_id'=>$patientId,
                'checktime_id'=>$checkTimeId,
                'form_id'=>$formId,
            ];
            if(SDMHelper::app()->form->getIdentificationEdit($formId) == 0){
                $content_where['is_lock'] = 1;
            }
            $contents = Laminas::$serviceManager->patientFormContent->fetchCol('data',$content_where);
            unset($content_where);
            if(!empty($contents)){
                $versionData = SDMHelper::app()->form->getVersionData($formId);
                $config = Laminas::$serviceManager->itemForm->getPreviewConfig($formId, true, false);
                foreach($contents as $content_key=>$content){
                    $content_data = StringHelper::jsonDecode($content);
                    if(!empty($content_data) && isset($config['generateFields']) && !empty($config['generateFields'])){
                        foreach ($config['generateFields'] as $field) {
                            $field_type = isset($versionData[$field]) && isset($versionData[$field]['type']) && $versionData[$field]['type'] != '' ? $versionData[$field]['type'] : '';
                            if (isset($content_data[$field]) && $content_data[$field] !== '' && ($field_type != FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE)) {
                                $over_num++;
                            }
                            unset($field_type);
                        }
                    }
                    unset($content_data);
                    unset($contents[$content_key]);
                }
                unset($versionData);
                unset($config);
            }
            unset($contents);
        }
        return $over_num;
    }
}