<?php

namespace Application\Service\Extension\Helper;


use Application\Service\Extension\Helper\base\BaseHelper;
use Application\Service\Extension\Helper\components\AEHelper;
use Application\Service\Extension\Helper\components\AnalysisHelper;
use Application\Service\Extension\Helper\components\ExpressionHelper;
use Application\Service\Extension\Helper\components\FormContentHelper;
use Application\Service\Extension\Helper\components\ItemHelper;
use Application\Service\Extension\Helper\components\LogicMessageFormatter;
use Application\Service\Extension\Helper\components\SignHelper;

/**
 * @property LogHelper $log
 * @property ItemHelper $item
 * @property FormHelper $form
 * @property AnalysisHelper $analysis
 * @property LogicHelper $logic
 * @property SignHelper $sign
 * @property AEHelper $ae
 * @property \Application\Service\Extension\Helper\components\UserHelper $user
 * @property PatientHelper $patient
 * @property CheckTimeHelper $checkTime
 * @property ExpressionHelper $expression
 * @property FormContentHelper $formContent
 * @property LogicMessageFormatter $logicMessageFormatter
 */
class SDMHelper
{
    public static ?array $SDMContainer = [];

    /**
     * @var SDMHelper| null
     */
    protected static ?SDMHelper $app = null;

    protected array $components = [
        'ae' => AEHelper::class,
        'log' => LogHelper::class,
        'form' => FormHelper::class,
        'sign' => SignHelper::class,
        'item' => ItemHelper::class,
        'user' => \Application\Service\Extension\Helper\components\UserHelper::class,
        'logic' => LogicHelper::class,
        'patient' => PatientHelper::class,
        'analysis' => AnalysisHelper::class,
        'checkTime' => CheckTimeHelper::class,
        'expression' => ExpressionHelper::class,
        'formContent' => FormContentHelper::class,
        'logicMessageFormatter' => LogicMessageFormatter::class,
    ];

    protected array $attributes = [];

    public function setAttributes(array $attrs)
    {
        foreach ($attrs as $prop => $val) {
            $exStr = explode('_', $prop);
            $firstWord = array_shift($exStr);
            if ($exStr) {
                foreach ($exStr as &$str) {
                    $str = ucfirst($str);
                }
            }

            $key = $firstWord . implode('', $exStr);
            $this->attributes[$key] = $val;
        }

        return $this;
    }

    public static function app(): SDMHelper
    {
        if (self::$app === null) {
            self::$app = new self();
        }

        return self::$app;
    }

    /**
     * 当前是否是单元测试
     * @return bool
     */
    public static function isUnitTest(): bool
    {
        if (defined('IS_UNIT_TEST')) {
            return true;
        }

        return false;
    }

    public function exist($name): bool
    {
        return isset($this->components[$name]);
    }

    public function __get($name)
    {
        if ($name === 'analysis') {
            if (!isset(self::$SDMContainer[$name])) {
                $c = (new $this->components[$name]($this->attributes));
                self::$SDMContainer[$name] = &$c;
            }
            return self::$SDMContainer[$name];
        } else {
            /** @var BaseHelper $class */
            return (new $this->components[$name]($this->attributes));// new FormHelper($params);
        }

    }

    public function getPatientHelper(int $patientId): PatientHelper
    {
        return new PatientHelper($patientId);
    }

    public function getCheckTimeHelper(int $checkTimeId): CheckTimeHelper
    {
        return new CheckTimeHelper(['checkTimeId' => $checkTimeId]);
    }

    public function getUserHelper(int $userId): UserHelper
    {
        return new UserHelper(['userId' => $userId]);
    }

    public function getFormHelper($params = []): FormHelper
    {
        if (!isset(self::$SDMContainer[__FUNCTION__])) {
            self::$SDMContainer[__FUNCTION__] = new FormHelper($params);
        }
        return self::$SDMContainer[__FUNCTION__];
    }
}