<?php

declare(strict_types=1);

namespace Flowaxy\Domain\Plugin\Services;

use Flowaxy\Support\Facades\Log;
use Throwable;

// Перевірка сумісності плагінів
final class PluginCompatibilityChecker
{
    public function __construct(
        private readonly PluginVersionResolver $versionResolver,
        private readonly PluginRepositoryInterface $pluginRepository
    ) {
    }

    public function checkCompatibility(string $pluginSlug, array $pluginConfig): array
    {
        $errors = [];
        $warnings = [];

        $pluginVersion = $pluginConfig['version'] ?? '1.0.0';
        $minEngineVersion = $pluginConfig['requires']['flowaxy'] ?? $pluginConfig['requires']['engine'] ?? null;
        $maxEngineVersion = $pluginConfig['requires']['flowaxy_max'] ?? $pluginConfig['requires']['engine_max'] ?? null;
        $currentEngineVersion = $this->versionResolver->getCurrentEngineVersion();

        $engineCheck = $this->versionResolver->checkEngineCompatibility(
            $pluginVersion,
            $minEngineVersion,
            $maxEngineVersion,
            $currentEngineVersion
        );

        if (!$engineCheck['compatible']) {
            $errors = [...$errors, ...$engineCheck['errors']];
        }
        $warnings = [...$warnings, ...$engineCheck['warnings']];

        $dependencies = $pluginConfig['requires']['plugins'] ?? $pluginConfig['dependencies'] ?? [];
        if (!empty($dependencies)) {
            $installedPlugins = $this->getInstalledPluginsVersions();
            $depsCheck = $this->versionResolver->checkDependencies($dependencies, $installedPlugins);

            if (!$depsCheck['compatible']) {
                $errors = [...$errors, ...$depsCheck['errors']];
            }
        }

        if (!empty($errors)) {
            try {
                Log::Warning('Плагін несумісний', [
                    'plugin_slug' => $pluginSlug,
                    'errors' => $errors,
                ]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
        }

        return [
            'compatible' => empty($errors),
            'errors' => $errors,
            'warnings' => $warnings,
        ];
    }

    private function getInstalledPluginsVersions(): array
    {
        try {
            $plugins = $this->pluginRepository->all();
            $versions = [];

            foreach ($plugins as $plugin) {
                $versions[$plugin->slug] = $plugin->version;
            }

            return $versions;
        } catch (Throwable $e) {
            try {
                Log::Error('Помилка отримання версій встановлених плагінів', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return [];
        }
    }
}
