<?php

namespace Application\Service\Extension\HelperV2;

use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Cache\Cache;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Store\Store;
use Application\Service\Logic\form\FormStructGenerator;
use Exception;

class FormHelper
{
    private bool $_isDictionary = false;

    private function _getStructCache($formId)
    {
        return Store::app()->getOrSet(__CLASS__ . __FUNCTION__ . $formId, function () use ($formId) {

            return unserialize(Cache::app()->getOrSet([$formId, $this->_isDictionary], function () use ($formId) {
                $generator = new FormStructGenerator();
                $generator->formId = $formId;
                $generator->isDictionary = $this->_isDictionary;
                return $generator->execute();
            }));
        });
    }

    public function getStructCacheFormModule($formId)
    {
        if (!isset($this->_getStructCache($formId)['form']) || !$this->_getStructCache($formId)['form']) {
            throw new Exception(__FUNCTION__ . 'is error.');
        }

        return $this->_getStructCache($formId)['form'];
    }

    public function getStructCacheFieldsModule($formId)
    {
        if (!isset($this->_getStructCache($formId)['fields']) || !$this->_getStructCache($formId)['fields']) {
            throw new Exception(__FUNCTION__ . 'is error.');
        }

        return $this->_getStructCache($formId)['fields'];
    }

    public function setIsDictionary(bool $isDictionary)
    {
        $this->_isDictionary = $isDictionary;
    }

    /**
     * 获取表单名称
     * @param int $formId
     * @return string
     * @throws Exception
     */
    public function getName(int $formId): string
    {
        return $this->getStructCacheFormModule($formId)['name'] ?? '';
    }

    /**
     * 获取缓存设置的时间
     * @param $formId
     * @return false|mixed
     */
    public function getCachedAt($formId)
    {
        return $this->_getStructCache($formId)['cached_at'] ?? false;
    }

    /**
     * 表单填写类型 0:一对一; 1:一对多;
     * @param int $formId
     * @return string
     * @throws Exception
     */
    public function getType(int $formId): string
    {
        return $this->_getStructCacheFormModule($formId)['type'] ?? '';
    }

    /**
     * 表单类型 @see FormGroup
     *
     * // 试验总结类
     * FormGroup::TEST_SUMMARY;
     *
     * // 随机分组
     * FormGroup::RANDOM_GROUP;
     *
     * // SAE类表单
     * FormGroup::SAE
     *
     * // 贯穿全程类
     * FormGroup::THROUGH_PROCESS
     *
     * // AE类表单
     * FormGroup::AE
     *
     * // 常规
     * FormGroup::NORMAL
     *
     * // 检查类（OCR识别
     * FormGroup::CHECK_OCR
     *
     * // 医嘱（OCR识
     * FormGroup::CHECK_DO
     *
     * // 贯穿全程识别医
     * FormGroup::THROUGH_PROCESS_DO
     *
     * // 常规类(识别)
     * FormGroup::NORMAL_OCR
     *
     * @param int $formId
     * @return string
     * @throws Exception
     */
    public function getGroupId(int $formId): string
    {
        return $this->getStructCacheFormModule($formId)['group_id'] ?? '';
    }

    /**
     * 获取表单缓存
     * @param int $formId
     * @return array
     */
    public function getStruct(int $formId): array
    {
        return $this->_getStructCache($formId);
    }

    /**
     * 重新设置表单缓存
     * @param int $formId
     * @throws Exception
     */
    public function resetStruct(int $formId)
    {
        // 入库
        $generator = new FormStructGenerator();
        $generator->formId = $formId;
        $generator->isDictionary = $this->_isDictionary;
        $data = $generator->execute();
        $query = Laminas::$serviceManager->formStruct->fetchOne([
            'where' => ['form_id' => $formId, 'is_dictionary' => intval($this->_isDictionary)]
        ]);

        Laminas::$serviceManager->formStruct->save(ArrayHelper::filter([
            'id' => $query['id'] ?? null,
            'form_id' => $formId,
            'data' => $data,
        ]));

        $args = func_get_args();
        // 写缓存
        Cache::app()->set($args, $data);
    }
}