<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\Referral;
use App\Models\ReferralWithdrawal;
use HopekellDev\Paystack\Paystack;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Illuminate\Http\JsonResponse;

class ReferralController extends Controller
{
    public function index(Request $request): View
    {
        $user = $request->user();

        if (!$user->referral_code) {
            $user->update([
                'referral_code' => strtoupper(Str::random(8)),
            ]);
        }

        $referralLink = route('register', [
            'ref' => $user->referral_code,
        ]);

        $referrals = Referral::with('referred')
            ->where('referrer_id', $user->id)
            ->latest()
            ->paginate(15);

        $withdrawals = ReferralWithdrawal::where('user_id', $user->id)
            ->latest()
            ->limit(10)
            ->get();

        $totalEarned = Referral::where('referrer_id', $user->id)
            ->where('status', 'rewarded')
            ->sum('reward_value');

        $pendingReferrals = Referral::where('referrer_id', $user->id)
            ->where('status', 'pending')
            ->count();

        $rewardedReferrals = Referral::where('referrer_id', $user->id)
            ->where('status', 'rewarded')
            ->count();

        // ✅ Cache banks for 48 hours
        $banks = Cache::remember('paystack_banks', now()->addHours(48), function () {
            try {
                $data = Paystack::verification()->listBanks();
                return $data['data'] ?? [];
            } catch (\Throwable $e) {
                return [];
            }
        });

        return view('user.referrals.index', compact(
            'user',
            'referralLink',
            'referrals',
            'withdrawals',
            'totalEarned',
            'pendingReferrals',
            'rewardedReferrals',
            'banks'
        ));
    }

    public function withdraw(Request $request)
    {
        $validated = $request->validate([
            'amount' => ['required', 'numeric', 'min:1000'],
            'bank_name' => ['required', 'string', 'max:120'],
            'account_name' => ['required', 'string', 'max:120'],
            'account_number' => ['required', 'string', 'max:20'],
        ]);

        $user = $request->user();

        if ((float) $validated['amount'] > (float) $user->wallet_balance) {
            return response()->json([
                'status' => false,
                'message' => 'Insufficient wallet balance.',
            ], 422);
        }

        DB::transaction(function () use ($user, $validated) {
            $user->decrement('wallet_balance', $validated['amount']);

            ReferralWithdrawal::create([
                'user_id' => $user->id,
                'amount' => $validated['amount'],
                'bank_name' => $validated['bank_name'],
                'account_name' => $validated['account_name'],
                'account_number' => $validated['account_number'],
                'status' => 'pending',
            ]);
        });

        return response()->json([
            'status' => true,
            'message' => 'Withdrawal request submitted successfully.',
            'redirect' => route('user.referrals.index'),
        ]);
    }

    public function resolveAccount(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'account_number' => ['required', 'digits:10'],
            'bank_code' => ['required', 'string'],
        ]);

        try {
            $response = Paystack::verification()->resolveAccountNumber(
                $validated['account_number'],
                $validated['bank_code']
            );

            if (!($response['status'] ?? false)) {
                return response()->json([
                    'status' => false,
                    'message' => $response['message'] ?? 'Unable to resolve account.',
                ], 422);
            }

            return response()->json([
                'status' => true,
                'message' => 'Account resolved successfully.',
                'data' => [
                    'account_name' => $response['data']['account_name'] ?? null,
                    'account_number' => $response['data']['account_number'] ?? $validated['account_number'],
                    'bank_id' => $response['data']['bank_id'] ?? null,
                ],
            ]);
        } catch (\Throwable $e) {
            return response()->json([
                'status' => false,
                'message' => 'Unable to resolve account at the moment: ' . $e->getMessage(),
            ], 422);
        }
    }
}