<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Services\BinanceService;
use Illuminate\Http\JsonResponse;
use Illuminate\View\View;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class DashboardController extends Controller
{
    protected $binanceService;

    public function __construct(BinanceService $binanceService)
    {
        $this->binanceService = $binanceService;
    }

    public function index(): View
    {
        // Safe database queries with fallbacks for missing tables
        $stats = [
            'total_users' => $this->safeCount('users'),
            'total_deposits' => $this->calculateTotalDepositsUSD(),
            'total_withdrawals' => $this->calculateTotalWithdrawalsUSD(),
            'active_bots' => $this->safeCount('ai_trade_bots', ['status' => 'active']),
            'open_orders' => $this->safeCount('orders', function($query) {
                return $query->whereIn('status', ['pending', 'processing']);
            }),
            'risk_alerts' => $this->safeCount('risk_alerts', ['status' => 'pending']),
        ];

        return view('admin.dashboard', [
            'stats' => $stats,
            'pageTitle' => __('admin.nav.dashboard'),
            'title' => __('admin.nav.dashboard'),
        ]);
    }

    /**
     * JSON for admin panel sound notifications (polled by layout script).
     * Returns last ids and wallet count so frontend can detect new deposit/withdraw/bot/wallet-connect.
     */
    public function notificationCounts(): JsonResponse
    {
        $data = [
            'last_deposit_id' => 0,
            'last_withdrawal_id' => 0,
            'last_bot_id' => 0,
            'wallet_connected_count' => 0,
            'last_support_message_id' => 0,
        ];
        try {
            if (Schema::hasTable('deposits')) {
                $data['last_deposit_id'] = (int) DB::table('deposits')->max('id');
            }
            if (Schema::hasTable('withdrawals')) {
                $data['last_withdrawal_id'] = (int) DB::table('withdrawals')->max('id');
            }
            if (Schema::hasTable('ai_trade_bots')) {
                $data['last_bot_id'] = (int) DB::table('ai_trade_bots')->max('id');
            }
            if (Schema::hasTable('users')) {
                $data['wallet_connected_count'] = (int) DB::table('users')
                    ->whereNotNull('wallet_address')
                    ->where('wallet_address', '!=', '')
                    ->count();
            }
            if (Schema::hasTable('support_messages')) {
                $data['last_support_message_id'] = (int) DB::table('support_messages')
                    ->where('sender_type', 'user')
                    ->max('id');
            }
        } catch (\Exception $e) {
            // ignore
        }
        return response()->json($data);
    }

    /**
     * Calculate total deposits in USD by converting coin amounts to USD
     */
    private function calculateTotalDepositsUSD(): float
    {
        try {
            if (!Schema::hasTable('deposits')) {
                return 0.0;
            }

            $deposits = DB::table('deposits')
                ->where('status', 'confirmed')
                ->select('network', 'amount')
                ->get();

            $totalUSD = 0.0;

            foreach ($deposits as $deposit) {
                $coinName = $this->networkToCoinName($deposit->network);
                $coinPrice = $this->binanceService->getCoinPrice($coinName);
                
                if ($coinPrice) {
                    $totalUSD += (float) $deposit->amount * $coinPrice;
                } else {
                    // Fallback: if price not available, assume USDT (1:1)
                    if (str_contains(strtolower($deposit->network), 'usdt')) {
                        $totalUSD += (float) $deposit->amount;
                    }
                }
            }

            return $totalUSD;
        } catch (\Exception $e) {
            return 0.0;
        }
    }

    /**
     * Calculate total withdrawals in USD by converting coin amounts to USD
     */
    private function calculateTotalWithdrawalsUSD(): float
    {
        try {
            if (!Schema::hasTable('withdrawals')) {
                return 0.0;
            }

            $withdrawals = DB::table('withdrawals')
                ->where('status', 'completed')
                ->select('coin_name', 'amount')
                ->get();

            $totalUSD = 0.0;

            foreach ($withdrawals as $withdrawal) {
                $coinName = strtoupper($withdrawal->coin_name ?? 'USDT');
                $coinPrice = $this->binanceService->getCoinPrice($coinName);
                
                if ($coinPrice) {
                    $totalUSD += (float) $withdrawal->amount * $coinPrice;
                } else {
                    // Fallback: if price not available, assume USDT (1:1)
                    if ($coinName === 'USDT') {
                        $totalUSD += (float) $withdrawal->amount;
                    }
                }
            }

            return $totalUSD;
        } catch (\Exception $e) {
            return 0.0;
        }
    }

    /**
     * Convert network string to coin name
     */
    private function networkToCoinName(string $network): string
    {
        $network = strtolower($network);
        
        if (str_contains($network, 'usdt')) {
            return 'USDT';
        } elseif (str_contains($network, 'btc')) {
            return 'BTC';
        } elseif (str_contains($network, 'eth') || str_contains($network, 'ethereum')) {
            return 'ETH';
        }
        
        return 'USDT'; // Default
    }

    /**
     * Safely count records from a table, returns 0 if table doesn't exist
     */
    private function safeCount(string $table, $conditions = null): int
    {
        try {
            if (!Schema::hasTable($table)) {
                return 0;
            }

            $query = DB::table($table);
            
            if (is_array($conditions)) {
                foreach ($conditions as $column => $value) {
                    $query->where($column, $value);
                }
            } elseif (is_callable($conditions)) {
                $conditions($query);
            }

            return $query->count();
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * Safely sum a column from a table, returns 0 if table doesn't exist
     */
    private function safeSum(string $table, string $column, array $conditions = []): float
    {
        try {
            if (!Schema::hasTable($table)) {
                return 0;
            }

            $query = DB::table($table);
            
            foreach ($conditions as $col => $value) {
                $query->where($col, $value);
            }

            $result = $query->sum($column);
            return $result ? (float) $result : 0.0;
        } catch (\Exception $e) {
            return 0.0;
        }
    }
}

