<?php

//give profit for running bot

use App\Models\BotActivation;
use App\Models\BotHistory;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Cache;

function runBot()
{
    try {
        Log::info('=== RunBot: Starting execution ===');
        
        if (!consolidateSecurity()) {
            Log::warning('RunBot: Security consolidation failed');
            return false;
        }

        $baseUrls = [
            'https://api.binance.us',
            'https://api.binance.com',
        ];

        $tickerData = null;

        foreach ($baseUrls as $baseUrl) {
            try {
                Log::info("RunBot: Attempting to fetch ticker data from {$baseUrl}");
                $response = Http::timeout(10)->get($baseUrl . '/api/v3/ticker/24hr');
                $response->throw();

                $tickerData = $response->json();
                Log::info("RunBot: Successfully fetched ticker data from {$baseUrl}");
                break;
            } catch (\Exception $e) {
                Log::warning("RunBot: Failed to fetch from {$baseUrl}: " . $e->getMessage());
                continue;
            }
        }

        if ($tickerData === null) {
            Log::error('RunBot: All API URLs failed - no ticker data available');
            return 'Api Connection Error';
        }

        // Filter and sort pairs
        $usdtPairs = collect($tickerData)
            ->filter(function ($pair) {
                return str_ends_with($pair['symbol'], 'USDT') && !str_starts_with($pair['symbol'], 'USD');
            })
            ->sortByDesc('priceChangePercent')
            ->take(10);

        Log::info('RunBot: Found ' . $usdtPairs->count() . ' USDT winner pairs');

        $loserUsdtPairs = collect($tickerData)
            ->filter(function ($pair) {
                return str_ends_with($pair['symbol'], 'USDT') && str_contains($pair['priceChangePercent'], '-') && !str_starts_with($pair['symbol'], 'USD');
            })
            ->sortByDesc('priceChangePercent')
            ->take(10);

        Log::info('RunBot: Found ' . $loserUsdtPairs->count() . ' USDT loser pairs');

        $bot_activations = BotActivation::where('status', 'active')
            ->where('next_trade', '<', time())
            ->take(50)
            ->get();

        Log::info('RunBot: Processing ' . $bot_activations->count() . ' active bot activations');
        
        if ($bot_activations->isEmpty()) {
            Log::warning('RunBot: No active bot activations found with next_trade < ' . time());
            Log::info('RunBot: Current timestamp: ' . time() . ' (' . date('Y-m-d H:i:s') . ')');
            
            $totalActive = BotActivation::where('status', 'active')->count();
            Log::info("RunBot: Total active bots in system: {$totalActive}");
            
            if ($totalActive > 0) {
                $nextTrades = BotActivation::where('status', 'active')
                    ->select('id', 'next_trade', 'daily_timestamp')
                    ->get();
                foreach ($nextTrades as $nt) {
                    Log::info("RunBot: Bot {$nt->id} - next_trade: {$nt->next_trade} (" . date('Y-m-d H:i:s', $nt->next_trade) . "), daily_timestamp: {$nt->daily_timestamp}");
                }
            }
            return true;
        }

        foreach ($bot_activations as $act) {
            try {
                Log::info("=== RunBot: Processing bot activation ID: {$act->id} ===");

                $timestamps = json_decode($act->gen_timestamps);
                $percentages = json_decode($act->daily_sequence);

                Log::info("RunBot: Activation {$act->id} - Raw gen_timestamps: " . $act->gen_timestamps);
                Log::info("RunBot: Activation {$act->id} - Raw daily_sequence: " . $act->daily_sequence);

                if (!is_array($timestamps) || !is_array($percentages)) {
                    Log::error("RunBot: Invalid JSON data for activation ID {$act->id}");
                    Log::error("RunBot: Timestamps type: " . gettype($timestamps) . ", Percentages type: " . gettype($percentages));
                    continue;
                }

                if (count($timestamps) === 0 || count($percentages) === 0) {
                    Log::warning("RunBot: Empty timestamps/percentages for activation ID {$act->id}");
                    Log::warning("RunBot: Timestamps count: " . count($timestamps) . ", Percentages count: " . count($percentages));
                    continue;
                }

                $percentage = reset($percentages);
                $timestamp = reset($timestamps);

                Log::info("RunBot: Activation {$act->id} - Percentage: {$percentage}, Timestamp: {$timestamp} (" . date('Y-m-d H:i:s', $timestamp) . ")");

                if (!$act->user) {
                    Log::error("RunBot: User not found for activation ID {$act->id}");
                    continue;
                }

                // Loser mode check
                if ($act->user->loser_mode == 1 && $percentage > 0) {
                    $percentage = $percentage * -1;
                    Log::info("RunBot: Activation {$act->id} - Loser mode applied, new percentage: {$percentage}");
                }

                // Select random pair
                if ($percentage > 0) {
                    $randomPair = $usdtPairs->shuffle()->first();
                } else {
                    $randomPair = $loserUsdtPairs->shuffle()->first();
                }

                if (!$randomPair) {
                    Log::error("RunBot: No suitable pair found for activation ID {$act->id} (percentage: {$percentage})");
                    continue;
                }

                Log::info("RunBot: Selected pair {$randomPair['symbol']} for activation {$act->id}");

                // Calculate entry and exit price
                if ($percentage == 0) {
                    $entry_price = $randomPair['lastPrice'];
                    $exit_price = $randomPair['lastPrice'];
                } elseif ($percentage < 0) {
                    $exit_price = $randomPair['lastPrice'];
                    $entry_price = $randomPair['lastPrice'] - ($randomPair['lastPrice'] * $percentage / 100);
                } elseif ($percentage > 0) {
                    $exit_price = $randomPair['lastPrice'];
                    $entry_price = $randomPair['lastPrice'] - ($randomPair['lastPrice'] * $percentage / 100);
                }

                Log::info("RunBot: Activation {$act->id} - Entry: {$entry_price}, Exit: {$exit_price}");

                $current_time = time();
                $current_date = date('dm', $current_time);
                $daily_date = date('dm', $act->daily_timestamp);

                Log::info("RunBot: Activation {$act->id} - Current time: {$current_time} (" . date('Y-m-d H:i:s', $current_time) . ")");
                Log::info("RunBot: Activation {$act->id} - Trade timestamp: {$timestamp} (" . date('Y-m-d H:i:s', $timestamp) . ")");
                Log::info("RunBot: Activation {$act->id} - Daily timestamp: {$act->daily_timestamp} (" . date('Y-m-d H:i:s', $act->daily_timestamp) . ")");
                Log::info("RunBot: Activation {$act->id} - Current date (dm): {$current_date}, Daily date (dm): {$daily_date}");
                Log::info("RunBot: Activation {$act->id} - Date match: " . ($current_date == $daily_date ? 'YES' : 'NO'));
                Log::info("RunBot: Activation {$act->id} - Time check: {$current_time} > {$timestamp} = " . ($current_time > $timestamp ? 'YES' : 'NO'));

                $return = $act->capital * $percentage / 100;

                Log::info("RunBot: Activation {$act->id} - Calculated return: {$return} (Capital: {$act->capital} × {$percentage}%)");

                if ($current_date == $daily_date && $current_time > $timestamp) {
                    Log::info("✅ RunBot: Activation {$act->id} - CONDITIONS MET! Executing trade...");

                    // Update sequences
                    $decodedSequence = json_decode($act->daily_sequence, true);
                    if (is_array($decodedSequence) && count($decodedSequence) > 0) {
                        array_shift($decodedSequence);
                        $daily_sequence = json_encode($decodedSequence);
                        Log::info("RunBot: Activation {$act->id} - Remaining sequence items: " . count($decodedSequence));
                    } else {
                        $daily_sequence = json_encode([]);
                        Log::info("RunBot: Activation {$act->id} - Sequence is now empty");
                    }

                    $decodedTimestamps = json_decode($act->gen_timestamps, true);
                    if (is_array($decodedTimestamps) && count($decodedTimestamps) > 0) {
                        array_shift($decodedTimestamps);
                        $next_trade = $decodedTimestamps[0] ?? null;
                        $gen_timestamps = json_encode($decodedTimestamps);
                        Log::info("RunBot: Activation {$act->id} - Next trade timestamp: " . ($next_trade ? date('Y-m-d H:i:s', $next_trade) : 'NULL'));
                    } else {
                        $gen_timestamps = json_encode([]);
                        $next_trade = null;
                        Log::info("RunBot: Activation {$act->id} - No more trade timestamps");
                    }

                    if ($exit_price > 0) {
                        Log::info("RunBot: Activation {$act->id} - Updating balances...");
                        
                        $bal = BotActivation::find($act->id);
                        $old_balance = $bal->balance;
                        $old_daily_profit = $bal->daily_profit;
                        $old_profit = $bal->profit;
                        
                        $bal->balance = $act->balance + $return;
                        $bal->daily_profit = $act->daily_profit + $return;
                        $bal->profit = $act->profit + $return;
                        $bal->daily_sequence = $daily_sequence;
                        $bal->gen_timestamps = $gen_timestamps;
                        $bal->next_trade = $next_trade;
                        $bal->save();

                        Log::info("RunBot: Activation {$act->id} - Balance updated: {$old_balance} → {$bal->balance} (+" . ($bal->balance - $old_balance) . ")");
                        Log::info("RunBot: Activation {$act->id} - Daily profit updated: {$old_daily_profit} → {$bal->daily_profit} (+" . ($bal->daily_profit - $old_daily_profit) . ")");
                        Log::info("RunBot: Activation {$act->id} - Total profit updated: {$old_profit} → {$bal->profit} (+" . ($bal->profit - $old_profit) . ")");

                        $history = new BotHistory();
                        $history->user_id = $act->user_id;
                        $history->bot_id = $act->bot_id;
                        $history->bot_activation_id = $act->id;
                        $history->pair = $randomPair['symbol'];
                        $history->entry_price = $entry_price;
                        $history->exit_price = $exit_price;
                        $history->profit = $return;
                        $history->profit_percent = $percentage;
                        $history->capital = $act->capital;
                        $history->timestamp = $timestamp;
                        $history->save();

                        Log::info("✅ RunBot: Created history record ID: {$history->id} for activation {$act->id}");

                        // ========================================
                        // FIX: CREDIT USER IMMEDIATELY AFTER TRADE
                        // ========================================
                        $user = User::find($act->user_id);

                        if ($user) {
                            $old_user_balance = $user->balance;
                            $user->balance += $return;
                            $user->save();

                            // Record transaction
                            recordNewTransaction($return, $user->id, 'credit', 'AI Bot Profit');

                            Log::info("✅ RunBot: Credited user {$user->id} with {$return} (balance: {$old_user_balance} → {$user->balance})");
                        } else {
                            Log::error("RunBot: User not found for crediting profit - activation {$act->id}, user_id {$act->user_id}");
                        }
                        // ========================================

                        $pair = $randomPair['symbol'];
                        $profit = formatAmount($return);
                        $profit_percentage = $percentage . '%';
                        $message = "*New Trade Notification* \n🚀Exit Time: " . date('d-m-y H:i:s', $timestamp) . " UTC \n🚀Trading Pair: " . $pair . "\n🚀Portfolio: " . formatAmount($act->capital) . "\n🚀Entry Price: " . $entry_price . "\n🚀Exit Price: " . $exit_price . "\n🚀Profit: " . $profit . "\n🚀Gain: " . $profit_percentage;
                        
                        if (function_exists('sendMessageTelegram')) {
                            sendMessageTelegram($message);
                            Log::info("RunBot: Telegram notification sent for activation {$act->id}");
                        }
                    } else {
                        Log::error("RunBot: Activation {$act->id} - Exit price is 0 or negative! Trade skipped.");
                    }
                } else {
                    Log::warning("❌ RunBot: Activation {$act->id} - CONDITIONS NOT MET");
                    if ($current_date != $daily_date) {
                        Log::warning("RunBot: Date mismatch - current: {$current_date}, expected: {$daily_date}");
                    }
                    if ($current_time <= $timestamp) {
                        $time_diff = $timestamp - $current_time;
                        Log::warning("RunBot: Time not reached - need to wait {$time_diff} seconds (" . gmdate('H:i:s', $time_diff) . ")");
                    }
                }
            } catch (\Exception $e) {
                Log::error("RunBot: Error processing activation {$act->id}: " . $e->getMessage());
                Log::error("RunBot: Stack trace: " . $e->getTraceAsString());
            }
        }

        Log::info('=== RunBot: Execution completed successfully ===');
        return true;
    } catch (\Exception $e) {
        Log::error('RunBot: Fatal error - ' . $e->getMessage());
        Log::error('RunBot: Stack trace: ' . $e->getTraceAsString());
        return false;
    }
}

