<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\CoinExService;
use App\UserWallet;
use App\Order;
use App\Trade;
use App\TradingPair;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TradingController extends Controller
{
    protected $coinex;

    public function __construct()
    {
        $this->middleware('auth');
        $this->coinex = new CoinExService();
    }

    /**
     * Show trading page
     */
    public function index($market = 'BTCUSDT')
    {
        $tradingPair = TradingPair::where('market', $market)->first();
        
        if (!$tradingPair || !$tradingPair->is_active) {
            return redirect()->route('trading', ['market' => 'BTCUSDT'])
                ->with('error', 'بازار مورد نظر یافت نشد');
        }

        // Get user wallets
        $user = Auth::user();
        list($baseCurrency, $quoteCurrency) = explode('USDT', $market);
        $baseCurrency = $baseCurrency ?: 'BTC';
        
        $baseWallet = UserWallet::firstOrCreate([
            'user_id' => $user->id,
            'currency' => $baseCurrency
        ]);
        
        $quoteWallet = UserWallet::firstOrCreate([
            'user_id' => $user->id,
            'currency' => 'USDT'
        ]);

        // Get order book
        $orderBook = $this->coinex->getOrderBook($market, 20);
        
        // Get ticker
        $ticker = $this->coinex->getTicker($market);
        
        // Get user's pending orders
        $pendingOrders = Order::where('user_id', $user->id)
            ->where('market', $market)
            ->whereIn('status', ['pending', 'partial'])
            ->orderBy('created_at', 'desc')
            ->get();

        return view('user.trading.index', compact(
            'market',
            'tradingPair',
            'baseWallet',
            'quoteWallet',
            'orderBook',
            'ticker',
            'pendingOrders'
        ));
    }

    /**
     * Place a limit order
     */
    public function placeLimitOrder(Request $request)
    {
        $request->validate([
            'market' => 'required|string',
            'side' => 'required|in:buy,sell',
            'price' => 'required|numeric|min:0',
            'amount' => 'required|numeric|min:0',
        ]);

        $user = Auth::user();
        $market = $request->market;
        $side = $request->side;
        $price = $request->price;
        $amount = $request->amount;

        try {
            DB::beginTransaction();

            // Get trading pair
            $tradingPair = TradingPair::where('market', $market)->first();
            if (!$tradingPair || !$tradingPair->is_active) {
                throw new \Exception('بازار غیرفعال است');
            }

            // Calculate total
            $total = $price * $amount;

            // Check minimum amounts
            if ($amount < $tradingPair->min_amount) {
                throw new \Exception('مقدار کمتر از حداقل مجاز است');
            }
            if ($total < $tradingPair->min_total) {
                throw new \Exception('مجموع کمتر از حداقل مجاز است');
            }

            // Get currencies
            list($baseCurrency, $quoteCurrency) = $this->parseCurrencies($market);

            // Lock balance
            if ($side === 'buy') {
                // Lock USDT
                $wallet = UserWallet::firstOrCreate([
                    'user_id' => $user->id,
                    'currency' => $quoteCurrency
                ]);
                $wallet->lockAmount($total);
            } else {
                // Lock base currency
                $wallet = UserWallet::firstOrCreate([
                    'user_id' => $user->id,
                    'currency' => $baseCurrency
                ]);
                $wallet->lockAmount($amount);
            }

            // Place order on CoinEx
            $coinexOrder = $this->coinex->placeLimitOrder($market, $side, $amount, $price);

            if (!$coinexOrder || !isset($coinexOrder['order_id'])) {
                throw new \Exception('خطا در ثبت سفارش در صرافی');
            }

            // Save order to database
            $order = Order::create([
                'user_id' => $user->id,
                'market' => $market,
                'type' => 'limit',
                'side' => $side,
                'price' => $price,
                'amount' => $amount,
                'total' => $total,
                'status' => 'pending',
                'coinex_order_id' => $coinexOrder['order_id'],
            ]);

            DB::commit();

            return response()->json([
                'status' => true,
                'message' => 'سفارش با موفقیت ثبت شد',
                'order' => $order
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Place limit order error: ' . $e->getMessage());
            
            return response()->json([
                'status' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Place a market order
     */
    public function placeMarketOrder(Request $request)
    {
        $request->validate([
            'market' => 'required|string',
            'side' => 'required|in:buy,sell',
            'amount' => 'required|numeric|min:0',
        ]);

        $user = Auth::user();
        $market = $request->market;
        $side = $request->side;
        $amount = $request->amount;

        try {
            DB::beginTransaction();

            // Get trading pair
            $tradingPair = TradingPair::where('market', $market)->first();
            if (!$tradingPair || !$tradingPair->is_active) {
                throw new \Exception('بازار غیرفعال است');
            }

            // Get current price
            $ticker = $this->coinex->getTicker($market);
            if (!$ticker || !isset($ticker['last'])) {
                throw new \Exception('خطا در دریافت قیمت');
            }
            $currentPrice = $ticker['last'];

            // Get currencies
            list($baseCurrency, $quoteCurrency) = $this->parseCurrencies($market);

            // Lock balance
            if ($side === 'buy') {
                $total = $currentPrice * $amount * 1.01; // 1% buffer
                $wallet = UserWallet::firstOrCreate([
                    'user_id' => $user->id,
                    'currency' => $quoteCurrency
                ]);
                $wallet->lockAmount($total);
            } else {
                $wallet = UserWallet::firstOrCreate([
                    'user_id' => $user->id,
                    'currency' => $baseCurrency
                ]);
                $wallet->lockAmount($amount);
            }

            // Place order on CoinEx
            $coinexOrder = $this->coinex->placeMarketOrder($market, $side, $amount);

            if (!$coinexOrder || !isset($coinexOrder['order_id'])) {
                throw new \Exception('خطا در ثبت سفارش در صرافی');
            }

            // Save order to database
            $order = Order::create([
                'user_id' => $user->id,
                'market' => $market,
                'type' => 'market',
                'side' => $side,
                'price' => null,
                'amount' => $amount,
                'total' => null,
                'status' => 'pending',
                'coinex_order_id' => $coinexOrder['order_id'],
            ]);

            DB::commit();

            return response()->json([
                'status' => true,
                'message' => 'سفارش با موفقیت ثبت شد',
                'order' => $order
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Place market order error: ' . $e->getMessage());
            
            return response()->json([
                'status' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Cancel an order
     */
    public function cancelOrder(Request $request)
    {
        $request->validate([
            'order_id' => 'required|integer',
        ]);

        $user = Auth::user();
        $order = Order::where('id', $request->order_id)
            ->where('user_id', $user->id)
            ->first();

        if (!$order) {
            return response()->json([
                'status' => false,
                'message' => 'سفارش یافت نشد'
            ], 404);
        }

        if (!$order->isPending()) {
            return response()->json([
                'status' => false,
                'message' => 'فقط سفارشات در حال انتظار قابل لغو هستند'
            ], 400);
        }

        try {
            DB::beginTransaction();

            // Cancel on CoinEx
            $this->coinex->cancelOrder($order->market, $order->coinex_order_id);

            // Unlock balance
            list($baseCurrency, $quoteCurrency) = $this->parseCurrencies($order->market);
            
            if ($order->side === 'buy') {
                $wallet = UserWallet::where('user_id', $user->id)
                    ->where('currency', $quoteCurrency)
                    ->first();
                if ($wallet) {
                    $wallet->unlockAmount($order->total - ($order->filled_amount * $order->price));
                }
            } else {
                $wallet = UserWallet::where('user_id', $user->id)
                    ->where('currency', $baseCurrency)
                    ->first();
                if ($wallet) {
                    $wallet->unlockAmount($order->amount - $order->filled_amount);
                }
            }

            // Update order status
            $order->cancel();

            DB::commit();

            return response()->json([
                'status' => true,
                'message' => 'سفارش لغو شد'
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Cancel order error: ' . $e->getMessage());
            
            return response()->json([
                'status' => false,
                'message' => 'خطا در لغو سفارش: ' . $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get order book
     */
    public function getOrderBook($market)
    {
        try {
            $orderBook = $this->coinex->getOrderBook($market, 20);
            
            return response()->json([
                'status' => true,
                'data' => $orderBook
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get user's orders
     */
    public function getMyOrders(Request $request)
    {
        $user = Auth::user();
        $market = $request->market;

        $query = Order::where('user_id', $user->id);
        
        if ($market) {
            $query->where('market', $market);
        }

        $orders = $query->orderBy('created_at', 'desc')
            ->limit(50)
            ->get();

        return response()->json([
            'status' => true,
            'data' => $orders
        ]);
    }

    /**
     * Get user's trade history
     */
    public function getMyTrades(Request $request)
    {
        $user = Auth::user();
        $market = $request->market;

        $query = Trade::where('user_id', $user->id);
        
        if ($market) {
            $query->where('market', $market);
        }

        $trades = $query->orderBy('created_at', 'desc')
            ->limit(50)
            ->get();

        return response()->json([
            'status' => true,
            'data' => $trades
        ]);
    }

    /**
     * Parse market to get base and quote currencies
     */
    protected function parseCurrencies($market)
    {
        // Assuming format like BTCUSDT
        $parts = explode('USDT', $market);
        $baseCurrency = $parts[0] ?: 'BTC';
        $quoteCurrency = 'USDT';
        
        return [$baseCurrency, $quoteCurrency];
    }
}
