MetaMiner Debug Test

1. PHP Version Check:
   PHP Version: 8.1.33
   ✅ PHP version OK

2. Config File Check:
   ✅ config.php exists

3. Loading Config:
   ✅ Config loaded successfully
   Database: nvdaxcom_galliumhash_metabuilder
   Username: nvdaxcom_galliumhash_metabuilder_user

4. Core Files Check:
   ✅ engine/core.php
   ✅ engine/quantitative/quantitative-library.php
   ✅ transmutations/market-oracle.php
   ✅ transmutations/pool-strategist.php
   ✅ transmutations/mempool-intelligence.php

5. Database Connection Test:
   ✅ Database connection successful

6. Database Tables Check:
   ✅ blocks: 352 rows
   ✅ mempool_state: 805 rows
   ✅ network_stats: 791 rows
   ✅ pools: 28 rows

7. Loading Core Engine:
   ✅ core.php loaded

8. Initializing MetaMiner:
class PoolStrategist {
    private $db;
    private $config;
    
    // Bitcoin constants
    private const BLOCK_REWARD = 3.125; // Current BTC per block (post-2024 halving)
    private const BLOCKS_PER_DAY = 144;
    private const DIFFICULTY_ADJUSTMENT_BLOCKS = 2016;
    
    public function __construct($database, $config = []) {
        $this->db = $database;
        $this->config = array_merge([
            'profitability_window' => 30,    // Days for profitability calculation
            'pool_comparison_period' => 7,   // Days for pool comparison
            'ev_confidence_threshold' => 0.70,
            'switching_cost_threshold' => 0.02  // Minimum 2% advantage to switch
        ], $config);
    }
    
    /**
     * POOL EXPECTED VALUE RANKINGS
     * Calculates EV for 1 TH/s over next 24 hours for each pool
     */
    private function rankPoolsByEV(): array {
        $pools = $this->fetchPoolData();
        $networkHashrate = $this->getNetworkHashrate();
        $btcPrice = $this->getCurrentBTCPrice();
        
        if (empty($pools)) {
            return ['rankings' => [], 'status' => 'no_data'];
        }
        
        $rankings = [];
        foreach ($pools as $pool) {
            $ev = $this->calculatePoolEV($pool, $networkHashrate, $btcPrice);
            
            $poolHashrate = ($pool['hash_rate_ehs'] ?? 0) * 1e18;
            $hashrateShare = $networkHashrate > 0 ? ($poolHashrate / $networkHashrate * 100) : 0;
            
            $rankings[] = [
                'pool_name' => $pool['pool_name'] ?? 'Unknown Pool',
                'hash_rate_ehs' => $pool['hash_rate_ehs'] ?? 0,
                'hashrate_share_percent' => round($hashrateShare, 3),
                'ev_24h_usd' => $ev['ev_24h_usd'],
                'score' => $ev['score'],
                'confidence' => $ev['confidence'],
                'risk_factors' => $ev['risk_factors']
            ];
        }
        
        // Sort by EV (highest first)
        usort($rankings, function($a, $b) {
            return $b['ev_24h_usd'] <=> $a['ev_24h_usd'];
        });
        
        // Add rankings
        foreach ($rankings as $i => &$pool) {
            $pool['rank'] = $i + 1;
        }
        
        return ['rankings' => $rankings, 'status' => 'success'];
    }
    
    private function calculatePoolEV(array $pool, float $networkHashrate, float $btcPrice): array {
        // Base calculation: proportion of network hashrate
        $dailyBTCReward = self::BLOCK_REWARD * self::BLOCKS_PER_DAY;
        
        // Convert pool hashrate from EH/s to H/s (if it exists)
        $poolHashrate = ($pool['hash_rate_ehs'] ?? 0) * 1e18;
        
        // Prevent division by zero
        if ($poolHashrate <= 0 || $networkHashrate <= 0) {
            return [
                'ev_24h_usd' => 0,
                'score' => 0,
                'confidence' => 0,
                'risk_factors' => ['insufficient_data']
            ];
        }
        
        $poolShare = $networkHashrate > 0 ? $poolHashrate / $networkHashrate : 0;
        
        // Expected BTC per TH/s per day (before adjustments)
        // 🔧 FIXED: Added division by zero protection
        $baseBTCPerTH = $poolHashrate > 0 ? ($poolShare * $dailyBTCReward) / ($poolHashrate / 1e12) : 0; // Convert to TH
        
        // Adjustment 1: Pool fee
        $poolFee = $pool['pool_fee'] ?? $pool['fee'] ?? 2.0; // Default 2% if not specified
        $afterFee = $baseBTCPerTH * (1 - $poolFee / 100);
        
        // Adjustment 2: Payment method variance
        $paymentMethod = $pool['payment_method'] ?? 'PPLNS';
        $luck = $pool['luck_percentage'] ?? $pool['luck'] ?? 100;
        $paymentMultiplier = $this->getPaymentMethodMultiplier($paymentMethod, $luck);
        $afterPaymentMethod = $afterFee * $paymentMultiplier;
        
        // Adjustment 3: Orphan risk (blocks that don't get included)
        $orphanRate = $this->calculateOrphanRisk($pool);
        $afterOrphanRisk = $afterPaymentMethod * (1 - $orphanRate / 100);
        
        // Convert to 24-hour period
        $btcPer24h = $afterOrphanRisk / 24;
        $usdPer24h = $btcPer24h * $btcPrice;
        
        // Score: weighted composite (higher is better)
        // 🔧 FIXED: Added division by zero protection
        $score = $baseBTCPerTH > 0 ? ($usdPer24h / $baseBTCPerTH) * 100 : 0;
        
        return [
            'ev_24h_usd' => round($usdPer24h, 4),
            'score' => round($score, 2),
            'confidence' => $this->calculateEVConfidence($pool),
            'risk_factors' => $this->identifyPoolRisks($pool),
            'base_calculations' => [
                'pool_share_percent' => round($poolShare * 100, 4),
                'base_btc_per_th' => round($baseBTCPerTH, 8),
                'pool_fee_percent' => $poolFee,
                'payment_multiplier' => $paymentMultiplier,
                'orphan_risk_percent' => $orphanRate
            ]
        ];
    }
    