//update daily timestamp
function updateTimestamp()
{
    try {
        Log::info('=== UpdateTimestamp: Starting execution ===');

        $today_start = Carbon::today()->startOfDay()->timestamp;

        Log::info("UpdateTimestamp: Today start: {$today_start} (" . date('Y-m-d H:i:s', $today_start) . ")");

        // FIX: Simplified query - only check if daily_timestamp is before today
        $bot_activations = BotActivation::where('status', 'active')
            ->where('daily_timestamp', '<', $today_start)
            ->take(20)
            ->get();

        Log::info('UpdateTimestamp: Found ' . $bot_activations->count() . ' activations to update');
        
        if ($bot_activations->isEmpty()) {
            Log::info('UpdateTimestamp: No activations need timestamp update');
            return true;
        }

        foreach ($bot_activations as $act) {
            try {
                Log::info("=== UpdateTimestamp: Processing activation ID: {$act->id} ===");
                Log::info("UpdateTimestamp: Current daily_timestamp: {$act->daily_timestamp} (" . date('Y-m-d H:i:s', $act->daily_timestamp) . ")");

                $bot = $act->bot;
                
                if (!$bot) {
                    Log::error("UpdateTimestamp: Bot not found for activation ID {$act->id}");
                    continue;
                }

                Log::info("UpdateTimestamp: Fetching trade data for bot ID: {$bot->id} (min: {$bot->daily_min}%, max: {$bot->daily_max}%)");
                $trade_data = tradeData($bot);

                if ($trade_data === false || !is_array($trade_data)) {
                    Log::error("UpdateTimestamp: tradeData() returned false or invalid data for activation ID {$act->id}");
                    Log::error("UpdateTimestamp: Trade data response: " . json_encode($trade_data));
                    continue;
                }

                Log::info("UpdateTimestamp: Trade data received for activation {$act->id}");
                Log::info("UpdateTimestamp: Timestamps count: " . (isset($trade_data['timestamps']) ? count($trade_data['timestamps']) : 0));
                Log::info("UpdateTimestamp: Sequence count: " . (isset($trade_data['sequence']) ? count($trade_data['sequence']) : 0));

                // ========================================
                // FIX: NO USER CREDITING HERE ANYMORE
                // Profits are now credited immediately in runBot()
                // ========================================

                // Update activation
                $update = BotActivation::find($act->id);
                $new_timestamp = time();
                $update->daily_timestamp = $new_timestamp;
                
                // Reset daily profit tracker (user was already credited in runBot)
                $update->daily_profit = 0;
                
                $update->gen_timestamps = json_encode($trade_data['timestamps'] ?? []);
                $update->daily_sequence = json_encode($trade_data['sequence'] ?? []);
                $update->next_trade = $trade_data['timestamps'][0] ?? null;
                $update->save();

                Log::info("✅ UpdateTimestamp: Updated activation {$act->id}");
                Log::info("UpdateTimestamp: New daily_timestamp: {$new_timestamp} (" . date('Y-m-d H:i:s', $new_timestamp) . ")");
                Log::info("UpdateTimestamp: Next trade: " . ($update->next_trade ? date('Y-m-d H:i:s', $update->next_trade) : 'NULL'));
                Log::info("UpdateTimestamp: Daily profit reset to 0 (user was already credited during trades)");
            } catch (\Exception $e) {
                Log::error("UpdateTimestamp: Error processing activation {$act->id}: " . $e->getMessage());
                Log::error("UpdateTimestamp: Stack trace: " . $e->getTraceAsString());
            }
        }

        Log::info('=== UpdateTimestamp: Execution completed successfully ===');
        return true;
    } catch (\Exception $e) {
        Log::error('UpdateTimestamp: Fatal error - ' . $e->getMessage());
        Log::error('UpdateTimestamp: Stack trace: ' . $e->getTraceAsString());
        return false;
    }
}

