<?php

declare(strict_types=1);

namespace Flowaxy\Infrastructure\Cache;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Domain\Plugin\Services\PluginCacheInterface;
use Flowaxy\Support\Helpers\CacheHelper;
use Throwable;

final class PluginCacheManager implements PluginCacheInterface
{
    public function get(string $pluginSlug, string $key, mixed $default = null): mixed
    {
        return CacheHelper::get('plugin_' . $pluginSlug . '_' . $key, $default);
    }

    public function set(string $pluginSlug, string $key, mixed $value, ?int $ttl = null): bool
    {
        return CacheHelper::set('plugin_' . $pluginSlug . '_' . $key, $value, $ttl);
    }

    public function delete(string $pluginSlug, string $key): bool
    {
        return CacheHelper::forget('plugin_' . $pluginSlug . '_' . $key);
    }

    public function clear(string $pluginSlug): bool
    {
        $this->clearPlugin($pluginSlug);
        return true;
    }

    public function has(string $pluginSlug, string $key): bool
    {
        return CacheHelper::has('plugin_' . $pluginSlug . '_' . $key);
    }

    public function afterInstall(string $slug): void
    {
        $this->forgetActiveLists();
        $this->clearPlugin($slug);
        $this->clearMenus();
    }

    public function afterActivate(string $slug): void
    {
        $this->forgetActiveLists();
        $this->clearPlugin($slug);
        $this->clearMenus();
    }

    public function afterDeactivate(string $slug): void
    {
        $this->forgetActiveLists();
        $this->clearPlugin($slug);
        $this->clearMenus();
    }

    public function afterUninstall(string $slug): void
    {
        $this->forgetActiveLists();
        $this->clearPlugin($slug);
        $this->clearMenus(true);
    }

    private function forgetActiveLists(): void
    {
        $keys = [
            'active_plugins',
            'active_plugins_hash',
            'active_plugins_list',
            'all_plugins_filesystem',
        ];

        CacheHelper::forgetMultiple($keys);
    }

    private function clearPlugin(string $slug): void
    {
        if ($slug === '') {
            return;
        }

        CacheHelper::forget('plugin_data_' . $slug);

        $cacheDir = $this->cacheDir();
        if (! is_dir($cacheDir)) {
            return;
        }

        $patterns = [
            $cacheDir . 'plugin_' . $slug . '_*.cache',
            $cacheDir . $slug . '_*.cache',
        ];

        foreach ($patterns as $pattern) {
            $files = glob($pattern) ?: [];
            foreach ($files as $file) {
                @unlink($file);
            }
        }
    }

    private function clearMenus(bool $full = false): void
    {
        CacheHelper::forget('active_plugins_hash');

        $cacheDir = $this->cacheDir();
        if (is_dir($cacheDir)) {
            $patterns = [
                $cacheDir . 'admin_menu_items_*.cache',
                $cacheDir . 'active_plugins_hash*.cache',
            ];

            foreach ($patterns as $pattern) {
                $files = glob($pattern) ?: [];
                foreach ($files as $file) {
                    @unlink($file);
                }
            }
        }

        if ($full) {
            $legacyPatterns = [
                'admin_menu_items_0',
                'admin_menu_items_1',
                'admin_menu_items_0_0',
                'admin_menu_items_0_1',
                'admin_menu_items_1_0',
                'admin_menu_items_1_1',
            ];

            CacheHelper::forgetMultiple($legacyPatterns);
        }
    }

    private function cacheDir(): string
    {
        return PathResolver::cache() . DS;
    }
}
