<?php

declare(strict_types=1);

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

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Database\Profiling\QueryAnalyzer;
use App\Framework\Database\Profiling\QueryProfile;

echo "=== Testing Database Query Optimization Tools ===\n\n";

echo "1. Testing Query Analysis System:\n";

try {
    // Create mock connection for analyzer
    $mockConnection = new class () {
        public function query(string $sql)
        {
            // Mock implementation that returns a result-like object
            return new class () {
                public function fetch()
                {
                    static $called = false;
                    if (! $called) {
                        $called = true;

                        return [
                            'id' => 1,
                            'select_type' => 'SIMPLE',
                            'table' => 'users',
                            'type' => 'ALL',
                            'key' => null,
                            'rows' => 1000,
                        ];
                    }

                    return false;
                }
            };
        }

        public function queryScalar(string $sql)
        {
            return '{"Plan": {"Node Type": "Seq Scan", "Relation Name": "users"}}';
        }
    };

    $analyzer = new QueryAnalyzer($mockConnection);

    echo "   ✅ QueryAnalyzer created successfully\n\n";

} catch (\Throwable $e) {
    echo "   ❌ Error creating QueryAnalyzer: {$e->getMessage()}\n\n";
}

echo "2. Testing Query Analysis with Different Query Types:\n";

$testQueries = [
    [
        'name' => 'Simple SELECT',
        'sql' => 'SELECT id, name FROM users WHERE active = 1',
        'execution_time_ms' => 25.5,
        'memory_usage' => 512000,
    ],
    [
        'name' => 'SELECT with wildcard',
        'sql' => 'SELECT * FROM users WHERE email LIKE "%@example.com"',
        'execution_time_ms' => 1250.0,
        'memory_usage' => 5242880,
    ],
    [
        'name' => 'Complex JOIN query',
        'sql' => 'SELECT u.*, p.name as profile_name FROM users u LEFT JOIN profiles p ON u.id = p.user_id LEFT JOIN settings s ON u.id = s.user_id WHERE u.active = 1 ORDER BY u.created_at DESC',
        'execution_time_ms' => 2100.7,
        'memory_usage' => 10485760,
    ],
    [
        'name' => 'Subquery with aggregation',
        'sql' => 'SELECT COUNT(*) FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > (SELECT AVG(total) FROM orders))',
        'execution_time_ms' => 3500.2,
        'memory_usage' => 15728640,
    ],
    [
        'name' => 'Optimized query',
        'sql' => 'SELECT id, email FROM users WHERE created_at >= ? AND status = ? LIMIT 100',
        'execution_time_ms' => 15.3,
        'memory_usage' => 204800,
    ],
];

foreach ($testQueries as $testQuery) {
    try {
        echo "   🔍 Analyzing: {$testQuery['name']}\n";

        // Create a QueryProfile for testing
        $profile = new class (
            $testQuery['sql'],
            $testQuery['execution_time_ms'],
            $testQuery['memory_usage']
        ) {
            public string $id;

            public object $query;

            public Duration $executionTime;

            public object $startTimestamp;

            public object $endTimestamp;

            public int $memoryUsage;

            public function __construct(string $sql, float $executionTimeMs, int $memoryUsage)
            {
                $this->id = uniqid('query_');
                $this->query = new class ($sql) {
                    public function __construct(public string $sql)
                    {
                    }
                };
                $this->executionTime = Duration::fromMilliseconds($executionTimeMs);
                $this->startTimestamp = new class () {
                    public function __construct()
                    {
                    }
                };
                $this->endTimestamp = new class () {
                    public function __construct()
                    {
                    }
                };
                $this->memoryUsage = $memoryUsage;
            }

            public function getComplexityScore(): int
            {
                $sql = strtoupper($this->query->sql);
                $complexity = 0;
                $complexity += substr_count($sql, 'JOIN') * 2;
                $complexity += substr_count($sql, 'SELECT') - 1;
                $complexity += substr_count($sql, 'UNION') * 3;
                $complexity += substr_count($sql, 'GROUP BY') * 2;
                $complexity += substr_count($sql, 'ORDER BY');
                $complexity += substr_count($sql, 'SUBQUERY') * 4;

                return max(1, $complexity);
            }
        };

        $analysis = $analyzer->analyzeQuery($profile);

        echo "      • SQL: " . substr($testQuery['sql'], 0, 60) . (strlen($testQuery['sql']) > 60 ? '...' : '') . "\n";
        echo "      • Execution time: {$testQuery['execution_time_ms']}ms\n";
        echo "      • Memory usage: " . number_format($testQuery['memory_usage'] / 1024 / 1024, 2) . " MB\n";
        echo "      • Optimization Score: {$analysis->optimizationScore}/100\n";
        echo "      • Issues found: " . count($analysis->issues) . "\n";
        echo "      • Suggestions: " . count($analysis->suggestions) . "\n";

        if (! empty($analysis->issues)) {
            echo "      • Top issue: {$analysis->issues[0]}\n";
        }

        if (! empty($analysis->suggestions)) {
            echo "      • Top suggestion: {$analysis->suggestions[0]}\n";
        }

        if (! empty($analysis->indexRecommendations)) {
            echo "      • Index recommendation: {$analysis->indexRecommendations[0]}\n";
        }

        echo "\n";

    } catch (\Throwable $e) {
        echo "      ❌ Error analyzing query: {$e->getMessage()}\n\n";
    }
}

echo "3. Testing Batch Analysis and Summary:\n";