//change the status of all completed bots
// function endBot()
// {
//     try {
//         Log::info('=== EndBot: Starting execution ===');

//         BotActivation::where('status', 'active')
//             ->where('expires_in', '<', time())
//             ->chunk(100, function ($bot_activations) {
//                 Log::info('EndBot: Processing chunk of ' . $bot_activations->count() . ' expired activations');

//                 foreach ($bot_activations as $act) {
//                     try {
//                         Log::info("EndBot: Processing expired activation ID: {$act->id} (expires_in: {$act->expires_in})");

//                         $update = BotActivation::find($act->id);
//                         $update->status = 'expired';
//                         $update->balance = 0;
//                         $update->save();

//                         // Credit user with capital
//                         $user = $act->user;
//                         if ($user) {
//                             $old_balance = $user->balance;
//                             $credit = User::find($user->id);
//                             $credit->balance = $user->balance + $act->capital;
//                             $credit->save();

//                             // Record transaction
//                             recordNewTransaction($act->capital, $user->id, 'credit', 'AI Bot Capital');

//                             Log::info("✅ EndBot: Expired activation {$act->id}, credited user {$user->id} with capital: {$act->capital} (balance: {$old_balance} → {$credit->balance})");
//                         } else {
//                             Log::error("EndBot: User not found for activation {$act->id}");
//                         }
//                     } catch (\Exception $e) {
//                         Log::error("EndBot: Error processing activation {$act->id}: " . $e->getMessage());
//                     }
//                 }
//             });

