<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Coin;
use App\Models\UserCoinBalance;
use GuzzleHttp\Client;

class UpdateCoinPrices extends Command
{
    protected $signature = 'update:coin-prices';
    protected $description = 'Fetch and update live coin prices and adjust user balances based on price changes';

    public function handle()
    {
        $coins = Coin::where('customcoin', 0)->get(); // Only fetch non-custom coins
        $client = new Client();

        foreach ($coins as $coin) {
            try {
                // Fetch the live price from CoinGecko API
                $response = $client->get("https://api.coingecko.com/api/v3/simple/price?ids={$coin->sname}&vs_currencies=usd", [
                    'timeout' => 5, // Add timeout to prevent indefinite waiting
                ]);
                $priceData = json_decode($response->getBody(), true);

                $newPrice = $priceData[$coin->sname]['usd'] ?? $coin->latest_price;

                if ($newPrice && $coin->latest_price !== $newPrice) {
                    $this->info("Price for {$coin->name} updated: {$coin->latest_price} → $newPrice");

                    // Update the coin price
                    $oldPrice = $coin->latest_price;
                    $coin->latest_price = $newPrice;
                    $coin->save();

                    // Adjust user balances affected by this coin
                    $this->adjustUserBalances($coin, $oldPrice, $newPrice);
                }
            } catch (\Exception $e) {
                \Log::error("Error fetching price for {$coin->name} ({$coin->symbol}): " . $e->getMessage());
                $this->error("Failed to update price for {$coin->name} ({$coin->symbol})");
            }
        }

        $this->info('Coin prices updated and user balances adjusted successfully!');
    }

    private function adjustUserBalances(Coin $coin, $oldPrice, $newPrice)
    {
        if ($oldPrice > 0 && $newPrice > 0) {
            $percentageChange = (($newPrice - $oldPrice) / $oldPrice) * 100;
            $this->info("Processing {$coin->name}: Old Price = $oldPrice, New Price = $newPrice, Change = {$percentageChange}%");

            $userBalances = UserCoinBalance::where('coin_id', $coin->id)->get();

            foreach ($userBalances as $userBalance) {
                $oldCryptoBalance = $userBalance->balance; // User's current crypto balance

                // Adjust the crypto balance based on the percentage change
                $adjustedBalance = $oldCryptoBalance * (1 + ($percentageChange / 100));

                // Debugging log for before and after values
                $this->info("User ID {$userBalance->user_id}: Old Balance = $oldCryptoBalance, New Balance = $adjustedBalance");

                // Save the new balance
                $userBalance->balance = $adjustedBalance;
                $userBalance->save();
            }
        } else {
            $this->warn("Skipped {$coin->name}: Invalid Old Price = $oldPrice or New Price = $newPrice");
        }
    }
}
