<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Consumer;

final class QueueConsumerManager
{
    private static ?self $instance = null;

    private QueueConsumer $consumer;
    private QueueConsumerStore $store;

    private function __construct(private readonly string $basePath)
    {
        $this->consumer = new QueueConsumer();
        $this->store = new QueueConsumerStore($basePath);
    }

    public static function instance(?string $basePath = null): self
    {
        if (self::$instance === null) {
            $basePath ??= self::detectBasePath();
            self::$instance = new self($basePath);
        }

        return self::$instance;
    }

    public static function resetInstance(?string $basePath = null): self
    {
        $basePath ??= self::detectBasePath();
        self::$instance = new self($basePath);

        return self::$instance;
    }

    public function consumer(): QueueConsumer
    {
        return $this->consumer;
    }

    public function store(): QueueConsumerStore
    {
        return $this->store;
    }

    public function consoleState(): QueueConsumerConsoleStateHydrator
    {
        return new QueueConsumerConsoleStateHydrator($this);
    }

    public function save(): QueueConsumerRuntimeState
    {
        return $this->store->save($this->consumer);
    }

    public function load(): QueueConsumerRuntimeState
    {
        return $this->store->load();
    }

    public function clear(): void
    {
        $this->consumer->clear();
        $this->store->reset();
    }

    public function statistics(): array
    {
        return $this->consoleState()->statistics();
    }

    public function summary(): array
    {
        return [
            'statistics' => $this->consoleState()->statistics(),
            'snapshot' => $this->consoleState()->snapshot(),
            'batchStatistics' => $this->consoleState()->batchStatistics(),
            'persisted' => $this->store->exists(),
            'stateFile' => $this->store->stateFile(),
        ];
    }

    private static function detectBasePath(): string
    {
        $candidate = dirname(__DIR__, 4);
        $real = realpath($candidate);

        return $real !== false ? $real : $candidate;
    }
}
