<?php

declare(strict_types=1);

namespace Flowaxy\Support\Services;

use Exception;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Support\Helpers\ManagerHelper;
use Flowaxy\Support\Managers\PluginManager;
use Throwable;

use function class_exists;
use function method_exists;

// Сервис для работы с плагинами
// Инкапсулирует логику работы с плагинами с обработкой ошибок
final class PluginService
{
    // Получение менеджера плагинов
    private function getPluginManager(): ?PluginManager
    {
        return ManagerHelper::pluginManager();
    }

    // Установка плагина
    public function install(string $pluginSlug): bool
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            throw new Exception('PluginManager не доступний');
        }

        try {
            $result = $pluginManager->installPlugin($pluginSlug);
            if ($result) {
                Log::Info('Плагін встановлено', ['plugin' => $pluginSlug]);
            } else {
                try {
                    Log::Warning('Помилка встановлення плагіна', ['plugin' => $pluginSlug]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
            }
            return $result;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка встановлення плагіна', ['exception' => $e, 'plugin' => $pluginSlug]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    // Активация плагина
    public function activate(string $pluginSlug, bool $autoInstallDependencies = false): bool
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            throw new Exception('PluginManager не доступний');
        }

        try {
            $result = $pluginManager->activatePlugin($pluginSlug, $autoInstallDependencies);
            if ($result) {
                Log::Info('Плагін активовано', ['plugin' => $pluginSlug]);
            } else {
                try {
                    Log::Warning('Помилка активації плагіна', ['plugin' => $pluginSlug]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
            }
            return $result;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка активації плагіна', ['exception' => $e, 'plugin' => $pluginSlug]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    // Деактивация плагина
    public function deactivate(string $pluginSlug): bool
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            throw new Exception('PluginManager не доступний');
        }

        try {
            $result = $pluginManager->deactivatePlugin($pluginSlug);
            if ($result) {
                Log::Info('Плагін деактивовано', ['plugin' => $pluginSlug]);
            } else {
                try {
                    Log::Warning('Помилка деактивації плагіна', ['plugin' => $pluginSlug]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
            }
            return $result;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка деактивації плагіна', ['exception' => $e, 'plugin' => $pluginSlug]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    // Удаление плагина
    public function uninstall(string $pluginSlug): bool
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            throw new Exception('PluginManager не доступний');
        }

        try {
            $result = $pluginManager->uninstallPlugin($pluginSlug);
            if ($result) {
                Log::Info('Плагін видалено', ['plugin' => $pluginSlug]);
            } else {
                try {
                    Log::Warning('Помилка видалення плагіна', ['plugin' => $pluginSlug]);
                } catch (Throwable $logError) {
                    // Ignore logging errors
                }
            }
            return $result;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка видалення плагіна', ['exception' => $e, 'plugin' => $pluginSlug]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    // Автоматическое обнаружение новых плагинов
    public function discover(): int
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            throw new Exception('PluginManager не доступний');
        }

        try {
            $count = $pluginManager->autoDiscoverPlugins();
            if ($count > 0) {
                Log::Info('Обнаружено новых плагинов', ['count' => $count]);
            }
            return $count;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка виявлення плагінів', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return 0;
        }
    }

    // Проверка, установлен ли плагин
    public function isInstalled(string $pluginSlug): bool
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            return false;
        }

        return $pluginManager->isPluginInstalled($pluginSlug);
    }

    // Проверка, активен ли плагин
    public function isActive(string $pluginSlug): bool
    {
        $pluginManager = $this->getPluginManager();
        if (!$pluginManager) {
            return false;
        }

        return $pluginManager->isPluginActive($pluginSlug);
    }
}
