<?php

declare(strict_types=1);

namespace Flowaxy\Support\Actions;

use Flowaxy\Support\Helpers\SecurityHelper;
use Flowaxy\Support\Facades\Log;
use Exception;
use Throwable;

// Обработчик действий
// Регистрирует и выполняет действия через паттерн Command
final class ActionHandler
{
    // @var array<string, ActionInterface>
    private array $actions = [];

    // Регистрация действия
    public function register(ActionInterface $action): void
    {
        $this->actions[$action->getName()] = $action;
    }

    // Выполнение действия
    public function execute(string $actionName, array $params = [], bool $checkAccess = true): array
    {
        // Проверка прав доступа
        if ($checkAccess && !SecurityHelper::checkAdminAccess()) {
            return [
                'success' => false,
                'error' => 'У вас немає прав на виконання цієї дії',
            ];
        }

        // Проверка существования действия
        if (!isset($this->actions[$actionName])) {
            return [
                'success' => false,
                'error' => "Дія '{$actionName}' не знайдена",
            ];
        }

        $action = $this->actions[$actionName];

        try {
            // Валидация параметров
            $validation = $action->validate($params);
            if (!$validation['valid']) {
                return [
                    'success' => false,
                    'error' => $validation['error'] ?? 'Помилка валідації параметрів',
                ];
            }

            // Выполнение действия
            $result = $action->execute($params);

            if ($result['success']) {
                Log::Info("Дія виконана успішно", [
                    'action' => $actionName,
                    'description' => $action->getDescription(),
                ]);
            } else {
                Log::Warning("Дія виконана з помилкою", [
                    'action' => $actionName,
                    'error' => $result['error'] ?? 'Невідома помилка',
                ]);
            }

            return $result;
        } catch (Throwable $e) {
            try {
                Log::Error("Помилка виконання дії '{$actionName}'", ['exception' => $e, 'action' => $actionName]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    // Проверка существования действия
    public function hasAction(string $actionName): bool
    {
        return isset($this->actions[$actionName]);
    }

    // Получение списка зарегистрированных действий
    public function getActions(): array
    {
        $actions = [];
        foreach ($this->actions as $name => $action) {
            $actions[$name] = $action->getDescription();
        }
        return $actions;
    }

    // Получение экземпляра действия
    public function getAction(string $actionName): ?ActionInterface
    {
        return $this->actions[$actionName] ?? null;
    }
}
