<?php

namespace AleshaCMS\CMS\Plugin;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
use AleshaCMS\Models\CMS\Plugin;

class PluginManager
{
    protected array $loaded = [];

    public function bootAll(): void
    {
        $active = Cache::remember('cms.active_plugins', 3600, function () {
            return Plugin::where('is_active', true)->pluck('slug')->toArray();
        });

        foreach ($active as $slug) {
            $this->boot($slug);
        }
    }

    public function boot(string $slug): void
    {
        if (!preg_match('/^[A-Za-z0-9_-]+$/', $slug)) {
            return;
        }

        if (isset($this->loaded[$slug])) {
            return;
        }

        $providerClass = $this->getProvider($slug);

        if (!$providerClass || !class_exists($providerClass)) {
            return;
        }

        app()->register($providerClass);
        $this->loaded[$slug] = true;
    }

    protected function getProvider(string $slug): ?string
    {
        $configPath = base_path("Plugins/{$slug}/plugin.json");

        if (!File::exists($configPath)) {
            return null;
        }

        $config = json_decode(File::get($configPath), true);
        return $config['providers'][0] ?? null;
    }

    public function getConfig(string $slug): array
    {
        $configPath = base_path("Plugins/{$slug}/plugin.json");

        if (!File::exists($configPath)) {
            return [];
        }

        return json_decode(File::get($configPath), true) ?? [];
    }

    public function getAvailable(): array
    {
        $pluginsPath = base_path('Plugins');
        $plugins = [];

        if (!File::exists($pluginsPath)) {
            return $plugins;
        }

        $activePlugins = Plugin::pluck('is_active', 'slug')->toArray();

        foreach (File::directories($pluginsPath) as $dir) {
            $slug = basename($dir);
            $configPath = "{$dir}/plugin.json";
            if (!File::exists($configPath)) {
                continue;
            }
            $config = $this->getConfig($slug);
            $plugins[] = array_merge($config, [
                'slug' => $slug,
                'is_active' => $activePlugins[$slug] ?? false,
            ]);
        }

        return $plugins;
    }

    public function activate(string $slug): void
    {
        $config = $this->getConfig($slug);
        Plugin::updateOrCreate(
            ['slug' => $slug],
            [
                'name' => $config['name'] ?? $slug,
                'version' => $config['version'] ?? '1.0.0',
                'is_active' => true,
            ]
        );
        Cache::forget('cms.active_plugins');
    }

    public function deactivate(string $slug): void
    {
        Plugin::where('slug', $slug)->update(['is_active' => false]);
        Cache::forget('cms.active_plugins');
    }
}