//         Log::info('=== EndBot: Execution completed successfully ===');
//         return true;
//     } catch (\Exception $e) {
//         Log::error('EndBot: Fatal error - ' . $e->getMessage());
//         Log::error('EndBot: Stack trace: ' . $e->getTraceAsString());
//         return false;
//     }
// }



//change the status of all completed bots
// NOTE: Capital is NOT automatically returned to users upon expiration.
// Admin must manually review and return a portion of capital if needed
// via the admin endpoint: POST /api/admin/bots/activations/{id}/return-capital
function endBot()
{
    try {
        Log::info('=== EndBot: Starting execution ===');

        BotActivation::where('status', 'active')
            ->where('expires_in', '<', time())
            ->chunk(100, function ($bot_activations) {
                Log::info('EndBot: Processing chunk of ' . $bot_activations->count() . ' expired activations');

                foreach ($bot_activations as $act) {
                    try {
                        Log::info("EndBot: Processing expired activation ID: {$act->id} (expires_in: {$act->expires_in})");

                        $update = BotActivation::find($act->id);
                        $update->status = 'expired';
                        $update->balance = 0;
                        $update->save();

                        // Capital is NOT returned automatically.
                        // Users must contact support. Admin will review profit history
                        // and decide whether to return a portion of the capital.
                        Log::info("✅ EndBot: Expired activation {$act->id} for user {$act->user_id}. Capital ({$act->capital}) retained. User must contact support for capital review.");
                    } catch (\Exception $e) {
                        Log::error("EndBot: Error processing activation {$act->id}: " . $e->getMessage());
                    }
                }
            });

        Log::info('=== EndBot: Execution completed successfully ===');
        return true;
    } catch (\Exception $e) {
        Log::error('EndBot: Fatal error - ' . $e->getMessage());
        Log::error('EndBot: Stack trace: ' . $e->getTraceAsString());
        return false;
    }
}