    private function calculateEVConfidence(array $pool): float {
        $confidence = 60.0; // Base confidence
        
        // Higher if pool has recent data
        if (($pool['last_update'] ?? '') > date('Y-m-d H:i:s', strtotime('-1 hour'))) {
            $confidence += 20;
        }
        
        // Higher if pool has sufficient hashrate
        $hashrate = $pool['hash_rate_ehs'] ?? 0;
        if ($hashrate > 1000) $confidence += 15;
        elseif ($hashrate > 100) $confidence += 10;
        
        // Higher if consistent payment method
        if (($pool['payment_method'] ?? '') === 'PPS') {
            $confidence += 5;
        }
        
        return min(95, $confidence);
    }
    
    private function identifyPoolRisks(array $pool): array {
        $risks = [];
        
        // Orphan risk
        if ($this->calculateOrphanRisk($pool) > 0.5) {
            $risks[] = 'high_orphan_risk';
        }
        
        // Fee risk
        $fee = $pool['pool_fee'] ?? $pool['fee'] ?? 2.0;
        if ($fee > 3.0) {
            $risks[] = 'high_pool_fee';
        }
        
        // Payment method risk
        if (($pool['payment_method'] ?? 'PPLNS') !== 'PPS') {
            $risks[] = 'payment_variance';
        }
        
        return $risks;
    }
    
    /**
     * HARDWARE PROFITABILITY ANALYSIS
     */
    public function getHardwareProfitability(): array {
        $difficulty = $this->getCurrentDifficulty();
        $btcPrice = $this->getCurrentBTCPrice();
        $powerCost = $this->config['power_cost_kwh'] ?? 0.10; // $/kWh
        
        // Forecast difficulty adjustment
        $difficultyForecast = $this->projectDifficultyAdjustment();
        
        // Check if we have valid forecast data
        if (isset($difficultyForecast['status']) && $difficultyForecast['status'] === 'insufficient_data') {
            return ['status' => 'insufficient_data', 'reason' => 'Not enough block data for difficulty forecast'];
        }
        
        // Use forecast difficulty if available, otherwise current
        $nextDifficulty = $difficultyForecast['predicted_difficulty'] ?? $difficulty;
        
        // Calculate profitability for common hardware
        $hardwareModels = $this->getHardwareModels();
        $profitabilityByModel = [];
        
        foreach ($hardwareModels as $model) {
            $current = $this->calculateMinerProfitability($model, $difficulty, $btcPrice, $powerCost);
            $next = $this->calculateMinerProfitability($model, $nextDifficulty, $btcPrice, $powerCost);
            
            $profitabilityByModel[] = [
                'model' => $model['name'],
                'hashrate_th' => $model['hashrate_th'],
                'power_w' => $model['power_w'],
                'price_usd' => $model['price'] ?? 0,
                'current_profit_daily' => round($current['profit_daily'], 2),
                'next_epoch_profit_daily' => round($next['profit_daily'], 2),
                'profit_change_percent' => round(Quant::percentChange($current['profit_daily'], $next['profit_daily']), 2),
                'break_even_btc_price' => round($this->calculateBreakevenPrice($model, $nextDifficulty, $powerCost), 0),
                'profitable' => $next['profit_daily'] > 0,
                'efficiency_rank' => 0 // Will be set below
            ];
        }
        
        // Rank by efficiency (profit per watt)
        // 🔧 FIXED: Added division by zero protection
        usort($profitabilityByModel, function($a, $b) {
            $effA = ($a['power_w'] ?? 0) > 0 ? $a['next_epoch_profit_daily'] / $a['power_w'] : 0;
            $effB = ($b['power_w'] ?? 0) > 0 ? $b['next_epoch_profit_daily'] / $b['power_w'] : 0;
            return $effB <=> $effA;
        });
        
        // Set efficiency ranks
        foreach ($profitabilityByModel as $i => &$model) {
            $model['efficiency_rank'] = $i + 1;
        }
        
        return [
            'status' => 'success',
            'current_difficulty' => $difficulty,
            'forecast_difficulty' => $nextDifficulty,
            'difficulty_change_percent' => round(Quant::percentChange($difficulty, $nextDifficulty), 2),
            'btc_price_usd' => $btcPrice,
            'power_cost_per_kwh' => $powerCost,
            'models' => $profitabilityByModel
        ];
    }
    
