<?php

namespace App\Http\Controllers\Dashboard\User;

use App\Enum\TransactionDirection;
use App\Enum\TransactionMethod;
use App\Models\User;
use App\Models\Wallet;
use App\Enum\WalletStatus;
use App\Models\Transaction;
use Illuminate\Http\Request;
use App\Enum\TransactionType;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class WithdrawController extends Controller
{
    public function __construct()
    {
        $this->middleware(['registeredUser', 'kycVerification']);
    }

    public function index()
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Withdraws', 'active' => true]
        ];

        $transactions = Transaction::where('user_id', $user->id)->where('type', TransactionType::WITHDRAW)->latest()->get();

        $data = [
            'title' => 'Withdraws',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
            'transactions' => $transactions
        ];

        return view('dashboard.user.withdraw.index', $data);
    }

    public function method()
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Withdraws', 'url' => route('user.withdraw.index')],
            ['label' => 'Withdraw Methods', 'active' => true]
        ];

        $data = [
            'title' => 'Withdraw Methods',
            'breadcrumbs' => $breadcrumbs,
            'user' => $user,
        ];

        return view('dashboard.user.withdraw.method', $data);
    }
    public function cryptoMethod()
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Withdraws', 'url' => route('user.withdraw.index')],
            ['label' => 'Withdraw Method', 'url' => route('user.withdraw.method')],
            ['label' => 'Crypto', 'active' => true],
        ];

        $wallets = Wallet::where('status', WalletStatus::ACTIVE)->latest()->get();

        $data = [
            'title' => 'Crypto',
            'breadcrumbs' => $breadcrumbs,
            'user' => $user,
            'wallets' => $wallets
        ];

        return view('dashboard.user.withdraw.method.crypto', $data);
    }

    public function cryptoMethodStore(Request $request)
    {
        $request->validate([
            'user_id'   => ['required', 'exists:users,id'],
            'wallet_id' => ['required', 'exists:wallets,id'],
            'amount'    => ['required', 'numeric', 'min:0.00000001'],
            'address'   => ['required', 'string', 'max:255'],
            'network'   => ['nullable', 'string', 'max:50'],
        ]);

        $user = User::where('id', $request->user_id)->firstOrFail();

        if ($user->balance < $request->amount) {
            return redirect()->back()->with(
                'error',
                'This withdrawal cannot be processed due to insufficient wallet balance.'
            );
        }

        $wallet = Wallet::where('id', $request->wallet_id)->firstOrFail();

        $meta['withdraw'] = [
            'receiver_wallet_address' => $request->address,
            'receiver_wallet_network' => $request->network,
            'sender_wallet_id' => $wallet->id,
            'sender_wallet_name' => $wallet->name,
            'sender_wallet_symbol' => $wallet->symbol,
            'sender_wallet_address' => $wallet->address,
            'sender_wallet_network' => $wallet->network
        ];

        try {
            DB::beginTransaction();

            Transaction::create([
                'user_id' => $user->id,
                'type' => TransactionType::WITHDRAW,
                'direction' => TransactionDirection::DEBIT,
                'description' => 'Crypto Withdraw',
                'amount' => $request->amount,
                'method' => TransactionMethod::CRYPTO,
                'transaction_at' => now(),
                'reference_id' => generateReferenceId(),
                'meta' => $meta
            ]);

            DB::commit();

            return redirect()->route('user.withdraw.index')->with('success', 'Your withdrawal request has been submitted successfully and is pending approval.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error($e->getMessage());
            return redirect()->back()->with('error', config('app.messages.error'));
        }
    }

    public function bankMethod()
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Withdraws', 'url' => route('user.withdraw.index')],
            ['label' => 'Withdraw Method', 'url' => route('user.withdraw.method')],
            ['label' => 'Bank', 'active' => true],
        ];

        $wallets = Wallet::where('status', WalletStatus::ACTIVE)->latest()->get();

        $data = [
            'title' => 'Bank',
            'breadcrumbs' => $breadcrumbs,
            'user' => $user,
            'wallets' => $wallets
        ];

        return view('dashboard.user.withdraw.method.bank', $data);
    }


    public function bankMethodStore(Request $request)
    {
        $request->validate([
            'wallet_id' => ['required', 'exists:wallets,id'],
            'amount'    => ['required', 'numeric', 'min:0.00000001'],
            'account_number' => ['required', 'numeric'],
            'bank_name' => ['required', 'string', 'max:255'],
        ]);

        $user = Auth::user();

        if ($user->balance < $request->amount) {
            return redirect()->back()->with(
                'error',
                'This withdrawal cannot be processed due to insufficient wallet balance.'
            );
        }

        $wallet = Wallet::where('id', $request->wallet_id)->firstOrFail();

        $meta['withdraw'] = [
            'receiver_account_number' => $request->account_number,
            'receiver_bank_name' => $request->bank_name,
            'sender_wallet_id' => $wallet->id,
            'sender_wallet_name' => $wallet->name,
            'sender_wallet_symbol' => $wallet->symbol,
            'sender_wallet_address' => $wallet->address,
            'sender_wallet_network' => $wallet->network
        ];

        try {
            DB::beginTransaction();

            Transaction::create([
                'user_id' => $user->id,
                'type' => TransactionType::WITHDRAW,
                'direction' => TransactionDirection::DEBIT,
                'description' => 'Bank Withdraw',
                'amount' => $request->amount,
                'method' => TransactionMethod::BANK,
                'transaction_at' => now(),
                'reference_id' => generateReferenceId(),
                'meta' => $meta
            ]);

            DB::commit();

            return redirect()->route('user.withdraw.index')->with('success', 'Your withdrawal request has been submitted successfully and is pending approval.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error($e->getMessage());
            return redirect()->back()->with('error', config('app.messages.error'));
        }
    }

    public function show(string $uuid)
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Withdraws', 'url' => route('user.withdraw.index')],
            ['label' => 'Withdraw Details', 'active' => true],
        ];

        $transaction = $user->transaction()->where('uuid', $uuid)->firstOrFail();

        $data = [
            'title' => 'Withdraw Details',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
            'transaction' => $transaction
        ];

        return view('dashboard.user.withdraw.show', $data);
    }
}