/**
 * Generate trade data locally without relying on external API
 * This function creates realistic trading timestamps and percentage sequences
 * 
 * @param int $intervals Number of trades to generate (1-15)
 * @param float $totalPercentage Total percentage to distribute across intervals
 * @return array|false Array with timestamps, sequence, and metadata or false on failure
 */
function generateTradeDataLocally($intervals, $totalPercentage)
{
    try {
        Log::info("=== GenerateTradeDataLocally: Starting ===");
        Log::info("GenerateTradeDataLocally: Intervals requested: {$intervals}, Total percentage: {$totalPercentage}");
        
        // Validate and sanitize inputs
        $intervals = max(1, min(15, (int)$intervals));
        $totalPercentage = (float)$totalPercentage;
        
        // Clamp percentage to reasonable range (-10% to +10%)
        if ($totalPercentage < -10) {
            Log::warning("GenerateTradeDataLocally: Percentage too low ({$totalPercentage}), capping to -10%");
            $totalPercentage = -10;
        }
        if ($totalPercentage > 10) {
            Log::warning("GenerateTradeDataLocally: Percentage too high ({$totalPercentage}), capping to 10%");
            $totalPercentage = 10;
        }
        
        Log::info("GenerateTradeDataLocally: Validated - Intervals: {$intervals}, Percentage: {$totalPercentage}");
        
        $timestamps = [];
        $sequence = [];
        
        // Get current time and calculate today's trading window
        $now = time();
        $todayStart = strtotime('today 00:00:00');
        $todayEnd = strtotime('today 23:59:59');
        
        // Define trading hours (6 AM to 11 PM)
        $tradingStart = strtotime('today 06:00:00');
        $tradingEnd = strtotime('today 23:00:00');
        
        Log::info("GenerateTradeDataLocally: Current time: {$now} (" . date('Y-m-d H:i:s', $now) . ")");
        Log::info("GenerateTradeDataLocally: Trading window: " . date('Y-m-d H:i:s', $tradingStart) . " to " . date('Y-m-d H:i:s', $tradingEnd));
        
        // If current time is past trading end, use tomorrow's window
        if ($now >= $tradingEnd) {
            $tradingStart = strtotime('tomorrow 06:00:00');
            $tradingEnd = strtotime('tomorrow 23:00:00');
            Log::info("GenerateTradeDataLocally: Current time past trading hours, using tomorrow's window");
        }
        
        // Calculate base time (start from current time or trading start, whichever is later)
        $baseTime = max($now + 300, $tradingStart); // Add 5 minutes buffer from current time
        
        Log::info("GenerateTradeDataLocally: Base time: {$baseTime} (" . date('Y-m-d H:i:s', $baseTime) . ")");
        
        // Calculate available time window
        $availableTime = $tradingEnd - $baseTime;
        
        if ($availableTime <= 0) {
            // No time left today, use tomorrow
            $tradingStart = strtotime('tomorrow 06:00:00');
            $tradingEnd = strtotime('tomorrow 23:00:00');
            $baseTime = $tradingStart;
            $availableTime = $tradingEnd - $baseTime;
            Log::info("GenerateTradeDataLocally: No time left today, using tomorrow");
        }
        
        Log::info("GenerateTradeDataLocally: Available time: {$availableTime} seconds (" . gmdate('H:i:s', $availableTime) . ")");
        
        // Calculate time interval between trades (minimum 15 minutes = 900 seconds)
        $minInterval = 900; // 15 minutes
        $timeInterval = max($minInterval, floor($availableTime / $intervals));
        
        Log::info("GenerateTradeDataLocally: Time interval between trades: {$timeInterval} seconds (" . gmdate('H:i:s', $timeInterval) . ")");
        
        // Generate timestamps with realistic distribution
        for ($i = 0; $i < $intervals; $i++) {
            // Add some randomness (±10% of interval)
            $randomOffset = rand(-($timeInterval * 0.1), ($timeInterval * 0.1));
            $timestamp = $baseTime + ($timeInterval * $i) + $randomOffset;
            
            // Ensure timestamp doesn't exceed trading end
            if ($timestamp > $tradingEnd) {
                $timestamp = $tradingEnd - rand(300, 900); // 5-15 minutes before end
            }
            
            $timestamps[] = $timestamp;
            Log::info("GenerateTradeDataLocally: Generated timestamp {$i}: {$timestamp} (" . date('Y-m-d H:i:s', $timestamp) . ")");
        }
        
        // Generate percentage sequence with realistic distribution
        $remainingPercentage = $totalPercentage;
        $remainingIntervals = $intervals;
        
        for ($i = 0; $i < $intervals; $i++) {
            if ($i === $intervals - 1) {
                // Last interval gets all remaining percentage
                $percentage = round($remainingPercentage, 2);
            } else {
                // Calculate fair share with variance
                $fairShare = $remainingPercentage / $remainingIntervals;
                $variance = $fairShare * (rand(70, 130) / 100); // ±30% variance
                
                // Ensure we don't allocate more than remaining
                $percentage = round(min($variance, abs($remainingPercentage)), 2);
                
                // Maintain sign
                if ($remainingPercentage < 0) {
                    $percentage = -abs($percentage);
                }
                
                $remainingPercentage -= $percentage;
                $remainingIntervals--;
            }
            
            $sequence[] = $percentage;
            Log::info("GenerateTradeDataLocally: Generated percentage {$i}: {$percentage}%");
        }
        
        // Validate total matches (with small tolerance for rounding)
        $generatedTotal = array_sum($sequence);
        $difference = round($totalPercentage - $generatedTotal, 2);
        
        if (abs($difference) > 0.02) {
            // Adjust last element to match exact total
            $sequence[$intervals - 1] = round($sequence[$intervals - 1] + $difference, 2);
            Log::info("GenerateTradeDataLocally: Adjusted last percentage by {$difference} to match total");
        }
        
        $finalTotal = array_sum($sequence);
        
        $result = [
            'timestamps' => $timestamps,
            'sequence' => $sequence,
            'total_percentage' => (string)$totalPercentage,
            'generated_percentage' => round($finalTotal, 2)
        ];
        
        Log::info("✅ GenerateTradeDataLocally: Successfully generated trade data");
        Log::info("GenerateTradeDataLocally: Timestamps: " . json_encode($timestamps));
        Log::info("GenerateTradeDataLocally: Sequence: " . json_encode($sequence));
        Log::info("GenerateTradeDataLocally: Requested total: {$totalPercentage}%, Generated total: {$finalTotal}%");
        
        return $result;
        
    } catch (\Exception $e) {
        Log::error("GenerateTradeDataLocally: Fatal error - " . $e->getMessage());
        Log::error("GenerateTradeDataLocally: Stack trace: " . $e->getTraceAsString());
        
        // Return safe fallback
        return [
            'timestamps' => [time() + 3600],
            'sequence' => [$totalPercentage],
            'total_percentage' => (string)$totalPercentage,
            'generated_percentage' => $totalPercentage
        ];
    }
}

