<?php

/**
 * Minimal Hot Reload Endpoint
 * Simple SSE implementation without complex framework dependencies
 */

declare(strict_types=1);

// Disable deprecation warnings
error_reporting(E_ALL & ~E_DEPRECATED);
ini_set('display_errors', 1);

// Simple .env parsing
function loadEnvVar(string $key, string $envFile = null): ?string {
    $envFile ??= __DIR__ . '/../.env';
    if (!file_exists($envFile)) {
        return null;
    }
    
    $content = file_get_contents($envFile);
    if (preg_match("/^{$key}\s*=\s*(.*)$/m", $content, $matches)) {
        return trim($matches[1], " \t\n\r\0\x0B\"'");
    }
    
    return null;
}

// Only allow in development
$appDebug = loadEnvVar('APP_DEBUG');
if ($appDebug !== 'true') {
    http_response_code(403);
    exit('Hot Reload is only available in development mode');
}

// Set SSE headers
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('X-Accel-Buffering: no'); // Disable nginx buffering

// Get watched directories
$watchedDirs = [
    __DIR__ . '/../src',
    __DIR__ . '/../resources/views',
    __DIR__ . '/../config',
];

// Store file modification times
$fileCache = [];

// Function to scan directories for PHP files
function scanDirectory(string $dir, array &$fileCache): array {
    $changes = [];
    
    if (!is_dir($dir)) {
        return $changes;
    }
    
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );
    
    foreach ($iterator as $file) {
        if (!$file->isFile()) {
            continue;
        }
        
        $path = $file->getPathname();
        
        // Only watch specific file types
        if (!preg_match('/\.(php|view\.php|css|js|ts)$/', $path)) {
            continue;
        }
        
        $mtime = $file->getMTime();
        
        if (!isset($fileCache[$path])) {
            $fileCache[$path] = $mtime;
        } elseif ($fileCache[$path] < $mtime) {
            $changes[] = [
                'path' => $path,
                'type' => 'modified',
                'time' => $mtime
            ];
            $fileCache[$path] = $mtime;
        }
    }
    
    return $changes;
}

// Send initial connection event
echo "event: connected\n";
echo "data: " . json_encode([
    'status' => 'connected',
    'timestamp' => date('c'),
    'message' => 'Hot Reload server started'
]) . "\n\n";
flush();

// Initialize file cache
foreach ($watchedDirs as $dir) {
    scanDirectory($dir, $fileCache);
}

$lastHeartbeat = time();

// Keep connection alive and watch for changes
while (connection_aborted() === 0) {
    $hasChanges = false;
    
    // Check each watched directory
    foreach ($watchedDirs as $dir) {
        $changes = scanDirectory($dir, $fileCache);
        
        foreach ($changes as $change) {
            $reloadType = 'full';
            if (str_ends_with($change['path'], '.css')) {
                $reloadType = 'css';
            } elseif (str_ends_with($change['path'], '.js') || str_ends_with($change['path'], '.ts')) {
                $reloadType = 'hmr';
            }
            
            echo "event: reload\n";
            echo "data: " . json_encode([
                'type' => $reloadType,
                'file' => basename($change['path']),
                'path' => $change['path'],
                'timestamp' => date('c'),
                'message' => 'File changed: ' . basename($change['path'])
            ]) . "\n\n";
            flush();
            
            $hasChanges = true;
        }
    }
    
    // Send heartbeat every 30 seconds
    if (time() - $lastHeartbeat >= 30) {
        echo "event: heartbeat\n";
        echo "data: " . json_encode([
            'timestamp' => date('c'),
            'message' => 'Connection alive'
        ]) . "\n\n";
        flush();
        $lastHeartbeat = time();
    }
    
    // Small delay to prevent high CPU usage
    usleep(500000); // 500ms
}