<?php

namespace Application\Service\Extension;

use Application\Common\EventEnum;
use Application\Form\FieldForm;

/**
 * Event::on('eventString', [new SomeClass(), 'methodName'])
 * Event::on('eventString', [SomeClass::class, 'methodName'])
 * Event::on('eventString', function() {})
 */
class Event
{
    private static array $_instance = [];

    public static function on(string $event, $callable)
    {
        if (self::$_instance === []) {
            self::initEventMap();
        }

        self::$_instance[$event] = $callable;
    }

    /**
     * @param string $event
     * @param array $params
     * @return mixed|void
     * @throws \Exception
     */
    public static function trigger(string $event, array $params = [])
    {
        if (self::$_instance === []) {
            self::initEventMap();
        }

        if (!isset(self::$_instance[$event])) {
            return;
        }

        $val = self::$_instance[$event];

        if ($val instanceof \Closure) {
            return $val(...$params);
        } else if (is_array($val)) {
            list($class, $method) = $val;
            if (is_object($class) && method_exists($class, $method)) {
                return $class->{$method}($params);
            } elseif (is_string($class)) {
                $class = new $class();
            }

            if (method_exists($class, $method)) {
                return $class->{$method}(...$params);
            }
        }

        // throw new \Exception('找不到对应的处理方法。');
    }

    /**
     * 初始化事件绑定
     */
    private static function initEventMap()
    {
        // 不知道干啥的, 让我调用的
        // $type 1==随机分组  2==基点日期
        /** @see EventEnum::BEFORE_EVENT_SUBMIT_ANCHOR_TIME */
        self::$_instance[EventEnum::BEFORE_EVENT_SUBMIT_ANCHOR_TIME] = function (&$owner, $value) {
            /** @var FieldForm $owner */
            Laminas::$serviceManager->itemRandom->ChangeRandomTime(...[$owner->patientId, $owner->itemId, 2, strtotime($value) ?: 0, $owner->formId]);
            Laminas::$serviceManager->itemPatientchecktime->EditPatientChecktimeStatus($owner->itemId, $owner->patientId);
        };

        /** @see EventEnum::BEFORE_EVENT_SUBMIT_RANDOM_TIME */
        self::$_instance[EventEnum::BEFORE_EVENT_SUBMIT_RANDOM_TIME] = function (&$owner, $value) {
            /** @var FieldForm $owner */
            Laminas::$serviceManager->itemRandom->ChangeRandomTime(...[$owner->patientId, $owner->itemId, 1, $value, $owner->formId]);
        };
    }
}