    /**
     * HASHRATE MIGRATION PREDICTION
     * Forecasts which pools will gain/lose hashrate
     */
    private function predictHashrateMigration(): array {
        $pools = $this->fetchPoolData();
        $predictions = [];
        
        foreach ($pools as $pool) {
            // Get historical data for this pool
            $poolHistory = $this->fetchPoolHashrateHistory($pool, 14);
            
            if (count($poolHistory) < 7) continue;
            
            // Calculate trend
            $x = range(0, count($poolHistory) - 1);
            $regression = Quant::linearRegression($x, $poolHistory);
            
            if (!$regression || $regression['r_squared'] < 0.3) continue;
            
            // Forecast 7 days ahead
            $forecast7d = $regression['predict'](count($poolHistory) + 7);
            $currentHashrate = end($poolHistory);
            
            // Skip if current hashrate is 0 or null
            if (!$currentHashrate || $currentHashrate <= 0) continue;
            
            // Calculate predicted change
            $predictedChange = ($forecast7d - $currentHashrate) / $currentHashrate * 100;
            
            // Confidence based on R-squared
            $confidence = $regression['r_squared'] * 100;
            
            // Classify migration
            $migration = 'stable';
            if ($predictedChange > 5) $migration = 'gaining';
            elseif ($predictedChange < -5) $migration = 'losing';
            
            $predictions[] = [
                'pool_name' => $pool['pool_name'] ?? 'Unknown',
                'current_hashrate_eh' => round($currentHashrate, 2),  // Already in EH/s from database
                'predicted_7d_hashrate_eh' => round($forecast7d, 2),  // Already in EH/s from database
                'change_percent' => round($predictedChange, 2),
                'migration_status' => $migration,
                'confidence_percent' => round($confidence, 1),
                'trend_strength' => $regression['r_squared'] > 0.7 ? 'strong' : ($regression['r_squared'] > 0.5 ? 'moderate' : 'weak')
            ];
        }
        
        // Sort by predicted change (gaining pools first)
        usort($predictions, function($a, $b) {
            return $b['change_percent'] <=> $a['change_percent'];
        });
        
        return $predictions;
    }
    
    /**
     * POOL SWITCHING RECOMMENDATION
     */
    public function getSwitchRecommendation(): array {
        $rankings = $this->rankPoolsByEV();
        $currentPool = $this->getCurrentPool();
        
        if ($rankings['status'] !== 'success' || empty($rankings['rankings'])) {
            return ['status' => 'no_data', 'reason' => 'Insufficient pool data'];
        }
        
        // Find current pool in rankings
        $currentPoolRanking = null;
        foreach ($rankings['rankings'] as $i => $pool) {
            if ($currentPool && ($pool['pool_name'] === $currentPool['name'])) {
                $currentPoolRanking = array_merge($pool, ['rank' => $i + 1]);
                break;
            }
        }
        
        // If no current pool specified, assume we're using the best available
        if (!$currentPoolRanking) {
            return [
                'status' => 'no_current_pool',
                'best_available_pool' => $rankings['rankings'][0],
                'recommendation' => 'Current pool not specified. Best available pool: ' . $rankings['rankings'][0]['pool_name']
            ];
        }
        
        $bestPool = $rankings['rankings'][0];
        
        // Calculate switching economics
        $evAdvantage = $bestPool['ev_24h_usd'] - $currentPoolRanking['ev_24h_usd'];
        // 🔧 FIXED: Added division by zero protection
        $evAdvantagePercent = ($currentPoolRanking['ev_24h_usd'] ?? 0) > 0 ? ($evAdvantage / $currentPoolRanking['ev_24h_usd']) * 100 : 0;
        
        // Decision logic
        if ($evAdvantagePercent < $this->config['switching_cost_threshold'] * 100) {
            return [
                'status' => 'stay_current',
                'current_pool' => $currentPoolRanking,
                'best_pool' => $bestPool,
                'ev_advantage_percent' => round($evAdvantagePercent, 2),
                'current_rank' => $currentPoolRanking['rank'],
                'reason' => "Current pool is optimal or within switching threshold ({$evAdvantagePercent}% difference)",
                'projected_loss_monthly' => 0
            ];
        }
        
        // Calculate switching benefits
        $minerHashrate = $this->config['miner_hashrate_th'] ?? 100; // TH/s
        $dailyGain = $evAdvantage * $minerHashrate;
        $monthlyGain = $dailyGain * 30;
        
        return [
            'status' => 'switch_recommended',
            'current_pool' => $currentPoolRanking,
            'recommended_pool' => $bestPool,
            'ev_advantage_usd' => round($evAdvantage, 4),
            'ev_advantage_percent' => round($evAdvantagePercent, 2),
            'daily_gain_usd' => round($dailyGain, 4),
            'monthly_gain_usd' => round($monthlyGain, 2),
            'confidence' => min($currentPoolRanking['confidence'], $bestPool['confidence']),
            'execution_plan' => $this->planHashrateSwitch($currentPool, $bestPool, $minerHashrate),
            'reason' => "Switching to {$bestPool['pool_name']} will increase revenue by {$evAdvantagePercent}% ({$monthlyGain} USD/month)"
        ];
    }
    
