<?php

namespace App\Http\Controllers\User;

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

class SwapController extends Controller
{
    protected $cryptoService;

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

    public function index()
    {
        $user = Auth::user();
        $cryptoAsset = CryptoAsset::where('user_id', $user->id)->first();
        $prices = $this->cryptoService->getPrices();

        // Get only active coins
        $activeCoins = collect([
            'btc', 'eth', 'usdt_trc20', 'usdt_bep20', 'usdt_erc20', 
            'trx', 'bnb', 'dot', 'bch', 'ltc', 'xlm', 'dash', 'sol'
        ])->filter(function ($coin) use ($cryptoAsset) {
            $statusField = $coin . '_status';
            return $cryptoAsset->$statusField === true;
        })->toArray();

        return view('user.swap', [
            'cryptoAsset' => $cryptoAsset,
            'prices' => $prices,
            'activeCoins' => $activeCoins
        ]);
    }

   public function swap(Request $request)
{
    $request->validate([
        'from_crypto' => 'required|string',
        'to_crypto' => 'required|string',
        'amount' => 'required|numeric|min:0',
    ]);

    try {
        $user = Auth::user();
        $cryptoAsset = CryptoAsset::where('user_id', $user->id)->first();
        $prices = $this->cryptoService->getPrices();

        // Verify both coins are active
        $fromStatus = $request->from_crypto . '_status';
        $toStatus = $request->to_crypto . '_status';
        
        if (!$cryptoAsset->$fromStatus || !$cryptoAsset->$toStatus) {
            return response()->json([
                'success' => false,
                'message' => 'One or both selected cryptocurrencies are not active'
            ]);
        }

        // Get balance fields
        $fromField = $request->from_crypto . '_balance';
        $toField = $request->to_crypto . '_balance';

        // Get crypto names for price lookup
        $fromCryptoName = $this->getCryptoNameForPrices($request->from_crypto);
        $toCryptoName = $this->getCryptoNameForPrices($request->to_crypto);

        // Get current prices
        $fromPrice = $prices[$fromCryptoName]['usd'] ?? 0;
        $toPrice = $prices[$toCryptoName]['usd'] ?? 0;

        if ($fromPrice === 0 || $toPrice === 0) {
            return response()->json([
                'success' => false,
                'message' => 'Unable to get current prices'
            ]);
        }

        // Calculate conversion
        $usdValue = $request->amount * $fromPrice;
        $toAmount = $usdValue / $toPrice;

        // Check if user has enough balance
        if ($cryptoAsset->$fromField < $request->amount) {
            return response()->json([
                'success' => false,
                'message' => 'Insufficient balance'
            ]);
        }

        // Perform swap
        $transaction = DB::transaction(function () use ($cryptoAsset, $fromField, $toField, $request, $toAmount, $fromPrice, $toPrice, $usdValue, $user) {
            // Deduct from source crypto
            $cryptoAsset->$fromField -= $request->amount;
            // Add to destination crypto
            $cryptoAsset->$toField += $toAmount;
            $cryptoAsset->save();

            // Create transaction record
            $transaction = Transaction::create([
                'user_id' => $cryptoAsset->user_id,
                'cryptoasset_id' => $cryptoAsset->id,
                'type' => Transaction::TYPE_SWAP,
                'which_crypto' => $request->from_crypto,
                'from_crypto' => $request->from_crypto,
                'to_crypto' => $request->to_crypto,
                'amount_in' => $request->amount,
                'amount_out' => $toAmount,
                'rate' => $toAmount / $request->amount,
                'status' => Transaction::STATUS_COMPLETED,
                'metadata' => [
                    'from_price_usd' => $fromPrice,
                    'to_price_usd' => $toPrice,
                    'usd_value' => $usdValue
                ],
                'processed_at' => now()
            ]);

            // Create notification for swap
            Notification::create([
                'user_id' => $user->id,
                'type' => 'crypto_swap',
                'title' => 'Crypto Swap',
                'message' => sprintf(
                    'Swapped %s %s to %s %s',
                    number_format($request->amount, 4),
                    strtoupper($request->from_crypto),
                    number_format($toAmount, 4),
                    strtoupper($request->to_crypto)
                ),
                'is_read' => false,
                'extra_data' => json_encode([
                    'transaction_id' => $transaction->id,
                    'from_crypto' => $request->from_crypto,
                    'to_crypto' => $request->to_crypto,
                    'from_amount' => $request->amount,
                    'to_amount' => $toAmount,
                    'usd_value' => $usdValue
                ])
            ]);
        
        Mail::to($user->email)->queue(new TransactionEmail($transaction));

            return $transaction;
        });

        return response()->json([
            'success' => true,
            'message' => 'Swap completed successfully',
            'data' => [
                'from_amount' => $request->amount,
                'to_amount' => $toAmount,
                'rate' => $toAmount / $request->amount,
                'from_crypto' => strtoupper($request->from_crypto),
                'to_crypto' => strtoupper($request->to_crypto)
            ]
        ]);

    } catch (\Exception $e) {
        \Log::error('Swap failed: ' . $e->getMessage());
        return response()->json([
            'success' => false,
            'message' => 'Failed to process swap. Please try again.'
        ]);
    }
}

    private function getCryptoNameForPrices($crypto)
    {
        if (str_starts_with($crypto, 'usdt_')) {
            return 'tether';
        }

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

        return $cryptoMap[$crypto] ?? $crypto;
    }
}