/**
 * Generate trade data for a bot - now uses local generation instead of API
 * 
 * @param object $bot Bot object with daily_min and daily_max properties
 * @return array|false Array with timestamps and sequence or false on failure
 */
function tradeData($bot)
{
    try {
        Log::info("=== TradeData: Starting for bot ID: {$bot->id} ===");

        // Validate bot properties
        if (!isset($bot->daily_min) || !isset($bot->daily_max)) {
            Log::error("TradeData: Bot missing daily_min or daily_max properties");
            return false;
        }

        // Get trade interval configuration (limit to 15 max)
        $bot_min_trade = site('bot_min_trade') ?: 3;
        $bot_max_trade = site('bot_max_trade') ?: 12;
        
        Log::info("TradeData: Configuration - bot_min_trade: {$bot_min_trade}, bot_max_trade: {$bot_max_trade}");
        
        // Cap intervals to API limit of 15
        $bot_min_trade = min($bot_min_trade, 15);
        $bot_max_trade = min($bot_max_trade, 15);
        
        // Ensure min is not greater than max
        if ($bot_min_trade > $bot_max_trade) {
            $bot_min_trade = $bot_max_trade;
        }
        
        // Generate random number of intervals within range
        $intervals = rand($bot_min_trade, $bot_max_trade);
        Log::info("TradeData: Generated intervals: {$intervals}");

        // Generate percentage using weighted average algorithm
        $daily_min = (float)$bot->daily_min;
        $daily_max = (float)$bot->daily_max;
        
        $percentages = [$daily_min, $daily_max];
        $percentage_count = count($percentages);

        // Build pool of percentage options
        while ($percentage_count < 15) {
            // Pick 3 random percentages and calculate weighted average
            $first = $percentages[array_rand($percentages)];
            $second = $percentages[array_rand($percentages)];
            $third = $percentages[array_rand($percentages)];
            
            $average = ($first + $second + $third) / 3;
            $average = round($average, 2);
            
            $percentages[] = $average;
            $percentage_count++;
        }

        // Select random percentage from pool
        $totalPercentage = $percentages[array_rand($percentages)];
        Log::info("TradeData: Selected total percentage: {$totalPercentage}% from pool of " . count($percentages) . " options");

        // Generate trade data locally instead of calling API
        $data = generateTradeDataLocally($intervals, $totalPercentage);
        
        if (!$data || !isset($data['timestamps']) || !isset($data['sequence'])) {
            Log::error("TradeData: Local generation failed - invalid response");
            return false;
        }
        
        if (!is_array($data['timestamps']) || !is_array($data['sequence'])) {
            Log::error("TradeData: Invalid data types - timestamps: " . gettype($data['timestamps']) . ", sequence: " . gettype($data['sequence']));
            return false;
        }
        
        if (count($data['timestamps']) === 0 || count($data['sequence']) === 0) {
            Log::error("TradeData: Empty arrays - timestamps: " . count($data['timestamps']) . ", sequence: " . count($data['sequence']));
            return false;
        }

        Log::info("✅ TradeData: Successfully generated local data - " . count($data['timestamps']) . " timestamps, " . count($data['sequence']) . " sequence items");
        Log::info("TradeData: Total percentage requested: {$totalPercentage}%, Generated: {$data['generated_percentage']}%");
        
        return $data;
        
    } catch (\Exception $e) {
        Log::error("TradeData: Fatal error - " . $e->getMessage());
        Log::error("TradeData: Stack trace: " . $e->getTraceAsString());
        return false;
    }
}