isLoggedIn()) { throw new Exception('Unauthorized'); } $db = Database::getInstance(); // Get current analysis state $stateQuery = $db->query("SELECT * FROM optimization_analysis_state ORDER BY id DESC LIMIT 1"); $state = $stateQuery ? $stateQuery->fetch_assoc() : null; // Get real-time counts from panel_directives table $totalQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives"); $totalCombinations = $totalQuery ? $totalQuery->fetch_assoc()['count'] : 0; $processedQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE llm_checked = 1"); $processedCount = $processedQuery ? $processedQuery->fetch_assoc()['count'] : 0; $impossibleQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE is_impossible = 1 AND llm_checked = 1"); $impossibleCount = $impossibleQuery ? $impossibleQuery->fetch_assoc()['count'] : 0; $possibleQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE is_impossible = 0 AND llm_checked = 1"); $possibleCount = $possibleQuery ? $possibleQuery->fetch_assoc()['count'] : 0; $pendingQuery = $db->query("SELECT COUNT(*) as count FROM panel_directives WHERE llm_checked = 0"); $pendingCount = $pendingQuery ? $pendingQuery->fetch_assoc()['count'] : 0; // Calculate progress percentage $progressPercent = $totalCombinations > 0 ? ($processedCount / $totalCombinations) * 100 : 0; // Update state table if different if ($state) { if ($processedCount != $state['processed_combinations'] || $totalCombinations != $state['total_combinations']) { $stmt = $db->prepare(" UPDATE optimization_analysis_state SET total_combinations = ?, processed_combinations = ?, last_updated = NOW() WHERE id = ? "); $stmt->bind_param('iii', $totalCombinations, $processedCount, $state['id']); $stmt->execute(); } // Check if analysis should be marked as complete if ($state['is_running'] && $processedCount >= $totalCombinations && $totalCombinations > 0) { $stmt = $db->prepare(" UPDATE optimization_analysis_state SET is_running = 0, completed_at = NOW() WHERE id = ? "); $stmt->bind_param('i', $state['id']); $stmt->execute(); $state['is_running'] = 0; $state['completed_at'] = date('Y-m-d H:i:s'); } } // Get processing rate (combinations per minute) $processingRate = 0; if ($state && $state['started_at']) { $startTime = strtotime($state['started_at']); $currentTime = time(); $elapsedMinutes = max(1, ($currentTime - $startTime) / 60); $processingRate = $processedCount / $elapsedMinutes; } // Estimate time remaining $estimatedTimeRemaining = null; if ($processingRate > 0 && $pendingCount > 0) { $remainingMinutes = $pendingCount / $processingRate; $estimatedTimeRemaining = [ 'minutes' => round($remainingMinutes), 'formatted' => formatTime($remainingMinutes) ]; } // Get some recent results for activity indicator $recentQuery = $db->query(" SELECT attribute1_name, choice1, attribute2_name, choice2, is_impossible, llm_reasoning FROM panel_directives WHERE llm_checked = 1 ORDER BY updated_at DESC LIMIT 3 "); $recentResults = []; if ($recentQuery) { while ($row = $recentQuery->fetch_assoc()) { $recentResults[] = [ 'combination' => "{$row['attribute1_name']}={$row['choice1']} + {$row['attribute2_name']}={$row['choice2']}", 'is_impossible' => (bool)$row['is_impossible'], 'reasoning' => substr($row['llm_reasoning'] ?? '', 0, 100) . '...' ]; } } echo json_encode([ 'success' => true, 'progress' => [ 'total_combinations' => (int)$totalCombinations, 'processed_combinations' => (int)$processedCount, 'impossible_combinations' => (int)$impossibleCount, 'possible_combinations' => (int)$possibleCount, 'pending_combinations' => (int)$pendingCount, 'progress_percent' => round($progressPercent, 2), 'is_running' => $state ? (bool)$state['is_running'] : false, 'started_at' => $state ? $state['started_at'] : null, 'completed_at' => $state ? $state['completed_at'] : null, 'processing_rate' => round($processingRate, 2), 'estimated_time_remaining' => $estimatedTimeRemaining, 'recent_results' => $recentResults ] ]); } catch (Exception $e) { http_response_code(500); echo json_encode([ 'success' => false, 'error' => $e->getMessage() ]); } function formatTime($minutes) { if ($minutes < 60) { return round($minutes) . ' minutes'; } elseif ($minutes < 1440) { $hours = floor($minutes / 60); $mins = round($minutes % 60); return $hours . 'h ' . $mins . 'm'; } else { $days = floor($minutes / 1440); $hours = floor(($minutes % 1440) / 60); return $days . 'd ' . $hours . 'h'; } } ?>