<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Key\Deterministic\HierarchicalKeyFactory;
use BitWasp\Bitcoin\Network\NetworkFactory;
use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress;
use BitWasp\Bitcoin\Crypto\Hash;
use App\Services\CryptoService;

class CryptoAsset extends Model
{
    use HasFactory;

     protected $fillable = [
        'user_id',
        'btc_balance',
        'btc_status',
        'btc_address',
        'btc_fee',
        'usdt_trc20_balance',
        'usdt_trc20_status',
        'usdt_trc20_address',
        'usdt_trc20_fee',
        'usdt_erc20_balance',
        'usdt_erc20_status',
        'usdt_erc20_address',
        'usdt_erc20_fee',
        'eth_balance',
        'eth_status',
        'eth_address',
        'eth_fee',
        'trx_balance',
        'trx_status',
        'trx_address',
        'trx_fee',
        'usdt_bep20_balance',
        'usdt_bep20_status',
        'usdt_bep20_address',
        'usdt_bep20_fee',
        'bch_balance',
        'bch_status',
        'bch_address',
        'bch_fee',
        'ltc_balance',
        'ltc_status',
        'ltc_address',
        'ltc_fee',
        'xlm_balance',
        'xlm_status',
        'xlm_address',
        'xlm_fee',
        'dash_balance',
        'dash_status',
        'dash_address',
        'dash_fee',
        'sol_balance',
        'sol_status',
        'sol_address',
        'sol_fee',
        'bnb_balance',
        'bnb_status',
        'bnb_address',
        'bnb_fee',
        'dot_balance',
        'dot_status',
        'dot_address',
        'dot_fee',
        'xrp_balance',
        'xrp_status',
        'xrp_address',
        'xrp_fee',
    ];

