<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Services\CryptoService;
use Illuminate\Http\Request;
use App\Models\CryptoAsset;
use App\Models\User;
use App\Models\Transaction;
use App\Models\Notification;
use App\Mail\TransactionEmail;
use Illuminate\Support\Facades\Mail;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class SendController extends Controller
{
    private $cryptoService;

    public function __construct(CryptoService $cryptoService)
    {
        $this->cryptoService = $cryptoService;
    }

    private function formatAsset(
        $symbol,
        $name,
        $coinId,
        $balance,
        $network = null,
        $networkSymbol = null
    ) {
        $prices = $this->cryptoService->getPrices();
        $price = $prices[$coinId]["usd"] ?? 0;
        $change = $prices[$coinId]["usd_24h_change"] ?? 0;

        $asset = [
            "symbol" => $symbol,
            "name" => $name . ($network ? " ($network)" : ""),
            "balance" => $balance,
            "value" => $balance * $price,
            "price" => $price,
            "change" =>
                $change < 0
                    ? number_format($change, 2)
                    : "+" . number_format($change, 2),
            "icon_url" => $this->cryptoService->getIconUrl($coinId),
            "network" => $network,
        ];

        if ($networkSymbol) {
            $asset["network_url"] = $this->cryptoService->getIconUrl(
                $networkSymbol
            );
        }

        return $asset;
    }

    private function mapCryptoAssets(CryptoAsset $cryptoAsset)
    {
        $assets = [];

        // Bitcoin
        if ($cryptoAsset->btc_status) {
            $assets[] = $this->formatAsset(
                "BTC",
                "Bitcoin",
                "bitcoin",
                $cryptoAsset->btc_balance
            );
        }

        // USDT with different networks
        $usdtNetworks = [
            "trc20" => [
                "status" => "usdt_trc20_status",
                "balance" => "usdt_trc20_balance",
                "network" => "TRC20",
                "symbol" => "tron",
            ],
            "bep20" => [
                "status" => "usdt_bep20_status",
                "balance" => "usdt_bep20_balance",
                "network" => "BNB",
                "symbol" => "binancecoin",
            ],
            "erc20" => [
                "status" => "usdt_erc20_status",
                "balance" => "usdt_erc20_balance",
                "network" => "ERC20",
                "symbol" => "ethereum",
            ],
        ];

        foreach ($usdtNetworks as $network => $config) {
            if ($cryptoAsset->{$config["status"]}) {
                $assets[] = $this->formatAsset(
                    "USDT",
                    "Tether",
                    "tether",
                    $cryptoAsset->{$config["balance"]},
                    $config["network"],
                    $config["symbol"]
                );
            }
        }

        // Other cryptocurrencies mapping
        $cryptoMapping = [
            "eth" => [
                "symbol" => "ETH",
                "name" => "Ethereum",
                "id" => "ethereum",
            ],
            "trx" => ["symbol" => "TRX", "name" => "Tron", "id" => "tron"],
            "bnb" => [
                "symbol" => "BNB",
                "name" => "Binance Coin",
                "id" => "binancecoin",
            ],
            "dot" => [
                "symbol" => "DOT",
                "name" => "Polkadot",
                "id" => "polkadot",
            ],
            "bch" => [
                "symbol" => "BCH",
                "name" => "Bitcoin Cash",
                "id" => "bitcoin-cash",
            ],
            "ltc" => [
                "symbol" => "LTC",
                "name" => "Litecoin",
                "id" => "litecoin",
            ],
            "xlm" => [
                "symbol" => "XLM",
                "name" => "Stellar",
                "id" => "stellar",
            ],
            "dash" => ["symbol" => "DASH", "name" => "Dash", "id" => "dash"],
            "sol" => ["symbol" => "SOL", "name" => "Solana", "id" => "solana"],
        ];

        foreach ($cryptoMapping as $key => $crypto) {
            $statusField = "{$key}_status";
            $balanceField = "{$key}_balance";

            if ($cryptoAsset->$statusField) {
                $assets[] = $this->formatAsset(
                    $crypto["symbol"],
                    $crypto["name"],
                    $crypto["id"],
                    $cryptoAsset->$balanceField
                );
            }
        }

        return $assets;
    }

    public function payidAssets()
    {
        $user = Auth::user();
        $cryptoAsset = CryptoAsset::where("user_id", $user->id)->first();

        if (!$cryptoAsset) {
            return redirect()
                ->route("dashboard")
                ->with("error", "No crypto assets found");
        }

        return view("user.send.assets-payid", [
            "assets" => $this->mapCryptoAssets($cryptoAsset),
        ]);
    }

    public function externalAssets()
    {
        $user = Auth::user();
        $cryptoAsset = CryptoAsset::where("user_id", $user->id)->first();

        if (!$cryptoAsset) {
            return redirect()
                ->route("dashboard")
                ->with("error", "No crypto assets found");
        }

        return view("user.send.assets-external", [
            "assets" => $this->mapCryptoAssets($cryptoAsset),
        ]);
    }

 public function payidDetails($symbol, $network = "native")
{
    $user = Auth::user();
    $cryptoAsset = CryptoAsset::where("user_id", $user->id)->first();

    if ($user->require_kyc && $user->kyc_status !== 'approved') {
        return redirect()
            ->route('kyc')
            ->with('error', 'Please verify your KYC to send crypto');
    }

    if (!$cryptoAsset) {
        return redirect()
            ->route("dashboard")
            ->with("error", "No crypto assets found");
    }

    if ($network === "BNB") {
        $network = "BEP20";
    }

    $asset = $this->getAssetDetails($cryptoAsset, $symbol, $network);

    if (!$asset) {
        return redirect()
            ->route("dashboard")
            ->with("error", "Asset not found");
    }

    // Get the fee field name based on symbol and network
    $feeField = $this->getBalanceField($symbol, $network);
    $feeField = str_replace('balance', 'fee', $feeField);
    
    // Add fee to asset array
    $asset['fee'] = $cryptoAsset->$feeField ?? 0;

    return view("user.send.payid-details", [
        "asset" => $asset,
    ]);
}

public function externalDetails($symbol, $network = "native")
{
    $user = Auth::user();
    $cryptoAsset = CryptoAsset::where("user_id", $user->id)->first();

    if ($user->require_kyc && $user->kyc_status !== 'approved') {
        return redirect()
            ->route('kyc')
            ->with('error', 'Please verify your KYC to send crypto');
    }

    if (!$cryptoAsset) {
        return redirect()
            ->route("dashboard")
            ->with("error", "No crypto assets found");
    }

    if ($network === "BNB") {
        $network = "BEP20";
    }

    $asset = $this->getAssetDetails($cryptoAsset, $symbol, $network, true);

    if (!$asset) {
        return redirect()
            ->route("dashboard")
            ->with("error", "Asset not found");
    }

    // Get the fee field name based on symbol and network
    $feeField = $this->getBalanceField($symbol, $network);
    $feeField = str_replace('balance', 'fee', $feeField);
    
    // Add fee to asset array
    $asset['fee'] = $cryptoAsset->$feeField ?? 0;
    
    // Get the current price for USD equivalent display
    $cryptoService = new CryptoService();
    $prices = $cryptoService->getPrices();
    $coinId = $cryptoService->getStandardSymbol($symbol);
    $asset['price'] = $prices[$coinId]["usd"] ?? 0;

    return view("user.send.external-details", [
        "asset" => $asset,
    ]);
}


    public function success(
        Request $request,
        $symbol,
        $network = "native",
        $transactionId
    ) {
        // Verify the transaction belongs to the authenticated user
        $transaction = Transaction::where('id', $transactionId)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        return view("user.send.payid-success", [
            "transaction" => $transaction,
            "symbol" => $symbol,
            "network" => $network,
        ]);
    }

    public function failed(Request $request, $symbol, $network = "native")
    {
        $error = session('error', 'Transaction failed');
        $errorCode = session('error_code', 'UNKNOWN_ERROR');
        $amount = session('amount', 0);

        return view("user.send.external-failed", [
            "symbol" => $symbol,
            "network" => $network,
            "error" => $error,
            "error_code" => $errorCode,
            "amount" => $amount,
            "available_balance" => session('available_balance', 0)
        ]);
    }

    public function verifyPayId(Request $request)
    {
        $request->validate([
            "payid" => "required|string",
        ]);

        $uuid = $request->payid;

        $recipient = User::where("uuid", $uuid)->first();

        if (!$recipient) {
            return response()->json([
                "success" => false,
                "message" => "PayID not found",
            ]);
        }

        return response()->json([
            "success" => true,
            "user" => [
                "name" => $recipient->name,
                "uuid" => $recipient->uuid,
            ],
        ]);
    }

    public function processPayId(Request $request, $symbol, $network = 'native')
{
    $validated = $request->validate([
        "payid" => "required|string",
        "amount" => "required|numeric|min:0",
    ]);
   

    DB::beginTransaction();
    try {
        $sender = Auth::user();
        $uuid = $request->payid;
        $recipient = User::where("uuid", $uuid)->first();
        
         if (!$sender->enable_crypto_sending) {
             DB::rollBack();
        return redirect()->route('send.payid.details', [
            'symbol' => $symbol,
            'network' => $network
        ])->with([
            'error' => 'Crypto sending is currently disabled. Please make a transaction to enable sending or contact support.',
            'error_code' => 'SENDING_DISABLED',
            'amount' => $request->amount
        ]);
    }

        if (!$recipient) {
            DB::rollBack();
            return redirect()->route('send.payid.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'PayID not found',
                'error_code' => 'RECIPIENT_NOT_FOUND',
                'amount' => $request->amount
            ]);
        }

        if ($sender->uuid === $uuid) {
            DB::rollBack();
            return redirect()->route('send.payid.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Cannot send to yourself',
                'error_code' => 'SELF_TRANSFER',
                'amount' => $request->amount
            ]);
        }

        // Get crypto assets
        $senderAsset = CryptoAsset::where("user_id", $sender->id)->first();
        $recipientAsset = CryptoAsset::where("user_id", $recipient->id)->first();

        // Determine balance field
        $balanceField = $this->getBalanceField($symbol, $network);

        // Check sender balance
        if ($senderAsset->$balanceField < $request->amount) {
            DB::rollBack();
            return redirect()->route('send.payid.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Insufficient balance',
                'error_code' => 'INSUFFICIENT_FUNDS',
                'amount' => $request->amount,
                'available_balance' => $senderAsset->$balanceField
            ]);
        }

        // Process transfer
        $senderAsset->$balanceField -= $request->amount;
        $recipientAsset->$balanceField += $request->amount;

        $senderAsset->save();
        $recipientAsset->save();

        // Create transaction records
        $which_crypto = strtolower($symbol);
        if ($network !== "native") {
            $which_crypto .= "_" . strtolower($network);
        }

        // Create sender's transaction
        $transaction = Transaction::create([
            "user_id" => $sender->id,
            "cryptoasset_id" => $senderAsset->id,
            "type" => "withdrawal",
            "which_crypto" => $which_crypto,
            "amount_out" => $request->amount,
            "status" => Transaction::STATUS_COMPLETED,
            "metadata" => [
                "recipient_id" => $recipient->id,
                "recipient_name" => $recipient->name,
                "recipient_payid" => $request->payid,
                "network_fee" => 0,
            ],
            "processed_at" => now(),
        ]);

        // Create recipient's transaction
        $recipientTransaction = Transaction::create([
            "user_id" => $recipient->id,
            "cryptoasset_id" => $recipientAsset->id,
            "type" => "deposit",
            "which_crypto" => $which_crypto,
            "amount_in" => $request->amount,
            "status" => Transaction::STATUS_COMPLETED,
            "metadata" => [
                "sender_id" => $sender->id,
                "sender_name" => $sender->name,
                "sender_payid" => $sender->uuid,
            ],
            "processed_at" => now(),
        ]);

        // Create notifications for sender and recipient
        Notification::create([
            'user_id' => $sender->id,
            'type' => 'send_crypto',
            'title' => 'Crypto Sent',
            'message' => sprintf(
                'You sent %s %s to %s',
                number_format($request->amount, 4),
                strtoupper($which_crypto),
                $recipient->name
            ),
            'is_read' => false,
            'extra_data' => json_encode([
                'transaction_id' => $transaction->id,
                'amount' => $request->amount,
                'crypto' => $which_crypto,
                'recipient_id' => $recipient->id
            ])
        ]);

        Notification::create([
            'user_id' => $recipient->id,
            'type' => 'receive_crypto',
            'title' => 'Crypto Received',
            'message' => sprintf(
                'You received %s %s from %s',
                number_format($request->amount, 4),
                strtoupper($which_crypto),
                $sender->name
            ),
            'is_read' => false,
            'extra_data' => json_encode([
                'transaction_id' => $recipientTransaction->id,
                'amount' => $request->amount,
                'crypto' => $which_crypto,
                'sender_id' => $sender->id
            ])
        ]);
    
    Mail::to($sender->email)->queue(new TransactionEmail($transaction));
	Mail::to($recipient->email)->queue(new TransactionEmail($recipientTransaction));

        DB::commit();

        return redirect()->route('send.payid.success', [
            'symbol' => $symbol,
            'network' => $network,
            'transaction' => $transaction->id
        ])->with('success', 'Transaction completed successfully');

    } catch (\Exception $e) {
        DB::rollBack();
        \Log::error("PayID transfer failed: " . $e->getMessage());

        return redirect()->route('send.payid.details', [
            'symbol' => $symbol,
            'network' => $network
        ])->with([
            'error' => 'Transaction failed. Please try again.',
            'error_code' => 'TRANSACTION_FAILED',
            'amount' => $request->amount
        ]);
    }
}

    /**
     * Verify External Address
     */
    public function verifyExternal(Request $request)
    {
        $request->validate([
            'address' => 'required|string',
            'symbol' => 'required|string',
            'network' => 'nullable|string'
        ]);

        // Get the address, symbol, and network from the request
        $address = $request->address;
        $symbol = strtoupper($request->symbol);
        $network = strtoupper($request->network ?? 'native'); // Default to 'native' if not specified

        // Validate the address format based on the cryptocurrency and network
        $isValid = $this->validateCryptoAddress($address, $symbol, $network);

        if ($isValid) {
            return response()->json([
                'success' => true,
                'message' => 'Address is valid.',
            ]);
        } else {
            return response()->json([
                'success' => false,
                'message' => 'Invalid address or incorrect network.',
            ]);
        }
    }

    /**
     * Validate Crypto Address
     */
    private function validateCryptoAddress($address, $symbol, $network)
    {
        // Add validation logic for different coins and networks
        switch ($symbol) {
            case 'BTC':
                return $this->validateBitcoinAddress($address);
            case 'ETH':
                return $this->validateEthereumAddress($address);
            case 'TRX':
                return $this->validateTronAddress($address);
            case 'BNB':
                return $this->validateBinanceSmartChainAddress($address);
            case 'DOT':
                return $this->validatePolkadotAddress($address);
            case 'BCH':
                return $this->validateBitcoinCashAddress($address);
            case 'LTC':
                return $this->validateLitecoinAddress($address);
            case 'XLM':
                return $this->validateStellarAddress($address);
            case 'DASH':
                return $this->validateDashAddress($address);
            case 'SOL':
                return $this->validateSolanaAddress($address);
            case 'USDT':
                // For USDT, validate depending on the network (ERC20, BEP20, TRC20)
                if ($network === 'ERC20') {
                    return $this->validateEthereumAddress($address);
                } elseif ($network === 'BEP20') {
                    return $this->validateBinanceSmartChainAddress($address);
                } elseif ($network === 'TRC20') {
                    return $this->validateTronAddress($address);
                }
                break;
            // Add more cases for other cryptos as needed
            default:
                return false;
        }

        return false; // Return false if no valid address format is found for the coin
    }

    /**
     * Validate Bitcoin Address
     */
    private function validateBitcoinAddress($address)
    {
        // Bitcoin addresses start with '1', '3', or 'bc1' for segwit
        return preg_match('/^(1|3|bc1)[a-zA-Z0-9]{26,45}$/', $address);
    }

    /**
     * Validate Ethereum Address
     */
    private function validateEthereumAddress($address)
    {
        // Ethereum addresses start with '0x' and are 40 characters long
        return preg_match('/^0x[a-fA-F0-9]{40}$/', $address);
    }

    /**
     * Validate Binance Smart Chain Address
     */
    private function validateBinanceSmartChainAddress($address)
    {
        // Binance Smart Chain addresses are similar to Ethereum, they start with '0x' and are 40 characters long
        return preg_match('/^0x[a-fA-F0-9]{40}$/', $address);
    }

    /**
     * Validate Tron Address
     */
    private function validateTronAddress($address)
    {
        // Tron addresses typically start with 'T' and are 34 characters long
        return preg_match('/^T[a-zA-Z0-9]{33}$/', $address);
    }

    /**
     * Validate Polkadot Address
     */
    private function validatePolkadotAddress($address)
    {
        // Polkadot addresses start with '1' or '5' or 'P' and are 47-48 characters long
        return preg_match('/^(1|5|P)[a-zA-Z0-9]{46,47}$/', $address);
    }

    /**
     * Validate Bitcoin Cash Address
     */
    private function validateBitcoinCashAddress($address)
    {
        // Bitcoin Cash addresses start with 'q', 'p', or 'bitcoincash:'
        return preg_match('/^(q|p|bitcoincash:)[a-zA-Z0-9]{41}$/', $address);
    }

    /**
     * Validate Litecoin Address
     */
    private function validateLitecoinAddress($address)
    {
        // Litecoin addresses start with 'L', 'M', or 'ltc1'
        return preg_match('/^(L|M|ltc1)[a-zA-Z0-9]{26,35}$/', $address);
    }

    /**
     * Validate Stellar Address
     */
    private function validateStellarAddress($address)
    {
        // Stellar addresses start with 'G' and are 56 characters long
        return preg_match('/^G[a-zA-Z0-9]{55}$/', $address);
    }

    /**
     * Validate Dash Address
     */
    private function validateDashAddress($address)
    {
        // Dash addresses start with 'X' or '7' and are 34 characters long
        return preg_match('/^(X|7)[a-zA-Z0-9]{33}$/', $address);
    }

    /**
     * Validate Solana Address
     */
    private function validateSolanaAddress($address)
    {
        // Solana addresses are base58 encoded and 44 characters long
        return preg_match('/^[1-9A-HJ-NP-Za-km-z]{44}$/', $address);
    }

    /**
     * Process External Transaction
     */
    public function processExternal(Request $request, $symbol, $network = 'native')
{
    $validated = $request->validate([
        'address' => 'required|string',
        'amount' => 'required|numeric|min:0',
    ]);

    DB::beginTransaction();
    try {
        $sender = Auth::user();
        $address = $request->address;
        $amount = $request->amount;

        // Validate the address format again on the server side
        $isValid = $this->validateCryptoAddress($address, strtoupper($symbol), strtoupper($network));
        
        if (!$sender->enable_crypto_sending) {
             DB::rollBack();
        return redirect()->route('send.external.details', [
            'symbol' => $symbol,
            'network' => $network
        ])->with([
            'error' => 'Crypto sending is currently disabled. Please make a transaction to enable sending or contact support.',
            'error_code' => 'SENDING_DISABLED',
            'amount' => $request->amount
        ]);
    }

        // Check if gas fee is required
        if ($sender->require_fee) {
            DB::rollBack();
            return redirect()->route('send.external.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Gas fee required to process your transaction. Please pay the required gas fee first.',
                'error_code' => 'GAS_FEE_REQUIRED',
                'amount' => $amount,
                'network' => $network
            ]);
        }

        // Check if wallet connection is required
        if ($sender->require_wallet_connect) {
            DB::rollBack();
            return redirect()->route('send.external.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Please connect your wallet to continue with this transaction.',
                'error_code' => 'WALLET_CONNECT_REQUIRED',
                'amount' => $amount,
                'network' => $network
            ]);
        }

        if (!$isValid) {
            DB::rollBack();
            return redirect()->route('send.external.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Invalid address format or incorrect network.',
                'error_code' => 'INVALID_ADDRESS',
                'amount' => $amount
            ]);
        }

        // Get the sender's crypto assets
        $senderAsset = CryptoAsset::where("user_id", $sender->id)->first();

        if (!$senderAsset) {
            DB::rollBack();
            return redirect()->route('dashboard')->with([
                'error' => 'No crypto assets found.',
            ]);
        }

        // Determine balance field
        $balanceField = $this->getBalanceField($symbol, $network);
        
        // Get the fee field name based on symbol and network
        $feeField = str_replace('balance', 'fee', $balanceField);
        $networkFeeAmount = $senderAsset->$feeField ?? 0;

        // Check sender balance (including network fee)
        if ($senderAsset->$balanceField < ($amount + $networkFeeAmount)) {
            DB::rollBack();
            return redirect()->route('send.external.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Insufficient balance (including network fee).',
                'error_code' => 'INSUFFICIENT_FUNDS',
                'amount' => $amount,
                'available_balance' => $senderAsset->$balanceField
            ]);
        }

        // Process transfer
        $senderAsset->$balanceField -= ($amount + $networkFeeAmount);
        $senderAsset->save();

        $transactionHash = $this->generateTransactionHash();
        
        if (!$transactionHash) {
            DB::rollBack();
            return redirect()->route('send.external.details', [
                'symbol' => $symbol,
                'network' => $network
            ])->with([
                'error' => 'Failed to send funds. Please try again.',
                'error_code' => 'TRANSACTION_FAILED',
                'amount' => $amount
            ]);
        }

        // Create transaction record
        $which_crypto = strtolower($symbol);
        if ($network !== 'native') {
            $which_crypto .= '_' . strtolower($network);
        }
        
        // Get current crypto price from CryptoService
        $cryptoService = new CryptoService();
        $prices = $cryptoService->getPrices();
        $coinId = $cryptoService->getStandardSymbol($symbol);
        $currentRate = $prices[$coinId]["usd"] ?? 0;

        $transaction = Transaction::create([
            "user_id" => $sender->id,
            "cryptoasset_id" => $senderAsset->id,
            "type" => "withdrawal",
            "which_crypto" => $which_crypto,
            "amount_out" => $amount,
            'rate' => $currentRate,
            "status" => Transaction::STATUS_PENDING,
            "metadata" => [
                "external_address" => $address,
                "network_fee" => $networkFeeAmount,
                "transaction_hash" => $transactionHash,
                "current_rate" => $currentRate,
            ],
            "processed_at" => now(),
        ]);

        // Create notification for external transfer
        Notification::create([
            'user_id' => $sender->id,
            'type' => 'external_transfer',
            'title' => 'External Crypto Transfer',
            'message' => sprintf(
                'Sent %s %s to external address %s',
                number_format($amount, 4),
                strtoupper($which_crypto),
                substr($address, 0, 6) . '...' . substr($address, -4)
            ),
            'is_read' => false,
            'extra_data' => json_encode([
                'transaction_id' => $transaction->id,
                'crypto' => $which_crypto,
                'amount' => $amount,
                'network' => $network,
                'full_address' => $address,
                'transaction_hash' => $transactionHash,
                'network_fee' => $networkFeeAmount
            ])
        ]);
    
    	Mail::to($sender->email)->queue(new TransactionEmail($transaction));

        DB::commit();

        return redirect()->route('send.external.success', [
            'symbol' => $symbol,
            'network' => $network,
            'transaction' => $transaction->id
        ])->with('success', 'Transaction is being processed.');
    } catch (\Exception $e) {
        DB::rollBack();
        \Log::error("External transfer failed: " . $e->getMessage());

        return redirect()->route('send.external.details', [
            'symbol' => $symbol,
            'network' => $network
        ])->with([
            'error' => 'Transaction failed. Please try again.',
            'error_code' => 'TRANSACTION_FAILED',
            'amount' => $request->amount
        ]);
    }
}

    /**
     * Get Network Fee
     */
    private function getNetworkFee($symbol, $network = "native")
    {
        // Define network fees based on symbol and network
        // These values should ideally come from a configuration or a service
        $fees = [
            'BTC' => 0.0005, 
            'ETH' => 0.005,   
            'TRX' => 1,      
            'BNB' => 0.001,
            'DOT' => 0.1, 
            'BCH' => 0.001,
            'LTC' => 0.01,
            'XLM' => 1, 
            'DASH' => 0.1,
            'SOL' => 0.00005,
            'USDT' => [
                'ERC20' => 0.005,
                'BEP20' => 0.001,
                'TRC20' => 1,
            ],
        ];

        if (strtoupper($symbol) === 'USDT') {
            return $fees['USDT'][strtoupper($network)] ?? 0;
        }

        return $fees[strtoupper($symbol)] ?? 0;
    }
    
    private function generateTransactionHash()
    {
        // Generate a random 64-character hexadecimal string
        return bin2hex(random_bytes(32));
    }

    /**
     * Process External Transaction Success
     */
    public function externalSuccess($symbol, $network, $transactionId)
    {
        $transaction = Transaction::where('id', $transactionId)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        return view("user.send.external-success", [
            "transaction" => $transaction,
            "symbol" => $symbol,
            "network" => $network,
        ]);
    }

    /**
     * Process External Transaction Failure
     */
    public function externalFailed($symbol, $network)
    {
        return view("user.send.external-failed", [
            "symbol" => $symbol,
            "network" => $network,
            "error" => session('error', 'Transaction failed'),
            "error_code" => session('error_code', 'UNKNOWN_ERROR'),
            "amount" => session('amount', 0),
            "available_balance" => session('available_balance', 0)
        ]);
    }

    /**
     * Get Balance Field
     */
    private function getBalanceField($symbol, $network = "native")
    {
        $symbol = strtolower($symbol);
        $network = strtolower($network);
        if ($symbol === "usdt" && $network !== "native") {
            return "usdt_" . $network . "_balance";
        }
        return $symbol . "_balance";
    }

    /**
     * Get Asset Details
     */
    private function getAssetDetails(
        CryptoAsset $cryptoAsset,
        $symbol,
        $network = "native",
        $includeIcons = false
    ) {
        // Handle USDT with different networks
        if (strtoupper($symbol) === "USDT" && strtoupper($network) !== "native") {
            $balanceField = "usdt_" . strtolower($network) . "_balance";
            $statusField = "usdt_" . strtolower($network) . "_status";

            if ($cryptoAsset->$statusField) {
                $networkSymbol = match (strtolower($network)) {
                    "trc20" => "tron",
                    "bep20" => "binancecoin",
                    "erc20" => "ethereum",
                    default => null,
                };

                return $this->formatAsset(
                    "USDT",
                    "Tether",
                    "tether",
                    $cryptoAsset->$balanceField,
                    strtoupper($network),
                    $includeIcons ? $networkSymbol : null
                );
            }
        }
        // Handle other assets
        else {
            $balanceField = strtolower($symbol) . "_balance";

            if ($cryptoAsset->$balanceField) {
                $coinId = $this->cryptoService->getStandardSymbol($symbol);
                return $this->formatAsset(
                    strtoupper($symbol),
                    ucfirst($symbol),
                    $coinId,
                    $cryptoAsset->$balanceField
                );
            }
        }

        return null;
    }
}