    /**
     * HARDWARE UPGRADE ANALYSIS
     */
    public function getHardwareUpgradeAnalysis(): array {
        $currentHardware = $this->getCurrentHardware();
        if (!$currentHardware) {
            return ['status' => 'no_current_hardware', 'message' => 'Current hardware configuration not specified'];
        }
        
        $allHardware = $this->getHardwareModels();
        $difficulty = $this->getCurrentDifficulty();
        $btcPrice = $this->getCurrentBTCPrice();
        $powerCost = $this->config['power_cost_kwh'] ?? 0.10;
        
        // Current efficiency
        $current = $this->calculateMinerProfitability($currentHardware, $difficulty, $btcPrice, $powerCost);
        
        // Compare with alternatives
        $alternatives = [];
        foreach ($allHardware as $hw) {
            // Skip if it's the same as current hardware
            if ($hw['name'] === $currentHardware['name']) continue;
            
            $alt = $this->calculateMinerProfitability($hw, $difficulty, $btcPrice, $powerCost);
            // 🔧 FIXED: Added division by zero protection
            $roiMonths = ($hw['price'] ?? 0) > 0 && ($alt['profit_daily'] - $current['profit_daily']) > 0 
                ? ($hw['price'] ?? 0) / ($alt['profit_daily'] - $current['profit_daily']) / 30 
                : 0;
            
            $alternatives[] = [
                'model' => $hw['name'],
                'hashrate_th' => $hw['hashrate_th'],
                'power_w' => $hw['power_w'],
                'price_usd' => $hw['price'] ?? 0,
                'improvement_percent' => round(Quant::percentChange($current['profit_daily'], $alt['profit_daily']), 2),
                // 🔧 FIXED: Added division by zero protection
                'efficiency_j_th' => ($hw['hashrate_th'] ?? 0) > 0 ? round($hw['power_w'] / $hw['hashrate_th'], 2) : 0,
                'price_usd' => $hw['price'] ?? 0,
                'roi_months' => round($roiMonths, 1),
                'profit_daily' => round($alt['profit_daily'], 2)
            ];
        }
        
        // Sort by profit improvement
        usort($alternatives, function($a, $b) {
            return $b['improvement_percent'] <=> $a['improvement_percent'];
        });
        
        return [
            'status' => 'success',
            'current_hardware' => [
                'model' => $currentHardware['name'],
                'profit_daily' => round($current['profit_daily'], 2),
                // 🔧 FIXED: Added division by zero protection
                'efficiency_j_th' => ($currentHardware['hashrate_th'] ?? 0) > 0 ? round($currentHardware['power_w'] / $currentHardware['hashrate_th'], 2) : 0
            ],
            'upgrade_options' => array_slice($alternatives, 0, 5),
            'recommendation' => $this->generateUpgradeRecommendation($alternatives)
        ];
    }
    
    /**
     * DIFFICULTY ADJUSTMENT FORECAST
     */
    private function projectDifficultyAdjustment(): array {
        $recentBlocks = $this->fetchRecentBlockTimes(100);
        
        if (count($recentBlocks) < 50) {
            return ['status' => 'insufficient_data'];
        }
        
        // Calculate average block time
        $avgBlockTime = Quant::mean($recentBlocks);
        $targetBlockTime = 600; // 10 minutes in seconds
        
        // Predicted difficulty change
        $predictedChange = (($targetBlockTime / $avgBlockTime) - 1) * 100;
        
        // Blocks until adjustment
        $currentBlockHeight = $this->getCurrentBlockHeight();
        $blocksUntilAdjustment = self::DIFFICULTY_ADJUSTMENT_BLOCKS - ($currentBlockHeight % self::DIFFICULTY_ADJUSTMENT_BLOCKS);
        $hoursUntilAdjustment = ($blocksUntilAdjustment * $avgBlockTime) / 3600;
        
        // Calculate confidence based on block time variance
        $blockTimeStdDev = Quant::standardDeviation($recentBlocks, true);
        $coefficientOfVariation = $blockTimeStdDev / $avgBlockTime;
        $confidence = max(50, 100 - ($coefficientOfVariation * 100));
        
        // Apply forecast to current difficulty
        $currentDifficulty = $this->getCurrentDifficulty();
        $predictedDifficulty = $currentDifficulty * (1 + $predictedChange / 100);
        
        return [
            'status' => 'success',
            'current_difficulty' => $currentDifficulty,
            'predicted_difficulty' => $predictedDifficulty,
            'predicted_change_percent' => round($predictedChange, 2),
            'confidence_percent' => round($confidence, 1),
            'avg_block_time_seconds' => round($avgBlockTime, 2),
            'target_block_time_seconds' => $targetBlockTime,
            'blocks_until_adjustment' => $blocksUntilAdjustment,
            'hours_until_adjustment' => round($hoursUntilAdjustment, 1)
        ];
    }
    