    protected $casts = [
        'btc_status' => 'boolean',
        'usdt_trc20_status' => 'boolean',
        'usdt_erc20_status' => 'boolean',
        'eth_status' => 'boolean',
        'trx_status' => 'boolean',
        'usdt_bep20_status' => 'boolean',
        'bch_status' => 'boolean',
        'ltc_status' => 'boolean',
        'xlm_status' => 'boolean',
        'dash_status' => 'boolean',
        'sol_status' => 'boolean',
        'bnb_status' => 'boolean',
        'dot_status' => 'boolean',
        'xrp_status' => 'boolean',
        'btc_balance' => 'decimal:4',
        'usdt_trc20_balance' => 'decimal:4',
        'usdt_erc20_balance' => 'decimal:4',
        'eth_balance' => 'decimal:4',
        'trx_balance' => 'decimal:4',
        'usdt_bep20_balance' => 'decimal:4',
        'bch_balance' => 'decimal:4',
        'ltc_balance' => 'decimal:4',
        'xlm_balance' => 'decimal:4',
        'dash_balance' => 'decimal:4',
        'sol_balance' => 'decimal:4',
        'bnb_balance' => 'decimal:4',
        'dot_balance' => 'decimal:4',
        'xrp_balance' => 'decimal:4',
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
    
    // Add this to your CryptoAsset model
public function debugStatusFields()
{
    $statusFields = [
        'btc_status',
        'usdt_trc20_status',
        'usdt_erc20_status',
        'eth_status',
        'trx_status',
        'usdt_bep20_status',
        'bch_status',
        'ltc_status',
        'xlm_status',
        'dash_status',
        'sol_status',
        'bnb_status',
        'dot_status',
        'xrp_status'
    ];

    $statuses = [];
    foreach ($statusFields as $field) {
        $statuses[$field] = $this->$field;
    }

    return $statuses;
}

    /**
     * Check if any address is set for a specific crypto
     */
    public function hasAddress(string $crypto): bool
    {
        $addressField = "{$crypto}_address";
        return !empty($this->$addressField);
    }

    /**
     * Get address for specific crypto
     */
    public function getAddress(string $crypto): ?string
    {
        $addressField = "{$crypto}_address";
        return $this->$addressField;
    }
    
    public static function getSupportedCryptos(): array
    {
        return [
            'btc' => [
                'name' => 'Bitcoin',
                'balance_field' => 'btc_balance',
                'status_field' => 'btc_status',
                'address_field' => 'btc_address',
                'icon' => 'fab fa-bitcoin',
                'color' => 'bg-orange-500',
            ],
            'usdt_trc20' => [
                'name' => 'USDT TRC20',
                'balance_field' => 'usdt_trc20_balance',
                'status_field' => 'usdt_trc20_status',
                'address_field' => 'usdt_trc20_address',
                'icon' => 'fas fa-dollar-sign', // Update with appropriate icon if available
                'color' => 'bg-green-500',
            ],
            'usdt_erc20' => [
                'name' => 'USDT ERC20',
                'balance_field' => 'usdt_erc20_balance',
                'status_field' => 'usdt_erc20_status',
                'address_field' => 'usdt_erc20_address',
                'icon' => 'fas fa-dollar-sign', // Update with appropriate icon if available
                'color' => 'bg-green-500',
            ],
            'eth' => [
                'name' => 'Ethereum',
                'balance_field' => 'eth_balance',
                'status_field' => 'eth_status',
                'address_field' => 'eth_address',
                'icon' => 'fab fa-ethereum',
                'color' => 'bg-blue-500',
            ],
            'trx' => [
                'name' => 'Tron',
                'balance_field' => 'trx_balance',
                'status_field' => 'trx_status',
                'address_field' => 'trx_address',
                'icon' => 'fas fa-bolt', // Replace with a suitable Tron icon if available
                'color' => 'bg-red-500',
            ],
            'usdt_bep20' => [
                'name' => 'USDT BNB',
                'balance_field' => 'usdt_bep20_balance',
                'status_field' => 'usdt_bep20_status',
                'address_field' => 'usdt_bep20_address',
                'icon' => 'fas fa-dollar-sign', // Update with appropriate icon if available
                'color' => 'bg-green-500',
            ],
            'bch' => [
                'name' => 'Bitcoin Cash',
                'balance_field' => 'bch_balance',
                'status_field' => 'bch_status',
                'address_field' => 'bch_address',
                'icon' => 'fab fa-bitcoin', // Replace with a different icon if available
                'color' => 'bg-green-600',
            ],
            'ltc' => [
                'name' => 'Litecoin',
                'balance_field' => 'ltc_balance',
                'status_field' => 'ltc_status',
                'address_field' => 'ltc_address',
                'icon' => 'fas fa-coins', // Update with appropriate icon if available
                'color' => 'bg-gray-500',
            ],
            'xlm' => [
                'name' => 'Stellar',
                'balance_field' => 'xlm_balance',
                'status_field' => 'xlm_status',
                'address_field' => 'xlm_address',
                'icon' => 'fas fa-star', // Update with appropriate icon if available
                'color' => 'bg-blue-400',
            ],
            'dash' => [
                'name' => 'Dash',
                'balance_field' => 'dash_balance',
                'status_field' => 'dash_status',
                'address_field' => 'dash_address',
                'icon' => 'fas fa-tachometer-alt', // Update with appropriate icon if available
                'color' => 'bg-blue-600',
            ],
            'sol' => [
                'name' => 'Solana',
                'balance_field' => 'sol_balance',
                'status_field' => 'sol_status',
                'address_field' => 'sol_address',
                'icon' => 'fas fa-sun', // Update with appropriate icon if available
                'color' => 'bg-purple-500',
            ],
            'bnb' => [
                'name' => 'Binance Coin',
                'balance_field' => 'bnb_balance',
                'status_field' => 'bnb_status',
                'address_field' => 'bnb_address',
                'icon' => 'fas fa-coins', // Update with appropriate icon if available
                'color' => 'bg-yellow-500',
            ],
            'dot' => [
                'name' => 'Polkadot',
                'balance_field' => 'dot_balance',
                'status_field' => 'dot_status',
                'address_field' => 'dot_address',
                'icon' => 'fas fa-circle', // Update with appropriate icon if available
                'color' => 'bg-pink-500',
            ],
            'xrp' => [
                'name' => 'Xrp',
                'balance_field' => 'xrp_balance',
                'status_field' => 'xrp_status',
                'address_field' => 'xrp_address',
                'icon' => 'fas fa-circle', // Update with appropriate icon if available
                'color' => 'bg-purple-500',
            ],
            // Add other cryptocurrencies here as needed
        ];
    }
    
    private function getCryptoNetwork(string $symbol): ?string
    {
        $networkMap = [
            'usdt_trc20' => 'TRC20',
            'usdt_erc20' => 'ERC20',
            'usdt_bep20' => 'BNB',
            // Add other mappings if necessary
        ];

        return $networkMap[strtolower($symbol)] ?? null;
    }
    
    public function getActiveCryptos(): array
    {
        $supportedCryptos = self::getSupportedCryptos();
        $activeCryptos = [];

        foreach ($supportedCryptos as $key => $crypto) {
            $balance = (float) $this->{$crypto['balance_field']};
            $status = (bool) $this->{$crypto['status_field']};
            $address = $this->{$crypto['address_field']};

            if (($balance > 0 || $status) && !empty($address)) {
                $activeCryptos[] = [
                    'symbol' => strtoupper($key),
                    'name' => $crypto['name'],
                    'balance' => $balance,
                    'address' => $address,
                    'icon' => $crypto['icon'],
                    'color' => $crypto['color'],
                    'network' => $this->getCryptoNetwork($key),
                ];
            }
        }

        return $activeCryptos;
    }
   
public function getTotalBalanceUSD(): float
{
    $cryptoService = new CryptoService();
    $prices = $cryptoService->getPrices();

    $symbolMap = [
        'btc' => 'bitcoin',
        'eth' => 'ethereum',
        'usdt_trc20' => 'tether',
        'usdt_erc20' => 'tether',
        'usdt_bep20' => 'tether',
        'trx' => 'tron',
        'bch' => 'bitcoin-cash',
        'ltc' => 'litecoin',
        'xlm' => 'stellar',
        'dash' => 'dash',
        'sol' => 'solana',
        'bnb' => 'binancecoin',
        'dot' => 'polkadot',
        'xrp' => 'xrp'
    ];

    $total = 0;

    foreach ($symbolMap as $assetSymbol => $priceSymbol) {
        $balanceField = "{$assetSymbol}_balance";
        $statusField = "{$assetSymbol}_status";

        if ($this->$statusField && $this->$balanceField > 0) {
            $price = $prices[$priceSymbol]['usd'] ?? 0;
            $total += $this->$balanceField * $price;
        }
    }

    return round($total, 2);
}

public function getCryptoValueUSD(string $symbol): float
{
    $cryptoService = new CryptoService();
    $prices = $cryptoService->getPrices();

    $symbolMap = [
        'btc' => 'bitcoin',
        'eth' => 'ethereum',
        'usdt_trc20' => 'tether',
        'usdt_erc20' => 'tether',
        'usdt_bep20' => 'tether',
        'trx' => 'tron',
        'bch' => 'bitcoin-cash',
        'ltc' => 'litecoin',
        'xlm' => 'stellar',
        'dash' => 'dash',
        'sol' => 'solana',
        'bnb' => 'binancecoin',
        'dot' => 'polkadot',
        'xrp' => 'xrp'
    ];

    $priceSymbol = $symbolMap[$symbol] ?? null;
    if (!$priceSymbol) {
        return 0.0;
    }

    $balanceField = "{$symbol}_balance";
    $statusField = "{$symbol}_status";

    if (!$this->$statusField || $this->$balanceField <= 0) {
        return 0.0;
    }

    $price = $prices[$priceSymbol]['usd'] ?? 0;
    return round($this->$balanceField * $price, 2);
}

    /**
     * Generate wallet addresses for all cryptocurrencies if not exists
     */
    public function generateAddressesIfNull()
{
    $cryptos = [
        'btc' => 'btc_address',
        'usdt_trc20' => 'usdt_trc20_address',
        'usdt_erc20' => 'usdt_erc20_address',
        'eth' => 'eth_address',
        'trx' => 'trx_address',
        'usdt_bep20' => 'usdt_bep20_address',
        'bch' => 'bch_address',
        'ltc' => 'ltc_address',
        'xlm' => 'xlm_address',
        'dash' => 'dash_address',
        'sol' => 'sol_address',
        'bnb' => 'bnb_address',
        'dot' => 'dot_address',
        'xrp' => 'xrp_address'
    ];

    foreach ($cryptos as $crypto => $settingKey) {
        $addressField = "{$crypto}_address";
        if (empty($this->$addressField)) {
            $settingValue = Setting::where('key', $settingKey)->value('value');
            if (!empty($settingValue)) {
                $this->$addressField = $settingValue;
            }
        }
    }

    $this->save();
}

    /**
     * Generate Bitcoin Address
     */
    protected function generateBitcoinAddress(): string
    {
         try {
        // Generate a random address similar to Bitcoin
        $privateKey = bin2hex(random_bytes(32));
        $addressHash = hash('sha256', $privateKey);
        $addressBytes = substr($addressHash, -40);
        
        return 'bc1' . $addressBytes;
    } catch (\Exception $e) {
        \Log::error('Bitcoin Address Generation Failed: ' . $e->getMessage());
        return '';
    }
    }

    /**
     * Generate Ethereum Address
     */
    protected function generateEthereumAddress(): string
    {
        try {
            
            $randomBytes = random_bytes(20); // 20 bytes = 40 hex characters
            $addressBytes = bin2hex($randomBytes);
            
            return '0x' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Ethereum Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Bitcoin Cash Address
     */
   protected function generateBitcoinCashAddress(): string
{
    try {
        
        $privateKey = bin2hex(random_bytes(32));
        $addressHash = hash('sha256', $privateKey);
        $addressBytes = substr($addressHash, -40);
        
        return '1' . $addressBytes;
    } catch (\Exception $e) {
        \Log::error('Bitcoin Cash Address Generation Failed: ' . $e->getMessage());
        return '';
    }
}

    /**
     * Generate Litecoin Address
     */
    protected function generateLitecoinAddress(): string
{
    try {
        
        $privateKey = bin2hex(random_bytes(32));
        $addressHash = hash('sha256', $privateKey);
        $addressBytes = substr($addressHash, -40);
        
        return 'L' . $addressBytes;
    } catch (\Exception $e) {
        \Log::error('Litecoin Address Generation Failed: ' . $e->getMessage());
        return '';
    }
}

    /**
     * Generate Tron Address
     */
    protected function generateTronAddress(): string
    {
        try {
            
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -40);
            
            return 'T' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Tron Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Binance Smart Chain Address
     */
    protected function generateBinanceSmartChainAddress(): string
    {
        
        return $this->generateEthereumAddress();
    }

    /**
     * Generate Stellar Address
     */
    protected function generateStellarAddress(): string
    {
        try {
           
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -56);
            
            return 'G' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Stellar Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Dash Address
     */
    protected function generateDashAddress(): string
    {
        try {
            
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -34);
            
            return 'X' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Dash Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Solana Address
     */
    protected function generateSolanaAddress(): string
    {
        try {
            // Simple Solana-like address generation
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -44);
            
            return 'So' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Solana Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Binance Coin Address
     */
    protected function generateBinanceAddress(): string
    {
        try {
            
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -38);
            
            return 'bnb' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Binance Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Polkadot Address
     */
    protected function generatePolkadotAddress(): string
    {
        try {
           
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -48);
            
            return '5' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Polkadot Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }

    /**
     * Generate Xrp Address
     */
    protected function generateXrpAddress(): string
    {
        try {
           
            $privateKey = bin2hex(random_bytes(32));
            $addressHash = hash('sha256', $privateKey);
            $addressBytes = substr($addressHash, -48);
            
            return 'x' . $addressBytes;
        } catch (\Exception $e) {
            \Log::error('Xrp Address Generation Failed: ' . $e->getMessage());
            return '';
        }
    }
}