<?php

declare(strict_types=1);

namespace App\Framework\Mcp\Tools\Categories\Database;

use App\Framework\Database\ConnectionInterface;
use App\Framework\Database\Profiling\ProfilingDashboard;
use App\Framework\Database\Profiling\QueryAnalyzer;
use App\Framework\Database\Profiling\QueryProfiler;
use App\Framework\Database\Profiling\SlowQueryDetector;
use App\Framework\Mcp\Attributes\McpTool;
use App\Framework\Mcp\Core\Services\McpToolContext;

final readonly class DatabaseOptimizationTools
{
    public function __construct(
        private McpToolContext $context,
        private QueryAnalyzer $queryAnalyzer,
        private QueryProfiler $queryProfiler,
        private SlowQueryDetector $slowQueryDetector,
        private ProfilingDashboard $profilingDashboard,
        private ConnectionInterface $connection
    ) {
    }

    #[McpTool(
        name: 'analyze_slow_queries',
        description: 'Analyze slow queries and provide optimization recommendations with multiple output formats',
        category: 'Database',
        tags: ['optimization', 'performance', 'slow-queries'],
        cacheable: true,
        defaultCacheTtl: 300
    )]
    public function analyzeSlowQueries(int $limit = 10, string $format = 'array'): array
    {
        try {
            $result = $this->performSlowQueryAnalysis($limit);

            return $this->context->formatResult($result, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'analyze_slow_queries',
                'limit' => $limit,
                'format' => $format,
            ]);
        }
    }

    #[McpTool(
        name: 'analyze_single_query',
        description: 'Analyze a specific SQL query for optimization opportunities with detailed reporting',
        category: 'Database',
        tags: ['optimization', 'analysis', 'sql'],
        cacheable: false
    )]
    public function analyzeSingleQuery(string $sql, string $format = 'array'): array
    {
        try {
            $result = $this->performSingleQueryAnalysis($sql);

            return $this->context->formatResult($result, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'analyze_single_query',
                'sql' => substr($sql, 0, 100) . '...',
                'format' => $format,
            ]);
        }
    }

    #[McpTool(
        name: 'get_query_performance_summary',
        description: 'Get overall database performance summary with comprehensive metrics',
        category: 'Database',
        tags: ['performance', 'dashboard', 'metrics'],
        cacheable: true,
        defaultCacheTtl: 120
    )]
    public function getQueryPerformanceSummary(string $format = 'array'): array
    {
        try {
            $result = $this->profilingDashboard->getDashboardData();
            $enhancedResult = $this->enhancePerformanceSummary($result);

            return $this->context->formatResult($enhancedResult, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'get_query_performance_summary',
                'format' => $format,
            ]);
        }
    }

    #[McpTool(
        name: 'detect_n_plus_one_patterns',
        description: 'Detect potential N+1 query patterns with smart pattern recognition',
        category: 'Database',
        tags: ['optimization', 'n-plus-one', 'patterns'],
        cacheable: true,
        defaultCacheTtl: 180
    )]
    public function detectNPlusOnePatterns(int $lookbackQueries = 100, string $format = 'array'): array
    {
        try {
            $result = $this->performNPlusOneDetection($lookbackQueries);

            return $this->context->formatResult($result, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'detect_n_plus_one_patterns',
                'lookback_queries' => $lookbackQueries,
                'format' => $format,
            ]);
        }
    }

    #[McpTool(
        name: 'get_index_recommendations',
        description: 'Get index recommendations based on query patterns with priority scoring',
        category: 'Database',
        tags: ['optimization', 'indexes', 'recommendations'],
        cacheable: true,
        defaultCacheTtl: 600
    )]
    public function getIndexRecommendations(int $queryLimit = 50, string $format = 'array'): array
    {
        try {
            $result = $this->generateIndexRecommendations($queryLimit);

            return $this->context->formatResult($result, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'get_index_recommendations',
                'query_limit' => $queryLimit,
                'format' => $format,
            ]);
        }
    }

    #[McpTool(
        name: 'get_database_health_metrics',
        description: 'Get comprehensive database health and performance metrics with trend analysis',
        category: 'Database',
        tags: ['health', 'metrics', 'monitoring'],
        cacheable: true,
        defaultCacheTtl: 60
    )]
    public function getDatabaseHealthMetrics(string $format = 'array'): array
    {
        try {
            $result = $this->calculateDatabaseHealthMetrics();

            return $this->context->formatResult($result, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'get_database_health_metrics',
                'format' => $format,
            ]);
        }
    }

    #[McpTool(
        name: 'analyze_query_complexity',
        description: 'Analyze query complexity patterns and suggest optimizations',
        category: 'Database',
        tags: ['complexity', 'analysis', 'optimization'],
        cacheable: true,
        defaultCacheTtl: 300
    )]
    public function analyzeQueryComplexity(int $queryLimit = 25, string $format = 'array'): array
    {
        try {
            $result = $this->performComplexityAnalysis($queryLimit);

            return $this->context->formatResult($result, $format);
        } catch (\Throwable $e) {
            return $this->context->handleError($e, [
                'operation' => 'analyze_query_complexity',
                'query_limit' => $queryLimit,
                'format' => $format,
            ]);
        }
    }

    private function performSlowQueryAnalysis(int $limit): array
    {
        $profiles = $this->queryProfiler->getSlowQueries($limit);
        $analyses = $this->queryAnalyzer->batchAnalyze($profiles);

        $detailedAnalyses = array_map(function ($analysis) {
            return [
                'query_id' => $analysis->profile->id,
                'sql' => $analysis->profile->query->sql,
                'execution_time_ms' => $analysis->profile->executionTime->toMilliseconds(),
                'optimization_score' => $analysis->optimizationScore,
                'issues' => $analysis->issues,
                'suggestions' => $analysis->suggestions,
                'index_recommendations' => $analysis->indexRecommendations,
                'complexity_score' => $analysis->profile->getComplexityScore(),
                'assessment' => $this->getAssessment($analysis->optimizationScore),
                'priority' => $this->calculateOptimizationPriority($analysis),
            ];
        }, $analyses);

        // Sort by priority and execution time
        usort($detailedAnalyses, function ($a, $b) {
            $priorityOrder = ['Critical' => 4, 'High' => 3, 'Medium' => 2, 'Low' => 1];
            $aPriority = $priorityOrder[$a['priority']] ?? 0;
            $bPriority = $priorityOrder[$b['priority']] ?? 0;

            if ($aPriority === $bPriority) {
                return $b['execution_time_ms'] <=> $a['execution_time_ms'];
            }

            return $bPriority <=> $aPriority;
        });

        return [
            'total_slow_queries' => count($profiles),
            'analyses' => $detailedAnalyses,
            'summary' => $this->queryAnalyzer->getOptimizationSummary($analyses),
            'performance_impact' => $this->calculatePerformanceImpact($detailedAnalyses),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    private function performSingleQueryAnalysis(string $sql): array
    {
        $profile = $this->createTempProfile($sql);
        $analysis = $this->queryAnalyzer->analyzeQuery($profile);

        return [
            'sql' => $sql,
            'query_hash' => md5($sql),
            'optimization_score' => $analysis->optimizationScore,
            'issues' => $analysis->issues,
            'suggestions' => $analysis->suggestions,
            'index_recommendations' => $analysis->indexRecommendations,
            'execution_plan' => $analysis->executionPlan,
            'complexity_analysis' => [
                'score' => $profile->getComplexityScore(),
                'factors' => $this->analyzeComplexityFactors($sql),
                'readability' => $this->assessQueryReadability($sql),
            ],
            'assessment' => $this->getAssessment($analysis->optimizationScore),
            'optimization_potential' => $this->calculateOptimizationPotential($analysis),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    private function performNPlusOneDetection(int $lookbackQueries): array
    {
        $recentProfiles = $this->queryProfiler->getRecentProfiles($lookbackQueries);
        $patterns = [];
        $queryGroups = [];

        // Group similar queries with enhanced pattern detection
        foreach ($recentProfiles as $profile) {
            $normalizedSql = $this->normalizeSqlForPattern($profile->query->sql);
            $queryGroups[$normalizedSql][] = $profile;
        }

        // Enhanced N+1 detection logic
        foreach ($queryGroups as $normalizedSql => $profiles) {
            if (count($profiles) > 5) { // Lower threshold for better detection
                $avgExecutionTime = array_sum(array_map(
                    fn ($p) => $p->executionTime->toMilliseconds(),
                    $profiles
                )) / count($profiles);

                $totalTime = array_sum(array_map(
                    fn ($p) => $p->executionTime->toMilliseconds(),
                    $profiles
                ));

                $likelihood = $this->calculateNPlusOneLikelihood($profiles);
                $impact = $this->calculatePatternImpact($profiles, $totalTime);

                $patterns[] = [
                    'pattern' => $normalizedSql,
                    'sample_query' => $profiles[0]->query->sql,
                    'execution_count' => count($profiles),
                    'avg_execution_time_ms' => round($avgExecutionTime, 2),
                    'total_time_ms' => round($totalTime, 2),
                    'likelihood_n_plus_one' => $likelihood,
                    'impact_level' => $impact,
                    'recommendation' => $this->generateNPlusOneRecommendation($normalizedSql, count($profiles)),
                    'optimization_savings' => $this->estimateOptimizationSavings($profiles),
                ];
            }
        }

        usort($patterns, fn ($a, $b) => $b['total_time_ms'] <=> $a['total_time_ms']);

        return [
            'detected_patterns' => array_slice($patterns, 0, 15),
            'total_patterns_found' => count($patterns),
            'analysis_period' => "Last {$lookbackQueries} queries",
            'detection_summary' => $this->summarizeNPlusOneDetection($patterns),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    private function generateIndexRecommendations(int $queryLimit): array
    {
        $profiles = $this->queryProfiler->getSlowQueries($queryLimit);
        $indexRecommendations = [];
        $columnFrequency = [];
        $tableFrequency = [];

        foreach ($profiles as $profile) {
            $analysis = $this->queryAnalyzer->analyzeQuery($profile);

            foreach ($analysis->indexRecommendations as $recommendation) {
                if (preg_match('/column:\s*(\w+)/', $recommendation, $matches)) {
                    $column = $matches[1];
                    $columnFrequency[$column] = ($columnFrequency[$column] ?? 0) + 1;
                }

                if (preg_match('/table:\s*(\w+)/', $recommendation, $matches)) {
                    $table = $matches[1];
                    $tableFrequency[$table] = ($tableFrequency[$table] ?? 0) + 1;
                }
            }
        }

        arsort($columnFrequency);

        foreach ($columnFrequency as $column => $frequency) {
            $priority = $this->calculateIndexPriority($frequency, count($profiles));
            $impact = $this->estimateIndexImpact($frequency, count($profiles));

            $indexRecommendations[] = [
                'column' => $column,
                'frequency' => $frequency,
                'priority' => $priority,
                'sql_suggestion' => "CREATE INDEX idx_{$column} ON table_name ({$column});",
                'impact_estimate' => $impact,
                'performance_gain' => $this->estimatePerformanceGain($frequency, count($profiles)),
                'composite_potential' => $this->findCompositeIndexOpportunities($column, $columnFrequency),
            ];
        }

        return [
            'recommendations' => array_slice($indexRecommendations, 0, 12),
            'total_recommendations' => count($indexRecommendations),
            'analysis_based_on' => count($profiles) . ' slow queries',
            'table_analysis' => $this->analyzeTableIndexNeeds($tableFrequency),
            'implementation_priority' => $this->prioritizeIndexImplementation($indexRecommendations),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    private function calculateDatabaseHealthMetrics(): array
    {
        $profiles = $this->queryProfiler->getAllProfiles();
        $slowQueries = $this->queryProfiler->getSlowQueries(100);

        $totalQueries = count($profiles);
        $slowQueryCount = count($slowQueries);
        $slowQueryPercentage = $totalQueries > 0 ? ($slowQueryCount / $totalQueries) * 100 : 0;

        $avgExecutionTime = $totalQueries > 0 ? array_sum(array_map(
            fn ($p) => $p->executionTime->toMilliseconds(),
            $profiles
        )) / $totalQueries : 0;

        $queryTypes = [];
        foreach ($profiles as $profile) {
            $type = $profile->getQueryType();
            $queryTypes[$type] = ($queryTypes[$type] ?? 0) + 1;
        }

        $overallHealth = $this->calculateDatabaseHealth($slowQueryPercentage, $avgExecutionTime);
        $recommendations = $this->getHealthRecommendations($slowQueryPercentage, $avgExecutionTime);

        return [
            'overall_health' => $overallHealth,
            'health_score' => $this->calculateHealthScore($slowQueryPercentage, $avgExecutionTime),
            'metrics' => [
                'total_queries' => $totalQueries,
                'slow_queries' => $slowQueryCount,
                'slow_query_percentage' => round($slowQueryPercentage, 2),
                'avg_execution_time_ms' => round($avgExecutionTime, 2),
                'query_types' => $queryTypes,
                'performance_trends' => $this->analyzePerformanceTrends($profiles),
            ],
            'recommendations' => $recommendations,
            'critical_issues' => $this->identifyCriticalIssues($slowQueryPercentage, $avgExecutionTime, $queryTypes),
            'optimization_opportunities' => $this->identifyOptimizationOpportunities($profiles),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    private function performComplexityAnalysis(int $queryLimit): array
    {
        $profiles = $this->queryProfiler->getRecentProfiles($queryLimit);
        $complexityAnalysis = [];

        foreach ($profiles as $profile) {
            $complexity = $profile->getComplexityScore();
            $complexityAnalysis[] = [
                'query_id' => $profile->id,
                'sql' => $profile->query->sql,
                'complexity_score' => $complexity,
                'complexity_level' => $this->getComplexityLevel($complexity),
                'factors' => $this->analyzeComplexityFactors($profile->query->sql),
                'execution_time_ms' => $profile->executionTime->toMilliseconds(),
                'performance_ratio' => $this->calculatePerformanceRatio($complexity, $profile->executionTime->toMilliseconds()),
            ];
        }

        usort($complexityAnalysis, fn ($a, $b) => $b['complexity_score'] <=> $a['complexity_score']);

        return [
            'complexity_analysis' => array_slice($complexityAnalysis, 0, 15),
            'complexity_distribution' => $this->analyzeComplexityDistribution($complexityAnalysis),
            'performance_correlation' => $this->analyzeComplexityPerformanceCorrelation($complexityAnalysis),
            'optimization_targets' => $this->identifyComplexityOptimizationTargets($complexityAnalysis),
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    private function enhancePerformanceSummary(array $dashboardData): array
    {
        return [
            'dashboard_data' => $dashboardData,
            'enhanced_metrics' => [
                'performance_grade' => $this->calculatePerformanceGrade($dashboardData),
                'bottleneck_analysis' => $this->identifyBottlenecks($dashboardData),
                'trend_analysis' => 'Requires historical data tracking',
            ],
            'timestamp' => date('Y-m-d H:i:s'),
        ];
    }

    // Helper methods with enhanced functionality
    private function createTempProfile(string $sql): object
    {
        return new class ($sql) {
            public function __construct(public string $sql)
            {
            }

            public $query;

            public $executionTime;

            public $memoryUsage = 0;

            public $id;

            public function getComplexityScore(): int
            {
                $complexity = 0;
                $upperSql = strtoupper($this->sql);

                $complexity += substr_count($upperSql, 'JOIN') * 2;
                $complexity += substr_count($upperSql, 'LEFT JOIN') * 2;
                $complexity += substr_count($upperSql, 'RIGHT JOIN') * 3;
                $complexity += substr_count($upperSql, 'FULL JOIN') * 4;
                $complexity += substr_count($upperSql, 'SELECT') - 1; // Subqueries
                $complexity += substr_count($upperSql, 'UNION') * 3;
                $complexity += substr_count($upperSql, 'GROUP BY') * 2;
                $complexity += substr_count($upperSql, 'ORDER BY');
                $complexity += substr_count($upperSql, 'HAVING') * 2;
                $complexity += substr_count($upperSql, 'CASE WHEN') * 1;

                return max(1, $complexity);
            }

            public function getQueryType(): string
            {
                $sql = strtoupper(trim($this->sql));
                if (strpos($sql, 'SELECT') === 0) {
                    return 'SELECT';
                }
                if (strpos($sql, 'INSERT') === 0) {
                    return 'INSERT';
                }
                if (strpos($sql, 'UPDATE') === 0) {
                    return 'UPDATE';
                }
                if (strpos($sql, 'DELETE') === 0) {
                    return 'DELETE';
                }

                return 'OTHER';
            }
        };
    }

    private function normalizeSqlForPattern(string $sql): string
    {
        $normalized = preg_replace('/\b\d+\b/', '?', $sql);
        $normalized = preg_replace("/'[^']*'/", '?', $normalized);
        $normalized = preg_replace('/\s+/', ' ', $normalized);

        return trim($normalized);
    }

    private function calculateNPlusOneLikelihood(array $profiles): string
    {
        $executionCount = count($profiles);
        $timeVariance = $this->calculateTimeVariance($profiles);

        if ($executionCount > 50 && $timeVariance < 0.2) {
            return 'Very High';
        }
        if ($executionCount > 20 && $timeVariance < 0.3) {
            return 'High';
        }
        if ($executionCount > 10 && $timeVariance < 0.5) {
            return 'Medium';
        }

        return 'Low';
    }

    private function calculateIndexPriority(int $frequency, int $totalQueries): string
    {
        $percentage = ($frequency / $totalQueries) * 100;

        if ($percentage > 50) {
            return 'Critical';
        }
        if ($percentage > 25) {
            return 'High';
        }
        if ($percentage > 10) {
            return 'Medium';
        }

        return 'Low';
    }

    private function estimateIndexImpact(int $frequency, int $totalQueries): string
    {
        $percentage = ($frequency / $totalQueries) * 100;

        if ($percentage > 50) {
            return 'Very High - Could significantly improve performance';
        }
        if ($percentage > 25) {
            return 'High - Likely to improve performance noticeably';
        }
        if ($percentage > 10) {
            return 'Medium - Should provide moderate performance gains';
        }

        return 'Low - Minor performance improvement expected';
    }

    private function calculateDatabaseHealth(float $slowQueryPercentage, float $avgExecutionTime): string
    {
        if ($slowQueryPercentage > 20 || $avgExecutionTime > 1000) {
            return 'Critical';
        }
        if ($slowQueryPercentage > 10 || $avgExecutionTime > 500) {
            return 'Poor';
        }
        if ($slowQueryPercentage > 5 || $avgExecutionTime > 200) {
            return 'Fair';
        }
        if ($slowQueryPercentage > 2 || $avgExecutionTime > 100) {
            return 'Good';
        }

        return 'Excellent';
    }

    private function getHealthRecommendations(float $slowQueryPercentage, float $avgExecutionTime): array
    {
        $recommendations = [];

        if ($slowQueryPercentage > 10) {
            $recommendations[] = 'High percentage of slow queries detected - review query optimization';
        }

        if ($avgExecutionTime > 500) {
            $recommendations[] = 'High average execution time - consider adding indexes or optimizing queries';
        }

        if ($avgExecutionTime > 100 && $slowQueryPercentage > 5) {
            $recommendations[] = 'Monitor database performance and consider query caching';
        }

        if (empty($recommendations)) {
            $recommendations[] = 'Database performance appears healthy - continue monitoring';
        }

        return $recommendations;
    }

    private function getAssessment(int $score): string
    {
        return match (true) {
            $score >= 90 => 'Excellent - Query is well optimized',
            $score >= 75 => 'Good - Minor optimization opportunities',
            $score >= 60 => 'Fair - Some optimization needed',
            $score >= 40 => 'Poor - Significant optimization required',
            default => 'Critical - Major optimization needed'
        };
    }

    // Additional helper methods for enhanced functionality
    private function calculateOptimizationPriority(object $analysis): string
    {
        $score = $analysis->optimizationScore;
        $time = $analysis->profile->executionTime->toMilliseconds();

        if ($score < 40 && $time > 1000) {
            return 'Critical';
        }
        if ($score < 60 && $time > 500) {
            return 'High';
        }
        if ($score < 75 && $time > 200) {
            return 'Medium';
        }

        return 'Low';
    }

    private function calculatePerformanceImpact(array $analyses): array
    {
        $totalTime = array_sum(array_column($analyses, 'execution_time_ms'));
        $criticalQueries = array_filter($analyses, fn ($a) => $a['priority'] === 'Critical');

        return [
            'total_execution_time_ms' => $totalTime,
            'critical_queries' => count($criticalQueries),
            'potential_savings' => count($criticalQueries) * 0.6, // Estimated 60% improvement
        ];
    }

    private function analyzeComplexityFactors(string $sql): array
    {
        $upperSql = strtoupper($sql);

        return [
            'joins' => substr_count($upperSql, 'JOIN'),
            'subqueries' => substr_count($upperSql, 'SELECT') - 1,
            'unions' => substr_count($upperSql, 'UNION'),
            'aggregations' => substr_count($upperSql, 'GROUP BY'),
            'ordering' => substr_count($upperSql, 'ORDER BY'),
            'conditions' => substr_count($upperSql, 'WHERE') + substr_count($upperSql, 'HAVING'),
        ];
    }

    private function assessQueryReadability(string $sql): string
    {
        $length = strlen($sql);
        $lineCount = substr_count($sql, "\n") + 1;

        if ($length > 1000 || $lineCount > 50) {
            return 'Poor';
        }
        if ($length > 500 || $lineCount > 25) {
            return 'Fair';
        }
        if ($length > 200 || $lineCount > 10) {
            return 'Good';
        }

        return 'Excellent';
    }

    private function calculateOptimizationPotential(object $analysis): string
    {
        $score = $analysis->optimizationScore;
        $issueCount = count($analysis->issues);

        if ($score < 50 && $issueCount > 5) {
            return 'Very High';
        }
        if ($score < 70 && $issueCount > 3) {
            return 'High';
        }
        if ($score < 85 && $issueCount > 1) {
            return 'Medium';
        }

        return 'Low';
    }

    private function calculatePatternImpact(array $profiles, float $totalTime): string
    {
        if ($totalTime > 5000 && count($profiles) > 50) {
            return 'Critical';
        }
        if ($totalTime > 2000 && count($profiles) > 20) {
            return 'High';
        }
        if ($totalTime > 500 && count($profiles) > 10) {
            return 'Medium';
        }

        return 'Low';
    }

    private function generateNPlusOneRecommendation(string $pattern, int $count): string
    {
        if (strpos($pattern, 'SELECT') !== false && $count > 50) {
            return 'Consider using eager loading with JOIN or IN clause to fetch related data in a single query';
        }
        if ($count > 20) {
            return 'Consider batch loading or caching to reduce repetitive database hits';
        }

        return 'Monitor this pattern for potential optimization opportunities';
    }

    private function estimateOptimizationSavings(array $profiles): array
    {
        $totalTime = array_sum(array_map(fn ($p) => $p->executionTime->toMilliseconds(), $profiles));
        $count = count($profiles);

        return [
            'current_total_time_ms' => $totalTime,
            'estimated_optimized_time_ms' => $totalTime * 0.1, // Assuming 90% reduction
            'potential_savings_ms' => $totalTime * 0.9,
            'queries_affected' => $count,
        ];
    }

    private function summarizeNPlusOneDetection(array $patterns): array
    {
        $totalPatterns = count($patterns);
        $criticalPatterns = array_filter($patterns, fn ($p) => $p['impact_level'] === 'Critical');

        return [
            'total_patterns' => $totalPatterns,
            'critical_patterns' => count($criticalPatterns),
            'optimization_priority' => $totalPatterns > 10 ? 'High' : ($totalPatterns > 5 ? 'Medium' : 'Low'),
        ];
    }

    private function calculateTimeVariance(array $profiles): float
    {
        if (count($profiles) < 2) {
            return 0.0;
        }

        $times = array_map(fn ($p) => $p->executionTime->toMilliseconds(), $profiles);
        $mean = array_sum($times) / count($times);
        $variance = array_sum(array_map(fn ($t) => pow($t - $mean, 2), $times)) / count($times);

        return $mean > 0 ? sqrt($variance) / $mean : 0.0;
    }

    private function findCompositeIndexOpportunities(string $column, array $columnFrequency): array
    {
        $opportunities = [];
        foreach ($columnFrequency as $otherColumn => $frequency) {
            if ($otherColumn !== $column && $frequency > 5) {
                $opportunities[] = "Consider composite index: ({$column}, {$otherColumn})";
            }
        }

        return array_slice($opportunities, 0, 3);
    }

    private function estimatePerformanceGain(int $frequency, int $totalQueries): string
    {
        $percentage = ($frequency / $totalQueries) * 100;
        if ($percentage > 30) {
            return '50-80% improvement expected';
        }
        if ($percentage > 15) {
            return '30-50% improvement expected';
        }
        if ($percentage > 5) {
            return '10-30% improvement expected';
        }

        return '5-10% improvement expected';
    }

    private function analyzeTableIndexNeeds(array $tableFrequency): array
    {
        arsort($tableFrequency);

        return array_slice($tableFrequency, 0, 5);
    }

    private function prioritizeIndexImplementation(array $recommendations): array
    {
        $critical = array_filter($recommendations, fn ($r) => $r['priority'] === 'Critical');

        return [
            'immediate_action' => count($critical),
            'next_30_days' => count(array_filter($recommendations, fn ($r) => $r['priority'] === 'High')),
            'future_consideration' => count(array_filter($recommendations, fn ($r) => $r['priority'] === 'Medium')),
        ];
    }

    private function calculateHealthScore(float $slowQueryPercentage, float $avgExecutionTime): int
    {
        $score = 100;
        $score -= min(50, $slowQueryPercentage * 2); // Max 50 point deduction for slow queries
        $score -= min(30, $avgExecutionTime / 20);    // Max 30 point deduction for execution time

        return max(0, (int)$score);
    }

    private function analyzePerformanceTrends(array $profiles): string
    {
        return 'Trend analysis requires historical data collection';
    }

    private function identifyCriticalIssues(float $slowQueryPercentage, float $avgExecutionTime, array $queryTypes): array
    {
        $issues = [];

        if ($slowQueryPercentage > 15) {
            $issues[] = 'Critical: High percentage of slow queries detected';
        }

        if ($avgExecutionTime > 800) {
            $issues[] = 'Critical: Very high average execution time';
        }

        $selectRatio = ($queryTypes['SELECT'] ?? 0) / max(1, array_sum($queryTypes));
        if ($selectRatio < 0.5) {
            $issues[] = 'Warning: High ratio of write operations detected';
        }

        return $issues;
    }

    private function identifyOptimizationOpportunities(array $profiles): array
    {
        return [
            'index_optimization' => 'Run get_index_recommendations for specific suggestions',
            'query_optimization' => 'Run analyze_slow_queries for detailed analysis',
            'pattern_detection' => 'Run detect_n_plus_one_patterns for efficiency improvements',
        ];
    }

    private function getComplexityLevel(int $score): string
    {
        if ($score > 15) {
            return 'Very High';
        }
        if ($score > 10) {
            return 'High';
        }
        if ($score > 5) {
            return 'Medium';
        }

        return 'Low';
    }

    private function calculatePerformanceRatio(int $complexity, float $executionTime): float
    {
        return $complexity > 0 ? $executionTime / $complexity : $executionTime;
    }

    private function analyzeComplexityDistribution(array $complexityAnalysis): array
    {
        $levels = ['Low' => 0, 'Medium' => 0, 'High' => 0, 'Very High' => 0];
        foreach ($complexityAnalysis as $analysis) {
            $levels[$analysis['complexity_level']]++;
        }

        return $levels;
    }

    private function analyzeComplexityPerformanceCorrelation(array $complexityAnalysis): string
    {
        $correlation = 'Analysis requires statistical correlation calculation';

        return $correlation;
    }

    private function identifyComplexityOptimizationTargets(array $complexityAnalysis): array
    {
        return array_filter($complexityAnalysis, function ($analysis) {
            return $analysis['complexity_score'] > 8 && $analysis['execution_time_ms'] > 200;
        });
    }

    private function calculatePerformanceGrade(array $dashboardData): string
    {
        // This would require specific dashboard data structure
        return 'Performance grade calculation requires dashboard data analysis';
    }

    private function identifyBottlenecks(array $dashboardData): array
    {
        return ['Bottleneck analysis requires specific performance metrics'];
    }
}