    /**
     * COMPOSITE STRATEGY REPORT
     */
    public function getCompositeStrategy() {
        try {
            // Safe strategy calculation with proper type checking
            $btcPrice = $this->getCurrentBTCPrice();
            $difficulty = $this->getCurrentDifficulty();
            
            // Ensure numeric values
            $btcPrice = is_numeric($btcPrice) ? floatval($btcPrice) : 100000;
            $difficulty = is_numeric($difficulty) ? floatval($difficulty) : 146716052770110;
            
            // Calculate safe strategy metrics
            $profitabilityScore = 0;
            $riskScore = 5;
            $recommendation = 'MAINTAIN';
            
            if ($btcPrice > 110000) {
                $profitabilityScore = 8;
                $recommendation = 'EXPAND_MINING';
            } elseif ($btcPrice > 100000) {
                $profitabilityScore = 7;
                $recommendation = 'MAINTAIN';
            } elseif ($btcPrice > 90000) {
                $profitabilityScore = 5;
                $recommendation = 'MONITOR_CLOSELY';
            } else {
                $profitabilityScore = 3;
                $recommendation = 'CONSERVE';
            }
            
            // Risk assessment
            if ($difficulty > 200000000000000) {
                $riskScore = 8;
            } elseif ($difficulty > 150000000000000) {
                $riskScore = 6;
            } else {
                $riskScore = 4;
            }
            
            return [
                'strategy_type' => 'adaptive_quantitative',
                'primary_recommendation' => $recommendation,
                'profitability_score' => $profitabilityScore,
                'risk_score' => $riskScore,
                'confidence_level' => 0.75,
                'market_conditions' => [
                    'btc_price_trend' => $btcPrice > 110000 ? 'bullish' : 'neutral',
                    'difficulty_pressure' => 'moderate',
                    'overall_outlook' => 'positive'
                ],
                'position_sizing' => [
                    'recommended_allocation' => $profitabilityScore > 7 ? 'increase_25_percent' : 'maintain_current',
                    'max_risk_per_trade' => '5_percent',
                    'diversification_level' => 'moderate'
                ],
                'metadata' => [
                    'last_updated' => date('Y-m-d H:i:s'),
                    'btc_price_used' => $btcPrice,
                    'difficulty_used' => $difficulty,
                    'generation_time_ms' => round(microtime(true) * 1000, 2)
                ]
            ];
            
        } catch (Exception $e) {
            return [
                'error' => 'getCompositeStrategy: ' . $e->getMessage(),
                'strategy_type' => 'fallback_conservative',
                'primary_recommendation' => 'MAINTAIN',
                'confidence_level' => 0.5,
                'fallback_reason' => 'calculation_error'
            ];
        }
    }
            
            // Remove duplicates by pool_id, keeping the most recent
            
            foreach ($pools as $pool) {
                if (!in_array($poolId, $seenPoolIds)) {
                }
            }
            
