<?php

declare(strict_types=1);

/**
 * Test Batch Loading Performance Verbesserungen
 */

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Database\Performance\QueryMonitor;
use App\Framework\Database\Repository\BatchLoader;
use App\Framework\Database\Repository\PaginatedResult;

// Bootstrap Framework
require_once __DIR__ . '/../bootstrap.php';

try {
    echo "🧪 Testing Batch Loading Performance Improvements\n";
    echo "=" . str_repeat("=", 55) . "\n\n";

    // Get services from container
    $container = createTestContainer();
    $entityManager = $container->get(\App\Framework\Database\EntityManager::class);
    $queryMonitor = new QueryMonitor();

    // Create BatchLoader
    $batchLoader = new BatchLoader($entityManager);

    echo "✅ Services initialized successfully\n\n";

    // Test 1: PaginatedResult Value Object
    echo "🔍 Test 1: PaginatedResult Value Object\n";
    echo "-" . str_repeat("-", 40) . "\n";

    $mockItems = ['item1', 'item2', 'item3'];
    $paginatedResult = PaginatedResult::fromQuery($mockItems, 100, 2, 10);

    echo "Total Items: {$paginatedResult->totalItems}\n";
    echo "Current Page: {$paginatedResult->currentPage}\n";
    echo "Items per Page: {$paginatedResult->itemsPerPage}\n";
    echo "Total Pages: {$paginatedResult->totalPages}\n";
    echo "Has Next Page: " . ($paginatedResult->hasNextPage() ? 'Yes' : 'No') . "\n";
    echo "Display Range: {$paginatedResult->getDisplayRange()}\n";

    $arrayData = $paginatedResult->toArray();
    echo "Array Export: " . json_encode($arrayData['pagination'], JSON_PRETTY_PRINT) . "\n\n";

    // Test 2: QueryMonitor mit Duration Value Objects
    echo "🔍 Test 2: QueryMonitor mit Duration Value Objects\n";
    echo "-" . str_repeat("-", 40) . "\n";

    // Simuliere verschiedene Queries
    $queryMonitor->logQuery(
        "SELECT * FROM users WHERE id = ?",
        [1],
        Duration::fromMilliseconds(50)
    );

    // Simuliere N+1 Pattern
    for ($i = 1; $i <= 5; $i++) {
        $queryMonitor->logQuery(
            "SELECT * FROM profiles WHERE user_id = ?",
            [$i],
            Duration::fromMilliseconds(25)
        );
    }

    // Simuliere slow query
    $queryMonitor->logQuery(
        "SELECT * FROM large_table WHERE complex_condition = ?",
        ['complex'],
        Duration::fromMilliseconds(150)
    );

    $stats = $queryMonitor->getStatistics();

    echo "Query Statistics:\n";
    echo $stats->getSummary() . "\n\n";

    echo "Detailed Statistics:\n";
    print_r($stats->toArray());
    echo "\n";

    echo "Performance Issues Detected: " . ($stats->hasPerformanceIssues() ? 'Yes' : 'No') . "\n";
    echo "Exceeds 200ms limit: " . ($stats->exceedsTimeLimit(Duration::fromMilliseconds(200)) ? 'Yes' : 'No') . "\n\n";

    // Test 3: Performance Recommendations
    echo "🔍 Test 3: Performance Recommendations\n";
    echo "-" . str_repeat("-", 40) . "\n";

    $recommendations = $queryMonitor->getRecommendations();
    foreach ($recommendations as $rec) {
        echo "⚠️  {$rec['type']} ({$rec['severity']}): {$rec['message']}\n";
        echo "   Impact: {$rec['impact']}\n";
        echo "   Solution: {$rec['solution']}\n\n";
    }

    // Test 4: BatchLoader mit Mock Entity (falls verfügbar)
    echo "🔍 Test 4: BatchLoader Basic Test\n";
    echo "-" . str_repeat("-", 40) . "\n";

    try {
        // Versuche Count-Operation zu testen
        $count = $batchLoader->countBy(\App\Domain\User\User::class, []);
        echo "✅ BatchLoader countBy test successful: $count items\n";

        // Versuche Pagination zu testen
        $paginated = $batchLoader->findPaginated(\App\Domain\User\User::class, 1, 5);
        echo "✅ BatchLoader findPaginated test successful\n";
        echo "   Page 1 of {$paginated->totalPages}, {$paginated->totalItems} total items\n";
        echo "   Range: {$paginated->getDisplayRange()}\n";

    } catch (Exception $e) {
        echo "ℹ️  BatchLoader entity test skipped (no entities found): {$e->getMessage()}\n";
    }

    echo "\n";

    // Test 5: Duration Value Object Integration
    echo "🔍 Test 5: Duration Value Object Integration\n";
    echo "-" . str_repeat("-", 40) . "\n";

    $duration1 = Duration::fromMilliseconds(150);
    $duration2 = Duration::fromSeconds(0.1); // 100ms
    $duration3 = Duration::zero();

    echo "Duration 1: {$duration1->toMilliseconds()}ms\n";
    echo "Duration 2: {$duration2->toMilliseconds()}ms\n";
    echo "Duration 3: {$duration3->toMilliseconds()}ms\n";

    echo "Duration1 > Duration2: " . ($duration1->isGreaterThan($duration2) ? 'Yes' : 'No') . "\n";
    echo "Duration2 > Duration3: " . ($duration2->isGreaterThan($duration3) ? 'Yes' : 'No') . "\n\n";

    echo "🎉 All Batch Loading tests completed successfully!\n\n";

    echo "📋 Summary of Improvements:\n";
    echo "   ✅ BatchLoader with Komposition statt Vererbung\n";
    echo "   ✅ PaginatedResult Value Object\n";
    echo "   ✅ QueryMonitor with Duration Value Objects\n";
    echo "   ✅ N+1 Query Detection\n";
    echo "   ✅ Performance Recommendations\n";
    echo "   ✅ Framework-konforme readonly final Classes\n";

} catch (Exception $e) {
    echo "❌ Test failed with error: " . $e->getMessage() . "\n";
    echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
    exit(1);
}
