<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\UserBalance;
use App\Models\AuditLog;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Hash;
use App\Services\BinanceService;

class UserManagementController extends Controller
{
    /** Fallback USD prices when Binance is unreachable (match frontend/API logic) */
    private static function fallbackPrice(string $coin): float
    {
        $map = [
            'USDT' => 1.0, 'BTC' => 95000.0, 'ETH' => 3500.0, 'BNB' => 600.0,
            'SOL' => 220.0, 'XRP' => 2.0, 'ADA' => 0.9, 'DOGE' => 0.4,
            'DOT' => 7.0, 'LTC' => 100.0, 'AVAX' => 35.0, 'TRX' => 0.25,
            'LINK' => 18.0, 'BCH' => 450.0, 'XLM' => 0.4, 'UNI' => 10.0, 'ATOM' => 8.0,
        ];
        return $map[strtoupper($coin)] ?? 0.0;
    }

    public function __construct(
        private BinanceService $binanceService
    ) {}

    public function index(Request $request): View
    {
        $query = User::query();

        // Search
        if ($request->has('search')) {
            $search = $request->get('search');
            $query->where(function($q) use ($search) {
                $q->where('wallet_address', 'like', "%{$search}%")
                  ->orWhere('name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }

        // Filter by status
        if ($request->has('status')) {
            $query->where('is_active', $request->get('status') === 'active');
        }

        // Per page - default 10, allow 10, 20, 50, 100
        $perPage = $request->get('per_page', 10);
        if (!in_array($perPage, [10, 20, 50, 100])) {
            $perPage = 10;
        }

        $users = $query->with('userBalances')->latest()->paginate($perPage)->withQueryString();

        // Compute Total Portfolio (USD) per user so admin matches frontend Assets display
        $totalPortfolioByUser = [];
        $coins = [];
        foreach ($users as $user) {
            foreach ($user->userBalances as $ub) {
                $c = strtoupper($ub->coin_name);
                if (!isset($coins[$c])) {
                    $coins[$c] = true;
                }
            }
        }
        $prices = [];
        foreach (array_keys($coins) as $coin) {
            if ($coin === 'USDT') {
                $prices[$coin] = 1.0;
                continue;
            }
            $price = $this->binanceService->getCoinPrice($coin);
            $prices[$coin] = $price !== null ? (float) $price : self::fallbackPrice($coin);
        }
        foreach ($users as $user) {
            $total = 0.0;
            foreach ($user->userBalances as $ub) {
                $price = $prices[strtoupper($ub->coin_name)] ?? 0.0;
                $total += (float) $ub->balance * $price;
            }
            $totalPortfolioByUser[$user->id] = $total;
        }

        return view('admin.users.index', [
            'users' => $users,
            'totalPortfolioByUser' => $totalPortfolioByUser,
            'pageTitle' => __('admin.nav.users'),
            'title' => __('admin.users.title')
        ]);
    }

    public function show($id): View
    {
        $user = User::with(['deposits', 'withdrawals', 'aiTradeBots', 'orders', 'referrals'])
            ->findOrFail($id);

        return view('admin.users.show', [
            'user' => $user,
            'pageTitle' => __('admin.users.user_details'),
            'title' => __('admin.users.user_id') . ' #' . $user->id
        ]);
    }

    public function update(Request $request, $id): RedirectResponse
    {
        $user = User::findOrFail($id);

        $validated = $request->validate([
            'name' => 'sometimes|string|max:255',
            'is_active' => 'sometimes|boolean',
            'account_weight_score' => 'sometimes|numeric|min:0|max:100',
            'authorization_quota' => 'sometimes|numeric|min:0',
        ]);

        $user->update($validated);

        // Log audit
        \App\Models\AuditLog::create([
            'admin_user_id' => session('admin.user_id'),
            'action' => 'user_update',
            'model_type' => User::class,
            'model_id' => $user->id,
            'changes' => json_encode($validated),
            'reason' => $request->input('reason', 'User management update'),
        ]);

        return redirect()->route('admin.users.show', $id)
            ->with('success', 'User updated successfully');
    }

    public function verify(Request $request, $id): RedirectResponse
    {
        $user = User::findOrFail($id);
        $user->update(['is_verified' => true]);

        \App\Models\AuditLog::create([
            'admin_user_id' => session('admin.user_id'),
            'action' => 'user_verify',
            'model_type' => User::class,
            'model_id' => $user->id,
            'changes' => json_encode(['is_verified' => true]),
            'reason' => 'KYC verification by admin',
        ]);

        return redirect()->back()->with('success', 'User verified successfully');
    }

    public function resetPin($id): RedirectResponse
    {
        $user = User::findOrFail($id);
        $user->update(['withdrawal_pin_hash' => null]);

        AuditLog::create([
            'admin_user_id' => session('admin.user_id'),
            'action' => 'user_reset_pin',
            'model_type' => User::class,
            'model_id' => $user->id,
            'changes' => json_encode(['withdrawal_pin_hash' => 'cleared']),
            'reason' => 'Admin reset withdrawal PIN',
        ]);

        return redirect()->back()->with('success', 'User withdrawal PIN has been cleared. They can set a new PIN in Settings.');
    }

    public function setPin(Request $request, $id): RedirectResponse
    {
        $validated = $request->validate([
            'pin' => 'required|string|size:6|regex:/^[0-9]+$/',
            'pin_confirmation' => 'required|same:pin',
        ], [
            'pin.required' => 'PIN is required.',
            'pin.size' => 'PIN must be exactly 6 digits.',
            'pin.regex' => 'PIN must be 6 digits only.',
            'pin_confirmation.same' => 'PIN confirmation does not match.',
        ]);

        $user = User::findOrFail($id);
        $user->update(['withdrawal_pin_hash' => Hash::make($validated['pin'])]);

        AuditLog::create([
            'admin_user_id' => session('admin.user_id'),
            'action' => 'user_set_pin',
            'model_type' => User::class,
            'model_id' => $user->id,
            'changes' => json_encode(['withdrawal_pin' => 'set by admin']),
            'reason' => 'Admin set withdrawal PIN for user',
        ]);

        return redirect()->back()->with('success', 'Withdrawal PIN has been set for this user.');
    }

    public function destroy($id): RedirectResponse
    {
        $user = User::findOrFail($id);
        $userName = $user->name;
        $user->delete();

        AuditLog::create([
            'admin_user_id' => session('admin.user_id'),
            'action' => 'user_delete',
            'model_type' => User::class,
            'model_id' => (int) $id,
            'changes' => json_encode(['deleted' => $userName]),
            'reason' => 'Admin deleted user',
        ]);

        return redirect()->route('admin.users')->with('success', __('admin.users.user_deleted'));
    }
}
