<?php

namespace AleshaCMS\CMS\Hook;

class HookManager
{
    protected array $listeners = [];
    protected array $filters = [];

    public function listen(string $hook, callable $callback, int $priority = 10): void
    {
        $this->listeners[$hook][$priority][] = $callback;
    }

    public function fire(string $hook, array $data = []): array
    {
        $results = [];

        if (!isset($this->listeners[$hook])) {
            return $results;
        }

        ksort($this->listeners[$hook]);

        foreach ($this->listeners[$hook] as $callbacks) {
            foreach ($callbacks as $callback) {
                $result = call_user_func($callback, $data);
                if ($result !== null) {
                    $results[] = $result;
                }
            }
        }

        return $results;
    }

    public function filter(string $hook, callable $callback, int $priority = 10): void
    {
        $this->filters[$hook][$priority][] = $callback;
    }

    public function applyFilter(string $hook, mixed $value, array $context = []): mixed
    {
        if (!isset($this->filters[$hook])) {
            return $value;
        }

        ksort($this->filters[$hook]);

        foreach ($this->filters[$hook] as $callbacks) {
            foreach ($callbacks as $callback) {
                $value = call_user_func($callback, $value, $context);
            }
        }

        return $value;
    }

    public function hasListeners(string $hook): bool
    {
        return !empty($this->listeners[$hook]);
    }
}
