<?php

namespace Application\Service\Extension\Helper;

use Application\Common\DictionaryVarNameEnum;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\Extension\Helper\base\BaseHelper;
use Application\Service\Extension\Laminas;
use Exception;

/**
 * 前端传过来的数据一些处理方法
 */
class FieldHelper extends BaseHelper
{
    public ?int $fieldId = null;

    public ?string $varName = null;

    public ?int $formId = null;

    const HELPER_KEY_WITH_VAR_NAME = 'WITH_VAR_NAME';

    public function getCacheKey(): string
    {
        return self::class;
    }

    protected function _getFieldData(): array
    {
        if (!$this->getCache()) {
            $data = Laminas::$serviceManager->itemFormField->fetchOne(['where' => ['id' => $this->fieldId]]);
            $this->setCache($data);
        }

        return $this->getCache();
    }

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

    protected function setCache($value, string $helperKey = self::HELPER_KEY_BASE)
    {
        self::$cache[$this->getCacheKey()][$this->fieldId][$helperKey] = $value;
    }

    public function getFieldString(int $fieldId = null)
    {
        if ($fieldId) {
            $this->fieldId = $fieldId;
        }

        return $this->getProperty($this->_getFieldData(), 'name');
    }

    public function getDefaultFieldId(int $fieldId = null)
    {
        if ($fieldId) {
            $this->fieldId = $fieldId;
        }

        return $this->getProperty($this->_getFieldData(), 'default_field_id');
    }
    public function getDefaultChecktimeFieldId(int $fieldId = null)
    {
        if ($fieldId) {
            $this->fieldId = $fieldId;
        }

        return $this->getProperty($this->_getFieldData(), 'default_checktimefield_id');
    }

    public function getName($fieldId = null)
    {
        if(!is_numeric($fieldId)) {
            return '字段ID无法对应。';
        }

        $fieldId = intval($fieldId);

        if ($fieldId) {
            $this->fieldId = $fieldId;
        }

        if (!isset($this->_getFieldData()['name'])) {
            return '未知的字段名称';
        }

        return $this->getProperty($this->_getFieldData(), 'name');
    }

    public function getFormId(int $fieldId = null)
    {
        if ($fieldId) {
            $this->fieldId = $fieldId;
        }

        return $this->getProperty($this->_getFieldData(), 'form_id');
    }


    /**
     * 通过选项值来获取对应的选项名称
     * @param $value
     * @param string $fieldId
     * @return mixed|string
     * @throws Exception
     */
    public function getValueLabel($value, string $fieldId)
    {
        if (stripos($fieldId, 'normal-type') !== false) {
            $arr = [
                '1' => '正常',
                '2' => 'CS',
                '3' => 'NCS',
            ];

            return $arr[$value];
        }

        if ($fieldId === 'sdtx') {
            return '手动填写';
        }

        $fieldId = DataHelper::getFieldId($fieldId);
        try {
            $formId = $this->getFormId($fieldId);
        }catch (\Throwable $exception) {
            // 自己构建的id, 表单设置没有这个字段
            $formId = null;
        }

        if (!$formId) {
            return '未知的字段';
        }

        $version = SDMHelper::app()->form->getVersionData($this->getFormId($fieldId));
        if (!isset($version[$fieldId])) {
            return '找不到字段所对应的数据';
        }

        $type = $version[$fieldId]['type'];
        if (!in_array($type, [FormField::FORM_FIELD_TYPE_CHECKBOX, FormField::FORM_FIELD_TYPE_RADIO])) {
            return $value;
        }

        $getLabel = function ($value) use ($version, $fieldId) {
            if ($value === '') {
                return '';
            }

            $varName = $version[$fieldId]['var_name'];

            if (in_array($varName, [DictionaryVarNameEnum::COLLECT_MEDICAL_TAKE_CMINDC])) {
                return SDMHelper::app()->form->field->getMedicalTakeName($value);
            }

            $valArr = ArrayHelper::index($version[$fieldId]['children'], 'value');

            return $valArr[$value]['name'] ?? $value;
        };

        if(!is_array($value)){  //是字符串但是多个值的 转换成数组处理
            $new_value = explode(',',$value);
            if(count($new_value) > 1){
                $value = $new_value;
            }
        }
        if (is_array($value)) {
            $r = [];
            foreach ($value as $v) {
                $r[] = $getLabel($v);
            }
            $res = implode(',', $r);
        } else {
            $res = $getLabel($value);
        }

        return $res;
    }

    /**
     * 通过选项值的名字来获取选项值
     * @param int $fieldId
     * @param string $label
     * @return mixed|string
     * @throws Exception
     */
    public function getLabelValue(int $fieldId, string $label)
    {
        $fieldId = DataHelper::getFieldId($fieldId);
        $version = SDMHelper::app()->form->getVersionData($this->getFormId($fieldId));
        if (!isset($version[$fieldId])) {
            return '';
        }

        $type = $version[$fieldId]['type'];
        if (!in_array($type, [FormField::FORM_FIELD_TYPE_CHECKBOX, FormField::FORM_FIELD_TYPE_RADIO])) {
            return $label;
        }

        $valArr = ArrayHelper::index($version[$fieldId]['children'], 'name');


        return $valArr[$label]['value'] ?? '';
    }

    /**
     * @param string $fieldId
     * @return string
     * @throws Exception
     */
    public function getVarName(string $fieldId): string
    {
        if ($fieldId) {
            $this->fieldId = $fieldId;
        }

        $val = $this->_getFieldData();
        return $val['var_name'] ?? '';
    }

    public function compareMedicalTake(string $currentVal, string $varName): bool
    {
        if (!isset($this->getCache(__FUNCTION__)['id'])) {
            $this->setCache(Laminas::$serviceManager->collectMedicaltake->fetchOne([
                'where' => ['take_type' => 6, 'english' => $varName]
            ]), __FUNCTION__);
        }

        return $this->getCache(__FUNCTION__)['id'] == $currentVal;
    }

    public function getMedicalTakeName(string $value): string
    {
        if ($value == 1) {
            return '属于新增AE';
        } elseif ($value == 2) {
            return '属于已有AE';
        }

        if (!$this->getCache(__FUNCTION__ . $value)) {
            $this->setCache(Laminas::$serviceManager->collectMedicaltake->fetchOne([
                'where' => ['take_type' => 6, 'id' => $value]
            ]), __FUNCTION__ . $value);
        }

        return $this->getCache(__FUNCTION__ . $value)['name'];
    }
}