try {
    // Create profiles for batch analysis
    $profiles = [];
    foreach ($testQueries as $i => $testQuery) {
        $profiles[] = new class (
            $testQuery['sql'],
            $testQuery['execution_time_ms'],
            $testQuery['memory_usage'],
            $i
        ) {
            public string $id;

            public object $query;

            public Duration $executionTime;

            public object $startTimestamp;

            public object $endTimestamp;

            public int $memoryUsage;

            public function __construct(string $sql, float $executionTimeMs, int $memoryUsage, int $index)
            {
                $this->id = "query_{$index}";
                $this->query = new class ($sql) {
                    public function __construct(public string $sql)
                    {
                    }
                };
                $this->executionTime = Duration::fromMilliseconds($executionTimeMs);
                $this->startTimestamp = new class () {
                    public function __construct()
                    {
                    }
                };
                $this->endTimestamp = new class () {
                    public function __construct()
                    {
                    }
                };
                $this->memoryUsage = $memoryUsage;
            }

            public function getComplexityScore(): int
            {
                $sql = strtoupper($this->query->sql);
                $complexity = 0;
                $complexity += substr_count($sql, 'JOIN') * 2;
                $complexity += substr_count($sql, 'SELECT') - 1;
                $complexity += substr_count($sql, 'UNION') * 3;
                $complexity += substr_count($sql, 'GROUP BY') * 2;
                $complexity += substr_count($sql, 'ORDER BY');

                return max(1, $complexity);
            }
        };
    }

    $batchAnalyses = $analyzer->batchAnalyze($profiles);
    $summary = $analyzer->getOptimizationSummary($batchAnalyses);

    echo "   📊 Batch Analysis Summary:\n";
    echo "      • Total queries analyzed: {$summary['total_queries_analyzed']}\n";
    echo "      • Average optimization score: {$summary['average_optimization_score']}/100\n";
    echo "      • Total issues: {$summary['total_issues']}\n";
    echo "      • Total suggestions: {$summary['total_suggestions']}\n";
    echo "      • Overall assessment: {$summary['overall_assessment']}\n\n";

    echo "   🔥 Most Common Issues:\n";
    foreach ($summary['most_common_issues'] as $issue => $count) {
        echo "      • {$issue} (occurred {$count} times)\n";
    }
    echo "\n";

    echo "   💡 Most Common Suggestions:\n";
    foreach ($summary['most_common_suggestions'] as $suggestion => $count) {
        echo "      • {$suggestion} (suggested {$count} times)\n";
    }
    echo "\n";

} catch (\Throwable $e) {
    echo "   ❌ Error in batch analysis: {$e->getMessage()}\n\n";
}

echo "4. Testing Individual Query Analysis Patterns:\n";

$specialTestCases = [
    [
        'name' => 'N+1 Pattern Detection',
        'queries' => [
            'SELECT * FROM users',
            'SELECT * FROM profiles WHERE user_id = 1',
            'SELECT * FROM profiles WHERE user_id = 2',
            'SELECT * FROM profiles WHERE user_id = 3',
            'SELECT * FROM profiles WHERE user_id = 4',
            'SELECT * FROM profiles WHERE user_id = 5',
        ],
    ],
    [
        'name' => 'Index Opportunity Detection',
        'queries' => [
            'SELECT * FROM orders WHERE customer_id = 123',
            'SELECT * FROM orders WHERE customer_id = 456',
            'SELECT * FROM orders WHERE customer_id = 789',
            'SELECT * FROM products WHERE category_id = 10',
            'SELECT * FROM products WHERE category_id = 20',
        ],
    ],
];

foreach ($specialTestCases as $testCase) {
    echo "   🔍 Testing: {$testCase['name']}\n";

    $queryGroups = [];
    foreach ($testCase['queries'] as $sql) {
        // Normalize SQL for pattern detection
        $normalized = preg_replace('/\b\d+\b/', '?', $sql);
        $normalized = preg_replace('/\s+/', ' ', trim($normalized));
        $queryGroups[$normalized][] = $sql;
    }

    foreach ($queryGroups as $pattern => $queries) {
        if (count($queries) > 1) {
            echo "      • Pattern detected: " . substr($pattern, 0, 50) . "...\n";
            echo "      • Execution count: " . count($queries) . "\n";
            echo "      • Recommendation: ";

            if (str_contains($pattern, 'profiles WHERE user_id')) {
                echo "Use eager loading to avoid N+1 queries\n";
            } elseif (str_contains($pattern, 'WHERE customer_id') || str_contains($pattern, 'WHERE category_id')) {
                echo "Consider adding index on the WHERE clause column\n";
            } else {
                echo "Review for optimization opportunities\n";
            }
        }
    }
    echo "\n";
}

echo "5. Testing Performance Assessment:\n";

$performanceTests = [
    ['score' => 95, 'expected' => 'excellent'],
    ['score' => 80, 'expected' => 'good'],
    ['score' => 65, 'expected' => 'fair'],
    ['score' => 45, 'expected' => 'poor'],
    ['score' => 25, 'expected' => 'critical'],
];

foreach ($performanceTests as $test) {
    $assessment = match (true) {
        $test['score'] >= 90 => 'excellent',
        $test['score'] >= 75 => 'good',
        $test['score'] >= 60 => 'fair',
        $test['score'] >= 40 => 'poor',
        default => 'critical'
    };

    $status = $assessment === $test['expected'] ? '✅' : '❌';
    echo "   {$status} Score {$test['score']}: {$assessment} (expected: {$test['expected']})\n";
}

echo "\n=== Database Query Optimization Tools Test Completed ===\n";