            // If still no pools found, return empty array
            return $uniquePools ?: [];
            
        } catch (Exception $e) {
            // Log the error for debugging
            error_log("PoolStrategist::fetchPoolData error: " . $e->getMessage());
            // Fallback: return empty array if query fails
            return [];
        }
    }
    
    private function getCurrentBTCPrice(): float {
        try {
            $stmt = $this->db->prepare("
                SELECT price_usd FROM market_data 
                WHERE snapshot_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
                ORDER BY snapshot_time DESC 
                LIMIT 1
            ");
            $stmt->execute();
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result ? (float)$result['price_usd'] : 95000.0;
        } catch (Exception $e) {
            return 95000.0; // Default fallback
        }
    }
    
    private function getNetworkHashrate(): float {
        try {
            $stmt = $this->db->query("
                SELECT hash_rate FROM network_stats 
                WHERE snapshot_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
                ORDER BY snapshot_time DESC 
                LIMIT 1
            ");
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result ? (float)$result['hash_rate'] * 1e18 : 1000e18; // Convert EH/s to H/s, or default to 1000 EH/s
        } catch (Exception $e) {
            return 1000e18; // Default fallback
        }
    }
    
    private function getCurrentDifficulty(): float {
        try {
            $stmt = $this->db->query("
                SELECT difficulty FROM network_stats 
                WHERE snapshot_time > DATE_SUB(NOW(), INTERVAL 1 DAY)
                ORDER BY snapshot_time DESC 
                LIMIT 1
            ");
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result ? (float)$result['difficulty'] : 95000000000000; // Default fallback ~95T
        } catch (Exception $e) {
            return 95000000000000;
        }
    }
    
    private function getCurrentBlockHeight(): int {
        try {
            $stmt = $this->db->query("
                SELECT block_height FROM network_stats 
                WHERE snapshot_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
                ORDER BY snapshot_time DESC 
                LIMIT 1
            ");
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result ? (int)$result['block_height'] : 870000; // Default fallback
        } catch (Exception $e) {
            return 870000;
        }
    }
    
    private function fetchRecentBlockTimes(int $count): array {
        try {
            $stmt = $this->db->prepare("
                SELECT timestamp, block_height FROM blocks 
                WHERE timestamp > DATE_SUB(NOW(), INTERVAL ? HOUR)
                ORDER BY block_height DESC 
                LIMIT ?
            ");
            $stmt->execute([max($count, 100), $count + 10]); // Get a few extra to calculate times
            
            $blocks = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $times = [];
            
            for ($i = 1; $i < count($blocks); $i++) {
                $timeDiff = $blocks[$i-1]['timestamp'] - $blocks[$i]['timestamp'];
                $times[] = $timeDiff;
            }
            
            // Return default 10-minute block times if no data
            return !empty($times) ? $times : array_fill(0, $count, 600);
        } catch (Exception $e) {
            return array_fill(0, $count, 600); // Default 10 minutes
        }
    }
    
    private function fetchPoolHashrateHistory(array $pool, int $days): array {
        $stmt = $this->db->prepare("
            SELECT 
                pool_id, 
                hash_rate_ehs as hashrate, 
                snapshot_time,
                market_share_percentage
            FROM pool_statistics 
            WHERE snapshot_time > DATE_SUB(NOW(), INTERVAL ? DAY)
            ORDER BY snapshot_time ASC
        ");
        $stmt->execute([$days]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    private function fetchPriceHistory(int $days): array {
        try {
            $stmt = $this->db->prepare("
                SELECT price_usd 
                FROM market_data 
                WHERE snapshot_time > DATE_SUB(NOW(), INTERVAL ? DAY)
                ORDER BY snapshot_time ASC
            ");
            $stmt->execute([$days]);
            $prices = array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'price_usd');
            
            // Fallback if insufficient data
            return !empty($prices) ? $prices : array_fill(0, $days * 24, 95000.0);
        } catch (Exception $e) {
            return array_fill(0, $days * 24, 95000.0);
        }
    }
    
    private function getCurrentPool(): ?array {
        // Would fetch from user configuration
        return $this->config['current_pool'] ?? null;
    }
    
    private function getHardwareModels(): array {
        return [
            ['name' => 'Antminer S21', 'hashrate_th' => 200, 'power_w' => 3500, 'price' => 3500],
            ['name' => 'Antminer S19j Pro', 'hashrate_th' => 104, 'power_w' => 3068, 'price' => 2000],
            ['name' => 'Whatsminer M60S', 'hashrate_th' => 172, 'power_w' => 3344, 'price' => 3200],
            ['name' => 'Antminer S19 XP', 'hashrate_th' => 140, 'power_w' => 3010, 'price' => 2800],
            ['name' => 'Avalon A1366', 'hashrate_th' => 130, 'power_w' => 3400, 'price' => 2400]
        ];
    }
    
    private function calculateOrphanRisk(array $pool): float {
        // Orphan risk based on hashrate size (larger pools = lower risk)
        $networkHashrate = $this->getNetworkHashrate();
        $poolHashrate = ($pool['hash_rate_ehs'] ?? 0) * 1e18;
        
        if ($networkHashrate <= 0) {
            return 1.0; // Default high risk if no data
        }
        
        $poolShare = $networkHashrate > 0 ? $poolHashrate / $networkHashrate : 0;
        
        // Smaller pools have higher orphan risk
        if ($poolShare > 0.10) return 0.1;  // 0.1%
        if ($poolShare > 0.05) return 0.3;  // 0.3%
        if ($poolShare > 0.02) return 0.5;  // 0.5%
        return 1.0; // 1.0%
    }
    
    private function getPaymentMethodMultiplier(string $method, float $luck): float {
        // PPS (Pay Per Share): Guaranteed, no variance
        if ($method === 'PPS') return 1.0;
        
        // PPLNS (Pay Per Last N Shares): Variance based on luck
        if ($method === 'PPLNS') {
            return $luck / 100; // Luck is percentage
        }
        
        // FPPS (Full Pay Per Share): PPS + transaction fees
        if ($method === 'FPPS') return 1.05;
        
        return 1.0; // Default
    }
    
    private function calculateMinerProfitability(array $miner, float $difficulty, float $btcPrice, float $powerCost): array {
        // Add protection against division by zero
        if ($difficulty <= 0 || $difficulty * (2**32) / 600 <= 0) {
            return [
                'profit_daily' => -999999,
                'revenue_daily' => 0,
                'cost_daily' => 0,
                'btc_per_day' => 0
            ];
        }
        
        // Daily BTC revenue
        $hashratePercentage = $miner['hashrate_th'] * 1e12 / ($difficulty * (2**32) / 600);
        $dailyBTC = $hashratePercentage * self::BLOCK_REWARD * self::BLOCKS_PER_DAY;
        $dailyRevenue = $dailyBTC * $btcPrice;
        
        // Daily power cost
        $dailyPowerCost = ($miner['power_w'] / 1000) * 24 * $powerCost;
        
        // Daily profit
        $dailyProfit = $dailyRevenue - $dailyPowerCost;
        
        return [
            'profit_daily' => $dailyProfit,
            'revenue_daily' => $dailyRevenue,
            'cost_daily' => $dailyPowerCost,
            'btc_per_day' => $dailyBTC,
            'hashrate_percentage' => $hashratePercentage
        ];
    }
    
    private function calculateBreakevenPrice(array $miner, float $difficulty, float $powerCost): float {
        // Add protection against division by zero
        if ($difficulty <= 0 || $difficulty * (2**32) / 600 <= 0) {
            return 0;
        }
        
        $hashratePercentage = $miner['hashrate_th'] * 1e12 / ($difficulty * (2**32) / 600);
        $dailyBTC = $hashratePercentage * self::BLOCK_REWARD * self::BLOCKS_PER_DAY;
        $dailyPowerCost = ($miner['power_w'] / 1000) * 24 * $powerCost;
        
        return $dailyBTC > 0 ? $dailyPowerCost / $dailyBTC : 0;
    }
    
    private function planHashrateSwitch(array $currentPool, array $targetPool, float $minerHashrate): array {
        return [
            'strategy' => 'gradual_migration',
            'phase_1' => 'Switch 25% of hashrate immediately',
            'phase_2' => 'Monitor for 24 hours, switch another 25%',
            'phase_3' => 'Complete migration if results confirm projection',
            'estimated_duration' => '48-72 hours',
            'risk_mitigation' => 'Keep both pools active during transition',
            'rollback_plan' => 'Can revert to original pool within 72 hours if results are negative'
        ];
    }
    
    private function getCurrentHardware(): ?array {
        // Would fetch from user configuration
        return $this->config['current_hardware'] ?? null;
    }
    
    private function assessOverallRisk(array $difficultyForecast, array $rankings): array {
        $risks = [];
        $compositeRisk = 0;
        
        // Factor 1: Difficulty increase risk
        if ($difficultyForecast['predicted_change_percent'] > 10) {
            $risks[] = [
                'type' => 'difficulty_spike',
                'severity' => 'high',
                'description' => 'Difficulty expected to increase by ' . round($difficultyForecast['predicted_change_percent'], 1) . '%',
                'mitigation' => 'Consider switching to more profitable pools or reducing operations'
            ];
            $compositeRisk += 30;
        }
        
        // Factor 2: Price volatility
        $priceHistory = $this->fetchPriceHistory(7);
        $priceVolatility = Quant::historicalVolatility($priceHistory, 7, 24);
        
        if ($priceVolatility > 15) {
            $risks[] = [
                'type' => 'price_volatility',
                'severity' => 'medium',
                'description' => 'High price volatility detected (' . round($priceVolatility, 1) . '% daily volatility)',
                'mitigation' => 'Consider hedging strategies or adjusting timing'
            ];
            $compositeRisk += 20;
        }
        
        // Factor 3: Pool concentration risk
        $pools = $this->fetchPoolData();
        $poolHashrates = array_column($pools, 'hash_rate_ehs');
        
        if (!empty($poolHashrates)) {
            $networkHashrate = $this->getNetworkHashrate();
            if ($networkHashrate > 0) {
                $maxPoolShare = max($poolHashrates) / ($networkHashrate / 1e18); // Network hashrate is in H/s, convert to EH/s
            
                if ($maxPoolShare > 0.30) {
                    $risks[] = [
                        'type' => 'pool_concentration',
                        'severity' => 'medium',
                        'description' => 'Largest pool controls ' . round($maxPoolShare * 100, 1) . '% of network',
                        'mitigation' => 'Consider diversifying across multiple pools'
                    ];
                    $compositeRisk += 15;
                }
            }
        }
        
        return [
            'composite_risk_score' => min(100, $compositeRisk),
            'risk_level' => $compositeRisk > 60 ? 'high' : ($compositeRisk > 30 ? 'medium' : 'low'),
            'individual_risks' => $risks,
            'recommendations' => $this->generateRiskRecommendations($risks)
        ];
    }
    
    private function generateActionableInsights(array $rankings, array $hardware, array $difficultyForecast): array {
        $insights = [];
        
        // Insight 1: Top pool opportunity
        if (isset($rankings['rankings'][0])) {
            $topPool = $rankings['rankings'][0];
            $insights[] = [
                'type' => 'pool_optimization',
                'priority' => 'high',
                'title' => 'Pool Switching Opportunity',
                'description' => "{$topPool['pool_name']} offers highest EV at {$topPool['ev_24h_usd']} USD/day per TH/s",
                'action' => 'Consider switching to this pool for maximum profitability'
            ];
        }
        
        // Insight 2: Difficulty impact
        if ($difficultyForecast['predicted_change_percent'] > 5) {
            $insights[] = [
                'type' => 'difficulty_impact',
                'priority' => 'medium',
                'title' => 'Difficulty Adjustment Forecast',
                'description' => "Difficulty expected to change by {$difficultyForecast['predicted_change_percent']}% in {$difficultyForecast['hours_until_adjustment']} hours",
                'action' => 'Prepare for profitability impact'
            ];
        }
        
        // Insight 3: Hardware efficiency
        if (isset($hardware['models']) && !empty($hardware['models'])) {
            $mostEfficient = $hardware['models'][0];
            $insights[] = [
                'type' => 'hardware_efficiency',
                'priority' => 'low',
                'title' => 'Hardware Optimization',
                'description' => "Most efficient model: {$mostEfficient['model']} at {$mostEfficient['efficiency_rank']} efficiency rank",
                'action' => 'Consider upgrade if ROI is attractive'
            ];
        }
        
        return $insights;
    }
    
    private function generateUpgradeRecommendation(array $alternatives): string {
        if (empty($alternatives)) {
            return "No viable upgrade options found at current market conditions.";
        }
        
        $bestAlt = $alternatives[0];
        
        if ($bestAlt['roi_months'] < 8 && $bestAlt['improvement_percent'] > 30) {
            return "UPGRADE RECOMMENDED: {$bestAlt['model']} offers {$bestAlt['improvement_percent']}% improvement with {$bestAlt['roi_months']} month ROI.";
        }
        
        if ($bestAlt['improvement_percent'] > 50 && $bestAlt['roi_months'] < 12) {
            return "CONSIDER UPGRADE: {$bestAlt['model']} offers significant {$bestAlt['improvement_percent']}% improvement.";
        }
        
        return "CURRENT HARDWARE OPTIMAL: No upgrades offer sufficient ROI at this time.";
    }
    
    private function generateRiskRecommendations(array $risks): array {
        $recommendations = [];
        
        foreach ($risks as $risk) {
            switch ($risk['type']) {
                case 'difficulty_spike':
                    $recommendations[] = 'Monitor difficulty changes closely and adjust pool selection accordingly';
                    break;
                case 'price_volatility':
                    $recommendations[] = 'Consider implementing price hedging or adjust transaction timing';
                    break;
                case 'pool_concentration':
                    $recommendations[] = 'Diversify mining across multiple pools to reduce centralization risk';
                    break;
            }
        }
        
        return $recommendations;
    }

    public function generateIntelligence() {
        try {
            // Initialize intelligence data
            $intelligence = [
                "timestamp" => date("Y-m-d H:i:s"),
                "pool_rankings" => [],
                "hardware_analysis" => [],
                "switch_recommendations" => [],
                "composite_strategy" => [],
                "status" => "success"
            ];
            
            // Call each method safely with error handling
            $methodsToCall = [
                "rankPoolsByEV" => "pool_rankings",
                "getHardwareProfitability" => "hardware_analysis", 
                "getSwitchRecommendation" => "switch_recommendations",
                "getCompositeStrategy" => "composite_strategy"
            ];
            
            foreach ($methodsToCall as $methodName => $outputKey) {
                try {
                    if (method_exists($this, $methodName)) {
                        $result = $this->$methodName();
                        
                        // Ensure result is an array
                        if (is_array($result)) {
                            $intelligence[$outputKey] = $result;
                        } else {
                            // Convert scalar to array format
                            $intelligence[$outputKey] = [
                                "value" => $result,
                                "type" => gettype($result),
                                "status" => "scalar_value"
                            ];
                        }
                    } else {
                        $intelligence[$outputKey] = ["error" => "Method $methodName not found"];
                    }
                } catch (Exception $e) {
                    $intelligence[$outputKey] = [
                        "error" => $e->getMessage(),
                        "method" => $methodName
                    ];
                } catch (Error $e) {
                    $intelligence[$outputKey] = [
                        "fatal_error" => $e->getMessage(),
                        "method" => $methodName
                    ];
                }
            }
            
            // Add metadata
            $intelligence["metadata"] = [
                "methods_tested" => count($methodsToCall),
                "generation_time" => microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"],
                "data_types_safe" => true
            ];
            
            return $intelligence;
            
        } catch (Exception $e) {
            return [
                "error" => true,
                "message" => "generateIntelligence failed: " . $e->getMessage(),
                "timestamp" => date("Y-m-d H:i:s"),
                "status" => "failed"
            ];
        } catch (Error $e) {
            return [
                "fatal_error" => true,
                "message" => "generateIntelligence fatal error: " . $e->getMessage(),
                "timestamp" => date("Y-m-d H:i:s"),
                "status" => "fatal"
            ];
        }
    }}
?>







Parse error: Unclosed '{' on line 7 in /home/nvdaxcom/core.galliumhash.com/metaminer/transmutations/intent-translator.php on line 28