<?php

namespace Application\Models\logic;

use Application\Service\DB\Db;
use Application\Service\Extension\Event\Event;
use Application\Service\Extension\Logger\BaseLogger;
use Application\Service\Extension\Logger\BasicLogger;
use Exception;

class BaseLogic
{
    public ?BaseLogger $logger = null;

    private array $_destructCallableList = [];

    public function __destruct()
    {
        foreach ($this->_destructCallableList as $item) {
            $item();
        }
    }

    public function beforeExecute()
    {
        // 自动执行回滚
        $this->_destructCallableList[] = fn() => Db::rollback();
    }

    public function afterExecute()
    {
        if ($this->logger) {
            $this->logger->flush();
        }
    }


    /**
     * 使用事务执行给定的方法
     *
     * @param string $method 要执行的方法名
     * @param array $args 传递给方法的参数数组
     * @return mixed 执行方法的返回值
     */
    public function executeWithTransaction(string $method, array $args = [])
    {
        // 注册并触发前置事件，以便执行任何需要的前置逻辑
        Event::app()->attach('before.logicModel.execute', [$this, 'beforeExecute']);
        Event::app()->trigger('before.logicModel.execute');

        // 开始数据库事务
        Db::beginTransaction();

        // 执行指定的方法，并传递参数
        $val = $this->{$method}(...$args);

        // 提交事务，确保所有数据库操作生效
        Db::commit();

        // 注册并触发后置事件，以便执行任何需要的后置逻辑
        Event::app()->attach('after.logicModel.execute', [$this, 'afterExecute']);
        Event::app()->trigger('after.logicModel.execute');

        // 返回执行方法的结果
        return $val;
    }

    public function setLogger(BaseLogger $logger): BaseLogic
    {
        $this->logger = $logger;
        return $this;
    }

    /**
     * @return BaseLogger|null|BasicLogger
     * @throws Exception
     */
    public function getLogger(): ?BaseLogger
    {
        if ($this->logger === null) {
            throw new Exception('没设置logger!!。');
        }

        return $this->logger;
    }
}