<?php

declare(strict_types=1);

namespace Flowaxy\Core\System\Registry;

use Flowaxy\Core\System\ComponentRegistry;
use Flowaxy\Core\Hooks\HookRegistry;
use Flowaxy\Core\Routing\RouteCollection;
use Flowaxy\Core\System\PathResolver;
use Flowaxy\Support\Facades\Log;
use Throwable;

/**
 * Менеджер hot reload для registry, hooks, routes
 * Работает только в dev окружении
 *
 * @package Flowaxy\Core\System\Registry
 */
final class HotReloadManager
{
    private FileWatcher $watcher;
    private int $debounceMs;
    private ?float $lastCheck = null;
    private bool $enabled = false;

    /**
     * @param int $debounceMs Debounce в миллисекундах (500-1000ms)
     */
    public function __construct(int $debounceMs = 750)
    {
        $this->watcher = new FileWatcher();
        $this->debounceMs = $debounceMs;
        $this->enabled = $this->isDevEnvironment();
    }

    /**
     * Проверить, является ли окружение dev
     *
     * @return bool
     */
    private function isDevEnvironment(): bool
    {
        $env = $_ENV['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'production';
        return strtolower($env) === 'dev' || strtolower($env) === 'development';
    }

    /**
     * Инициализация наблюдения за путями
     *
     * @return void
     */
    public function initialize(): void
    {
        if (!$this->enabled) {
            return;
        }

        // Наблюдаем только указанные пути
        $pluginsDir = PathResolver::plugins();
        $this->watcher->watch($pluginsDir . '/*/init.php');

        $routesFile = PathResolver::content() . '/admin/includes/admin-routes.php';
        if (file_exists($routesFile)) {
            $this->watcher->watch($routesFile);
        }

        // Отслеживаем services.json из storage/config/flowaxy
        $servicesFile = PathResolver::storageConfig() . '/flowaxy/services.json';
        if (file_exists($servicesFile)) {
            $this->watcher->watch($servicesFile);
        } else {
            // Fallback для обратной совместимости
            $legacyServicesFile = PathResolver::root() . '/config/flowaxy/services.php';
            if (file_exists($legacyServicesFile)) {
                $this->watcher->watch($legacyServicesFile);
            }
        }
    }

    /**
     * Проверить изменения и перезагрузить при необходимости
     *
     * @return void
     */
    public function checkAndReload(): void
    {
        if (!$this->enabled) {
            return;
        }

        $now = microtime(true) * 1000; // миллисекунды

        // Debounce: проверяем только если прошло достаточно времени
        if ($this->lastCheck !== null && ($now - $this->lastCheck) < $this->debounceMs) {
            return;
        }

        $this->lastCheck = $now;

        $changed = $this->watcher->checkChanges();
        if (empty($changed)) {
            return;
        }

        // Перезагружаем только registry, hooks, routes (НЕ классы)
        try {
            ComponentRegistry::clear();
            HookRegistry::clear();
            RouteCollection::clear();

            try {
                Log::Debug('Hot reload: перезагружены registry, hooks, routes', ['changed_files' => $changed]);
            } catch (Throwable $e) {
                // Ignore logging errors
            }
        } catch (Throwable $e) {
            try {
                Log::Error('Hot reload: ошибка перезагрузки', ['exception' => $e]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
        }
    }
}
