<?php

namespace App\Http\Controllers\User;

use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Http;
use App\Models\User;
use App\Models\Card;
use App\Models\Withdrawal;
use Illuminate\Support\Facades\DB; 
use Illuminate\Support\Facades\Validator;
use App\Models\Notice;
use App\Models\Plan;
use App\Models\MiningSession;

class DashboardController extends Controller
{
    protected $baseUrl;
    protected $apiKey;
    
    private $baseUrlSafe = 'https://api.safehavenmfb.com';

    public function __construct()
    {
        // $this->baseUrl = "https://api.sudo.africa"; // e.g., https://api.sandbox.sudo.cards
        $this->baseUrl = "https://api.sandbox.sudo.cards";
        // $this->apiKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NTE3OWUzYTAyMTY1ODI3OTgzZGRmMmQiLCJlbWFpbEFkZHJlc3MiOiJqZXRocm9kYWFyQGdtYWlsLmNvbSIsImp0aSI6IjY4MzgyMDJhZGZmOWExZmZhNTQwYzMxMCIsIm1lbWJlcnNoaXAiOnsiX2lkIjoiNjUxNzllM2EwMjE2NTgyNzk4M2RkZjMwIiwiYnVzaW5lc3MiOnsiX2lkIjoiNjUxNzllM2EwMjE2NTgyNzk4M2RkZjJiIiwibmFtZSI6IkplYml6IElubm92YXRpb24gTHRkIiwiaXNBcHByb3ZlZCI6dHJ1ZX0sInVzZXIiOiI2NTE3OWUzYTAyMTY1ODI3OTgzZGRmMmQiLCJyb2xlIjoiQVBJS2V5In0sImlhdCI6MTc0ODUwODcxNCwiZXhwIjoxNzgwMDY2MzE0fQ.1tBtYPIuuAaFCyqm-iy8bxxEYRT9wpaeYvJu5gypYs4";   // Your Sudo API key
    
        $this->apiKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NTE3OWUzYTAyMTY1ODI3OTgzZGRmMmQiLCJlbWFpbEFkZHJlc3MiOiJqZXRocm9kYWFyQGdtYWlsLmNvbSIsImp0aSI6IjY4M2JmMjBmMTg0MGEzNzUxMmQzZGY4YSIsIm1lbWJlcnNoaXAiOnsiX2lkIjoiNjUxNzllM2EwMjE2NTgyNzk4M2RkZjMwIiwiYnVzaW5lc3MiOnsiX2lkIjoiNjUxNzllM2EwMjE2NTgyNzk4M2RkZjJiIiwibmFtZSI6IkplYml6IElubm92YXRpb24gTHRkIiwiaXNBcHByb3ZlZCI6dHJ1ZX0sInVzZXIiOiI2NTE3OWUzYTAyMTY1ODI3OTgzZGRmMmQiLCJyb2xlIjoiQVBJS2V5In0sImlhdCI6MTc0ODc1OTA1NSwiZXhwIjoxNzgwMzE2NjU1fQ.gpJ7KfNIJ4VdFFXEI7dp_7MJ-qkHibffN6LhrBo5Bc8";
    //   $this->baseUrl = "https://api.sandbox.sudo.cards"; // e.g., https://api.sandbox.sudo.cards
    //   $this->apiKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NTE3OWUzYTAyMTY1ODI3OTgzZGRmMmQiLCJlbWFpbEFkZHJlc3MiOiJqZXRocm9kYWFyQGdtYWlsLmNvbSIsImp0aSI6IjY4MzgyMDJhZGZmOWExZmZhNTQwYzMxMCIsIm1lbWJlcnNoaXAiOnsiX2lkIjoiNjUxNzllM2EwMjE2NTgyNzk4M2RkZjMwIiwiYnVzaW5lc3MiOnsiX2lkIjoiNjUxNzllM2EwMjE2NTgyNzk4M2RkZjJiIiwibmFtZSI6IkplYml6IElubm92YXRpb24gTHRkIiwiaXNBcHByb3ZlZCI6dHJ1ZX0sInVzZXIiOiI2NTE3OWUzYTAyMTY1ODI3OTgzZGRmMmQiLCJyb2xlIjoiQVBJS2V5In0sImlhdCI6MTc0ODUwODcxNCwiZXhwIjoxNzgwMDY2MzE0fQ.1tBtYPIuuAaFCyqm-iy8bxxEYRT9wpaeYvJu5gypYs4";   // Your Sudo API key
     
        
    }
    
    
    // mining
   public function mining()
{
    $page_title = 'Mining';

    /** @var \App\Models\User $user */
    $user = user(); // authenticated user

    // Find the user's current plan (if any)
    $userPlan = $user && $user->plan_id
        ? Plan::find($user->plan_id)
        : null;

    // Fetch all active plans (for upsell, etc)
    $plans = Plan::where('status', 'active')->get();

     // Only check session if user has an active plan
    if ($user && $user->plan_id) {
        $latestSession = MiningSession::where('user_id', $user->id)
            ->where('is_active', 0)
            ->latest()
            ->first();

        // Only clear plan if the latest session ended recently (e.g., within 1 hour)
        if ($latestSession && $latestSession->created_at->gt(Carbon::now()->subHour())) {
            $user->plan_id = null;
            $user->save();
        }
    }

    return view(template('user.mining'), compact(
        'page_title',
        'userPlan',
        'plans'
    ));
}



    // public function mining()
    // {
    //     $page_title = 'Mining';
        
    //     $userData = user();
    //     $user = User::where('id', $userData->id)->first();
        
    //     $userPlan = null;
        
    //     // Get user's active plan (you might need to adjust this logic based on your user-plan relationship)
    //     if ($user && $user->plan_id) {
    //         $userPlan = Plan::find($user->plan_id);
    //     }
    //     // If no plan, user gets free plan (handled in frontend with default values)
        
    //     $plans = Plan::where('status', 'active')->get();
        
    //     // check if user has active plan
    //     if($user->plan_id != null){
    //         // check session
    //         $session = MiningSession::where('user_id', $user->id)->where('is_active', 0)->latest();
            
    //         if($session){
    //             // user session is expired set plan to null
    //             $user->plan_id = null;
    //             $user->save();
    //         }
            
    //     }
        
    //     return view(template('user.mining'), compact('page_title', 'userPlan', 'plans'));
    
    // }
    
    
    public function plans()
    {
        $page_title = 'Plans';


        $plans = Plan::orderByDesc('id')->get();
    
        return view(template('user.plans'), compact('page_title', 'plans'));
    }
    
    
    public function purchasePlan($id)
    {
        $user = user();
        $plan = Plan::find($id);
    
        if (!$plan) {
            return response()->json([
                'success' => false,
                'message' => 'Plan not found.'
            ]);
        }
    
        if ($plan->price > $user->balance) {
            return response()->json([
                'success' => false,
                'message' => 'Account balance is too low for plan purchase. Please deposit first.'
            ]);
        }
    
        // Update user's plan and balance
        $user->plan_id = $plan->id;
        $user->balance -= $plan->price;
        $user->staked += $plan->price;
        $user->save();
    
        return response()->json([
            'success' => true,
            'message' => 'Plan purchased successfully!',
            'redirect' => route('user.mining')
        ]);
    }

    
    
    // public function purchasePlan($id)
    // {
    //     $user = user();

    //     $plan = Plan::where('id', $id)->first();
        
    //     if($plan->price > $user->balance){
    //         return response()->json([
    //         'success' => false,
    //         'message' => 'Account Balance is low for plan purchase. Please deposit first',
    //     ]);
    //     }
        
    //     $user->plan_id = $plan->id;
    //     $user->save();
        
    //     $user->balance -= $plan->price;
    //     $user->staked += $plan->price;
    //     $user->save();
        
        
        
    //     return redirect()->route('user.mining')->with('success', 'Plan purchased successfully!');
    // }
    
    
   public function transferFunds(Request $request)
{
    // 1. Validate
    $validator = Validator::make($request->all(), [
        'amount1' => 'required|numeric|min:25000',
        'bank'     => 'required',
        'account'  => 'required',
    ]);

    if ($validator->fails()) {
        $message = $validator->errors()->first();
        return $this->respondError($request, $message, 422);
    }

    $user = user(); // Assuming you have a helper function `user()`

    // Check if user is null
    if (!$user) {
        return $this->respondError($request, 'User not authenticated.', 401);
    }
    
    // site('dis_with') == 0
    if(site('dis_with') == 1){
        return $this->respondError($request, 'Withdrawals are restricted at the moment, Kindly contact admin!', 422);  
    }
    

    // Check if user is restricted
    if ($user->restricted == 1) {
        return $this->respondError($request, 'Your account is limited, kindly contact admin!', 422);
    }

    // 2. Balance check
    $usdAmountRequested = $request->amount1 / 1500;
    if ($user->balance < $usdAmountRequested) {
        return $this->respondError($request, 'Sorry, you do not have enough in your withdrawable balance to initiate this withdrawal. Kindly earn more.', 422);
    }

    // 3. Bank name enquiry
    try {
        $enquiry = $this->bankEnquiry($request->bank, $request->account);
    } catch (\Exception $e) {
        return $this->respondError($request, 'Name enquiry failed: ' . $e->getMessage(), 500);
    }

    // 4. Get token
    $token = $this->requestSafeHavenToken();
    if (!$token) {
        return $this->respondError($request, 'Unable to fetch authentication token', 500);
    }

    // 5. Do the transfer
    $payload = [
        'nameEnquiryReference'     => $enquiry,
        'debitAccountNumber'       => '0119318661',
        'beneficiaryBankCode'      => $request->bank,
        'beneficiaryAccountNumber' => $request->account,
        'amount'                   => (float) $request->amount1,
        'saveBeneficiary'          => false,
        'narration'                => 'Withdrawal',
        'paymentReference'         => uniqid('trx-'),
    ];

    $response = $this->makeSafeHavenRequest('POST', '/transfers', $token, $payload);
    $body     = $response->json();

    if (!isset($body['data']['fees'])) {
        $errMsg = $body['message'] ?? 'Sorry, bank transactions are currently facing a delay due to maintenance. Please try again or contact admin if the issue persists.';
        return $this->respondError($request, $errMsg, $response->status());
    }

    // 6. Deduct, log, save
    $fee       = $body['data']['fees'];
    $finalAmt  = $request->amount1 + $fee;
    $usdAmount = $finalAmt / 1500;

    DB::transaction(function () use ($usdAmount, $finalAmt, $request, $fee, $user) {
        // Update balance
        $user->balance -= $usdAmount;
        $user->save();

        // Record transaction
        recordNewTransaction($request->amount1, $user->id, 'debit', 'New Withdrawal Request');

        // Create withdrawal record
        $withdrawal = Withdrawal::create([
            'user_id'           => $user->id,
            'deposit_coin_id'   => 1,
            'wallet_address'    => $request->account,
            'amount'            => $finalAmt,
            'converted_amount'  => $usdAmount,
            'fee'               => $fee,
            'status'            => 'approved',
            'type'              => 'auto',
            'currency'              => 'ngn',
            'ref'               => uniqid('trx-'),
        ]);

        sendWithdrawalEmail($withdrawal);

        session()->flash('withdrawal', $withdrawal);
    });

    return $this->respondSuccess($request, 'Withdrawal sent successfully');
}

    
    /**
     * Helper to send an error either as JSON (for AJAX) or as a redirect+flash.
     */
    protected function respondError(Request $request, $message, $status = 400)
    {
        if ($request->expectsJson()) {
            return response()->json([
                'status'  => 'error',
                'message' => $message,
            ], $status);
        }
    
        return redirect()->back()
            ->with('error', $message);
    }
    
    /**
     * Helper to send success either as JSON or redirect+flash.
     */
    protected function respondSuccess(Request $request, $message, $data = [])
    {
        if ($request->expectsJson()) {
            return response()->json(array_merge([
                'status'  => 'success',
                'message' => $message,
            ], $data));
        }
    
        return redirect()->back()
            ->with('message', $message);
    }

    
    
    // public function transferFunds(Request $request)
    // {
    //     $request->validate([
    //         'amount1' => 'required',
    //         'bank' => 'required',
    //         'account' => 'required'
    //     ]);
        
        
    //     if (user()->balance < $request->amount1/1500) {
    //         return response()->json(validationError('Insufficient balance'), 422);
    //     }
        
        
        
    //     $enq = $this->bankEnquiry($request->bank, $request->account);
        
    //     // return $enq;
        
        
        
    //     $enquiry = $enq;
    //     $debitAccountNo = "0119318661";
    //     $bankCode = $request->bank;
    //     $accountNo = $request->account;
    //     $amount = $request->amount1;
        
        
    //     $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
    //     if (!$token) {
    //         return response()->json(['error' => 'Unable to fetch token'], 500);
    //     }
    
    //     $payload = [
    //         'nameEnquiryReference' => $enquiry,
    //         'debitAccountNumber' => $debitAccountNo,
    //         'beneficiaryBankCode' => $bankCode,
    //         'beneficiaryAccountNumber' => $accountNo,
    //         'amount' => (float) $amount,
    //         'saveBeneficiary' => false,
    //         'narration' => "Withdrawal",
    //         'paymentReference' => uniqid('trx-'),
    //     ];
        
        
    
        
    //     $endpoint = "/transfers";
    
    //     $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
        
    //     $responseBody = $response->json();
        
    //     $fee = $responseBody['data']['fees'];
        
    //     $finalAmount = (float) $fee + (float) $amount;
        
    //     $usdAmount = $finalAmount/1500;
        
        
    //     $debit = User::find(user()->id);
    //     $debit->balance = user()->balance - $usdAmount;
    //     $debit->save();
        
    //     $ref = uniqid('trx-');
        
    //     //log transaction
    //     recordNewTransaction($amount, user()->id, 'debit', 'New Withdrawal Request');

    //     //store the withdrawal
    //     $withdrawal = new Withdrawal();
    //     $withdrawal->user_id = user()->id;
    //     $withdrawal->deposit_coin_id = 1;
    //     $withdrawal->wallet_address = $accountNo;
    //     $withdrawal->amount = $usdAmount;
    //     $withdrawal->converted_amount = $usdAmount;
    //     $withdrawal->fee = (float) $fee/1500;
    //     $withdrawal->status = 'approved';
    //     $withdrawal->type = "auto";
    //     $withdrawal->ref = $ref;
    //     $withdrawal->save();
        
    //     sendWithdrawalEmail($withdrawal);

    //     return redirect()->back()
    // ->with('withdrawal', $withdrawal)
    // ->with('message', 'Withdrawal initiated successfully');

    
    //     // return $response->successful()
    //     //     ? $response->json()
    //     //     : response()->json([
    //     //         'error' => 'Payment request failed',
    //     //         'status' => $response->status(),
    //     //         'body' => $response->body()
    //     //     ], $response->status());
    // }
    
    
    public function bankEnquiry($bank, $account)
    {
        $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
        if (!$token) {
            throw new \Exception('Unable to fetch SafeHaven token');
        }
    
        $payload = [
            'bankCode' => $bank,
            'accountNumber' => $account,
        ];
    
        $endpoint = "/transfers/name-enquiry";
    
        // Log the request for debugging
        \Log::info('SafeHaven bankEnquiry request', [
            'endpoint' => $endpoint,
            'payload' => $payload,
            'bank' => $bank,
            'account' => $account
        ]);
    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
        $responseBody = $response->json();
        
        // Log the response for debugging
        \Log::info('SafeHaven bankEnquiry response', [
            'response' => $responseBody,
            'status' => $response->status()
        ]);
        
        // Handle different types of API responses
        if (!$response->successful()) {
            \Log::error('SafeHaven bankEnquiry failed', [
                'status' => $response->status(),
                'response' => $responseBody
            ]);
            
            // Handle specific SafeHaven error responses
            if (isset($responseBody['message'])) {
                $errorMessage = $responseBody['message'];
                $responseCode = $responseBody['responseCode'] ?? null;
                
                // Map common SafeHaven error codes to user-friendly messages
                switch ($responseCode) {
                    case '91':
                        throw new \Exception('The selected bank is not supported for transfers. Please choose a different bank from the supported banks list.');
                    case '10':
                        throw new \Exception('Invalid account number. Please check the account number and try again.');
                    case '15':
                        throw new \Exception('Account name could not be verified. Please check the account details.');
                    default:
                        throw new \Exception('Bank verification failed: ' . $errorMessage);
                }
            }
            
            throw new \Exception('SafeHaven API request failed with status: ' . $response->status() . '. Please try again or contact support.');
        }
        
        // Check if response has the expected structure
        if (!isset($responseBody['data']) || !isset($responseBody['data']['sessionId'])) {
            // Log the actual response for debugging
            \Log::error('SafeHaven bankEnquiry unexpected response structure', [
                'response' => $responseBody,
                'status' => $response->status(),
                'expected_keys' => ['data.sessionId'],
                'actual_keys' => array_keys($responseBody ?? [])
            ]);
            
            // Check if it's a successful response but with different structure
            if (isset($responseBody['message']) && str_contains(strtolower($responseBody['message']), 'success')) {
                throw new \Exception('Bank verification completed but session could not be established. Please try again.');
            }
            
            throw new \Exception('Invalid response from SafeHaven API: Missing session information. Please try again or contact support.');
        }

        $enq = $responseBody['data']['sessionId'];
    
        return $enq;
    }
    
    
    public function confirmBank(Request $request)
    {
        
        
        $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $payload = [
            'bankCode' => $request->bankCode,
            'accountNumber' => $request->accountNumber,
        ];
    
        
        $endpoint = "/transfers/name-enquiry";

    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
        
        $responseBody = $response->json();

        // $enq = $responseBody['data']['sessionId'];
    
        return $responseBody;
    }
    
    
    public function banks()
    {
        $token = $this->requestSafeHavenToken();
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $response = $this->makeSafeHavenRequest('GET', '/transfers/banks', $token);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }
    
    
    
    // Transactions
    public function safeHavenTransactions()
    {
        $token = $this->requestSafeHavenToken();
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $endpoint = "/vas/transactions";
    
        $response = $this->makeSafeHavenRequest('GET', $endpoint, $token);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Failed to fetch transactions',
                'status' => $response->status(),
                'body' => $response->body(),
            ], $response->status());
    }

    
    // Purchase Utility
    public function safeHavenUtilityPurchase()
    {
        $amount = 10;
        $categoryId = "61efac19b5ce7eaad3b405d4";
        $meter = '55260119318661';
        $vendor = "67348634834";
        
        $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $payload = [
            'amount' => $amount,
            'channel' => 'WEB',
            'serviceCategoryId' => $categoryId,
            'debitAccountNumber' => '0119318661',
            'meterNumber' => $meter,
            'vendType' => $vendor,
        ];
    
        
        $endpoint = "/vas/pay/utility";
    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Payment request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }
    
    
    // Purchase Cable TV
    public function safeHavenCableTvPurchase()
    {
        $amount = 10;
        $categoryId = "61efac19b5ce7eaad3b405d4";
        $card = '55260119318661';
        
        $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $payload = [
            'amount' => $amount,
            'channel' => 'WEB',
            'serviceCategoryId' => $categoryId,
            'bundleCode' => 'hsdgfhsdfg',
            'debitAccountNumber' => '0119318661',
            'cardNumber' => $card,
        ];
    
        
        $endpoint = "/vas/pay/cable-tv";
    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Payment request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }
    
    
    // Purchase Data
    public function safeHavenDataPurchase()
    {
        $amount = 10;
        $categoryId = "61efac19b5ce7eaad3b405d4";
        $phone = '+2349136066805';
        
        $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $payload = [
            'amount' => $amount,
            'channel' => 'WEB',
            'serviceCategoryId' => $categoryId,
            'bundleCode' => 'rtrtrtrt',
            'debitAccountNumber' => '0119318661',
            'phoneNumber' => $categoryId,
            'statusUrl' => 'https://jebiz.org/api/safe-callback',
        ];
    
        
        $endpoint = "/vas/pay/data";
    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Payment request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }
    
    
    // Purchase Airtime
    public function safeHavenAirtimePurchase()
    {
        $amount = 10;
        $categoryId = "61efac19b5ce7eaad3b405d4";
        $phone = '+2349136066805';
        
        $token = $this->requestSafeHavenToken(); // Make sure this fetches a valid token
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $payload = [
            'amount' => $amount,
            'channel' => 'WEB',
            'serviceCategoryId' => $categoryId,
            'phoneNumber' => $phone,
            'statusUrl' => 'https://jebiz.org/api/safe-callback',
            'debitAccountNumber' => '0119318661',
        ];
    
        
        $endpoint = "/vas/pay/airtime";
    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Payment request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }


    
    public function safeHavenVerifyEntity()
    {
        $token = $this->requestSafeHavenToken(); 
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $payload = [
            'serviceCategoryId' => '61efac19b5ce7eaad3b405d4',
            'entityNumber' => '623642364752354',
        ];
        
        $endpoint = "/vas/verify";
    
        $response = $this->makeSafeHavenRequest('POST', $endpoint, $token, $payload);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }



    
    public function safeHavenCategoryProducts()
    {
        $id = "61efac19b5ce7eaad3b405d4";
        
        $token = $this->requestSafeHavenToken();
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $endpoint = "/vas/service-category/{$id}/products";
    
        $response = $this->makeSafeHavenRequest('GET', $endpoint, $token);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }

    
    public function safeHavenServiceCategories()
    {
        $id = "61efab78b5ce7eaad3b405d0";
        
        $token = $this->requestSafeHavenToken();
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $endpoint = "/vas/service/{$id}/service-categories";
    
        $response = $this->makeSafeHavenRequest('GET', $endpoint, $token);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }

    
    public function safeHavenSingleService()
    {
        $service = "61efab78b5ce7eaad3b405d0";
    
        $token = $this->requestSafeHavenToken();
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $endpoint = "/vas/service/{$service}";
    
        $response = $this->makeSafeHavenRequest('GET', $endpoint, $token);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }

    
     
    public function safeHavenServices()
    {
        $token = $this->requestSafeHavenToken();
    
        if (!$token) {
            return response()->json(['error' => 'Unable to fetch token'], 500);
        }
    
        $response = $this->makeSafeHavenRequest('GET', '/vas/services', $token);
    
        return $response->successful()
            ? $response->json()
            : response()->json([
                'error' => 'Request failed',
                'status' => $response->status(),
                'body' => $response->body()
            ], $response->status());
    }


    private function requestSafeHavenToken()
    {
        $payload = [
            'grant_type' => 'client_credentials',
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
            'client_id' => '523d581921dd49665d3aae522b8baa02',
            'client_assertion' => 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FwaS5jYnJpbGxpYW5jZS5pbyIsInN1YiI6IjUyM2Q1ODE5MjFkZDQ5NjY1ZDNhYWU1MjJiOGJhYTAyIiwiYXVkIjoiaHR0cHM6Ly9hcGkuc2FmZWhhdmVubWZiLmNvbSIsImlhdCI6MTc2MDU3NDA1OSwiZXhwIjoxODYwNTczOTQ2fQ.qWoBQ4kv7hpOqnH9fkop-AE3Sbjg3PO8CQKBmvITvxMGa-ULRK8ZD0vGMIpbUFd35dZgwwWsTyzuc14TIfJdZ448zqnymDOhTKTE3o9GtGpFCZ8ewB3Tp1ju9eGEnPfmBFmSxbFGb9GvzuBeAxZv08xfMatsqlyaD4dfoOr3Hyo' // Replace with actual JWT
        ];
    
        $response = $this->makeSafeHavenRequest('POST', '/oauth2/token', null, $payload);
    
        return $response->successful()
            ? $response->json('access_token')
            : null;
    }


    private function makeSafeHavenRequest(string $method, string $endpoint, ?string $token = null, array $data = [])
    {
        $url = $this->baseUrlSafe . $endpoint;
    
        $headers = [
            'Accept' => 'application/json',
            'ClientID' => '523d581921dd49665d3aae522b8baa02',
        ];
    
        if ($token) {
            $headers['Authorization'] = 'Bearer ' . $token;
        }
    
        $http = Http::withHeaders($headers)
            ->withOptions([
                'verify' => false, // Disable SSL verification for Windows
                'curl' => [
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_SSL_VERIFYHOST => false,
                ]
            ])
            ->timeout(30);
    
        $method = strtoupper($method);
    
        switch ($method) {
            case 'POST':
                return $http->post($url, $data);
            case 'PUT':
                return $http->put($url, $data);
            case 'PATCH':
                return $http->patch($url, $data);
            case 'DELETE':
                return $http->delete($url, $data);
            default:
                return $http->get($url, $data);
        }
    }


    
    
    public function fundCard(Request $request, $id) {
        $card = Card::findOrFail($id);
        $amount = $request->input('amount');
        // logic to fund card
        $card->amount += $amount;
        $card->save();
        
         $data = [
            'debitAccountId' => '6528253fb42cd354e6642b87',
            'creditAccountId' => $card->card_id,
            'amount' => (float) $amount,
            'narration' => 'Funding of wallet for ' . $card->customer,
        ];
    
        // Make the card request to Sudo API
        $response = $this->sudoRequest('post', '/accounts/transfer', $data);
        
        Log::info('Fund card response:', ['response' => $response]);
        
        return response()->json(['message' => 'Card funded']);
    }
    
    public function freezeCard($id) {
        $card = Card::findOrFail($id);
        $card->status = 'frozen';
        $card->save();
        return response()->json(['message' => 'Card frozen']);
    }
    
    public function activateCard($id) {
        $card = Card::findOrFail($id);
        $card->status = 'active';
        $card->save();
        return response()->json(['message' => 'Card activated']);
    }

    
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function dashboard()
    {
        $page_title = 'Dashboard';

        $today_start = Carbon::today(); // Start of today
        $today_end = Carbon::now(); // Current time

        $yesterday_start = Carbon::yesterday(); // Start of yesterday
        $yesterday_end = Carbon::yesterday()->endOfDay(); // End of yesterday

        // Today's deposits
        $todays_deposits = user()->transactions()
            ->whereBetween('created_at', [$today_start, $today_end])
            ->where('type', 'credit')
            ->sum('amount');

        // Yesterday's deposits
        $yesterdays_deposits = user()->transactions()
            ->whereBetween('created_at', [$yesterday_start, $yesterday_end])
            ->where('type', 'credit')
            ->sum('amount');

        if ($yesterdays_deposits > 0) {
            $percentage_deposit_increase = (($todays_deposits - $yesterdays_deposits) / $yesterdays_deposits) * 100;
        } else {
            // Handle the case where yesterday's deposits are zero
            if ($todays_deposits > 0) {
                $percentage_deposit_increase = 100; // Treat as 100% increase
            } else {
                $percentage_deposit_increase = 0; // No increase since both are zero
            }
        }


        // PNL
        $activations = user()->botActivations();
        $capital = $activations->sum('capital');
        $profit_fig = $activations->sum('profit');
        $profit_percent = user()->botHistory()->sum('profit_percent');
        //dd($profit / $capital);

        $activations =  user()
            ->botActivations()
            ->with('bot')
            ->orderBy('id', 'DESC')
            ->paginate(site('pagination'));


        // history
        $histories = user()
            ->botHistory()
            ->with(['botActivation.bot'])
            ->orderBy('timestamp', 'DESC')
            ->paginate(site('pagination'));

        $startDate = Carbon::now()->subDays(6);
        $endDate = Carbon::now();

        $chart_data = user()
            ->botHistory()
            ->selectRaw('DATE(created_at) as date, SUM(profit) as total_profit, SUM(profit_percent) as total_profit_percent')
            ->whereBetween('created_at', [$startDate, $endDate])
            ->groupBy('date')
            ->orderBy('date')
            ->get();

        $graph_info = [];
        $days = [];
        $profit_percentages = [];
        $profits = [];

        // Create an associative array with all days within the date range and initial values of 0
        $currentDate = $startDate;
        while ($currentDate <= $endDate) {
            $formatted_date = $currentDate->format('d-m');
            $graph_info[$formatted_date] = ['profit' => 0, 'profit_percent' => 0];
            $currentDate->addDay();
            array_push($days, $formatted_date);
        }

        // Populate the graph_info array with actual data from $chart_data
        foreach ($chart_data as $data) {
            $formatted_date = date('d-m', strtotime($data->date));
            $graph_info[$formatted_date] = ['profit' => $data->total_profit, 'profit_percent' => $data->total_profit_percent];
        }


        foreach ($graph_info as $day => $profit) {
            array_push($days, $day);
            array_push($profits, $profit['profit']);
            array_push($profit_percentages, $profit['profit_percent']);
        }

        $withdrawals = user()
            ->withdrawals()
            ->with('depositCoin')
            ->orderBy('id', 'DESC')
            ->paginate(site('pagination'));

        $deposits = user()
            ->deposits()
            ->with('depositCoin')
            ->orderBy('id', 'DESC')
            ->paginate(site('pagination'));
            
        $notices = Notice::orderByDesc('id')->get();
            
        return view(template('user.dashboard'), compact(
            'page_title',
            'todays_deposits',
            'percentage_deposit_increase',
            'capital',
            'notices',
            
            'profit_fig',
            'activations',
            'histories',
            'profits',
            'days',
            'profit_percentages',
            'withdrawals',
            'deposits',
            'profit_percent'
        ));
    }
    
    
     // Make sure this is at the top of your controller

    public function cards()
    {
        $page_title = 'Cards';
    
        // Handle both web and API authentication
        $session = auth()->user(); // Use auth()->user() instead of user() helper
        
        if (!$session) {
            Log::error('No authenticated user found in cards method');
            return response()->json(['message' => 'User not authenticated']);
        }
    
        $user = User::where('id', $session->id)->first();
    
        // Redirect to profile completion if any essential fields are missing
        if (!$user->name || !$user->username || !$user->email || !$user->phone) {
            return redirect()->route('user.profile.edit');
        }
    
        if (empty($user->sudo_id)) {
            // Create a new customer on the Sudo API
            $customer = $this->createCustomer($user->name, $user->username, $user->email, $user->phone);
    
            Log::info('Sudo customer creation response:', ['response' => $customer]);
    
            // Safely access the nested _id field
            if (isset($customer['data']['_id'])) {
                $user->sudo_id = $customer['data']['_id'];
                $user->save();
    
                Log::info('Sudo customer creation response ID', ['id' => $user->sudo_id]);
            } else {
                Log::error('Failed to create Sudo customer.', ['response' => $customer]);
                // Optionally: return redirect()->back()->with('error', 'Could not create Sudo customer.');
            }
        }
    
        $cards = Card::orderByDesc('id')->where('user_id', $user->id)->get();
    
        return view(template('user.cards'), compact('page_title', 'cards'));
    }


    
    // Cards generation
    protected function sudoRequest($method, $endpoint, $data = [])
    {
        $response = Http::withToken($this->apiKey)
            ->withOptions([
                'verify' => false, // Disable SSL verification for Windows
                'curl' => [
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_SSL_VERIFYHOST => false,
                ]
            ])
            ->timeout(30)
            ->acceptJson()
            ->{$method}("{$this->baseUrl}{$endpoint}", $data);

        return $response->json();
    }

    // 1. Create a Customer
    public function createCustomer($firstName, $lastName, $email, $phone)
    {
        $data = [
            "type" => "individual",
            "name" => "$firstName",
            "phoneNumber" => $phone,
            "emailAddress" => $email,
            "individual" => [
                "firstName" => $firstName,
                "lastName" => $lastName,
                "otherNames" => "", // Fill if you have this data
                "dob" => "1990-01-01", // Ideally get from user profile
                "identity" => [
                    "type" => "BVN",
                    "number" => "12345678901" // Replace with real BVN if available
                ],
                "documents" => [
                    "idFrontUrl" => "https://example.com/id-front.jpg",
                    "idBackUrl" => "https://example.com/id-back.jpg",
                    "incorporationCertificateUrl" => "https://example.com/certificate.jpg",
                    "addressVerificationUrl" => "https://example.com/address.jpg"
                ]
            ],
            "status" => "active",
            "billingAddress" => [
                "line1" => "123 Main St",
                "line2" => "Apt 4B",
                "city" => "Lagos",
                "state" => "Lagos",
                "postalCode" => "100001",
                "country" => "NG"
            ]
        ];
    
        return $this->sudoRequest('post', '/customers', $data);
    }


    // 2. Get Customers
    public function getCustomers()
    {
        return $this->sudoRequest('get', '/customers');
    }

    // 3. Create a Card
public function createCard()
{
    // Handle both web and API authentication
    $session = auth()->user(); // Use auth()->user() instead of user() helper
    
    if (!$session) {
        Log::error('No authenticated user found');
        return response()->json(['message' => 'User not authenticated']);
    }
    
    $user = User::find($session->id);

    if (!$user || !$user->sudo_id) {
        Log::error('User not found or missing sudo_id', [
            'user_id' => $session->id,
            'user_exists' => $user ? 'yes' : 'no',
            'sudo_id' => $user ? $user->sudo_id : 'user_not_found'
        ]);
        return response()->json(['message' => 'User not valid or sudo_id missing']);
    }

    // if ($user->balance < 50) {
    //     Log::info('Insufficient Funds to create a Card!', ['user' => $user->id]);
    //     return response()->json(['message' => 'Insufficient Funds to create a Card!']);
    // }

    $data = [
        "customerId" => $user->sudo_id,
        // "fundingSourceId" => "683bebe16f7ef70ec24b9eb6",
        "fundingSourceId" => "65179e3a02165827983ddf32",
        "type" => "virtual",
        "brand" => "MasterCard",
        "currency" => "USD",
        "issuerCountry" => "USA",
        "status" => "active",
        "debitAccountId" => "6528253fb42cd354e6642b87",
        "sendPINSMS" => false,
        "amount" => 3
    ];

    // Make the card request to Sudo API
    $response = $this->sudoRequest('post', '/cards', $data);
    
    
    

    if ($response['statusCode'] == 200) {
        
    $cardData = $response['data'];

    //
    // 1) FETCH THE TOKEN CORRECTLY
    //
    $tokenRes = $this->sudoRequest('get', "/cards/{$cardData['_id']}/token");
    
    Log::error('Generated token', [
            'response' => $tokenRes,
        ]);

    // Make sure we check both statusCode and the nested data.token key
    if (
        is_array($tokenRes)
        && isset($tokenRes['statusCode'])
        && $tokenRes['statusCode'] === 200
        && isset($tokenRes['data']['token'])
    ) {
        $token = $tokenRes['data']['token'];
    } else {
        Log::error('Failed to get token', [
            'response' => $tokenRes,
        ]);
        return response()->json(['message' => 'Failed to get token'], 500);
    }

    //
    // 2) FETCH CARD NUMBER
    // https://vdl2xefo5.forward.securepro.xyz/cards/683adeb5ae447a52c68adb42/secure-data/number
    // https://we0dsa28s.forward.securepro.xyz/cards/683adeb5ae447a52c68adb42/secure-data/number - sandbox
    //
    $cardRes = Http::withHeaders([
        'Authorization' => "Bearer {$token}",
    ])->withOptions([
        'verify' => false, // Disable SSL verification for Windows
        'curl' => [
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
        ]
    ])->timeout(30)->get("https://we0dsa28s.forward.securepro.xyz/cards/{$cardData['_id']}/secure-data/number");

    if ($cardRes->successful()) {
        $cardNumberData = $cardRes->json('data');
        $cardNumber     = isset($cardNumberData['number']) ? $cardNumberData['number'] : null;

        if (!$cardNumber) {
            Log::error('Card number missing in response', [
                'response' => $cardRes->body(),
            ]);
            return response()->json(['message' => 'Card number not found'], 500);
        }
    } else {
        Log::error('Failed to fetch card number', [
            'response' => $cardRes->body(),
        ]);
        return response()->json(['message' => 'Failed to fetch card number'], 500);
    }

    //
    // 3) FETCH CVV2
    //
    $ccvRes = Http::withHeaders([
        'Authorization' => "Bearer {$token}",
    ])->withOptions([
        'verify' => false, // Disable SSL verification for Windows
        'curl' => [
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
        ]
    ])->timeout(30)->get("https://we0dsa28s.forward.securepro.xyz/cards/{$cardData['_id']}/secure-data/cvv2");

    if ($ccvRes->successful()) {
        $ccvData  = $ccvRes->json('data');
        $ccvNumber = isset($ccvData['cvv2']) ? $ccvData['cvv2'] : null;

        if (!$ccvNumber) {
            Log::error('CVV2 missing in response', [
                'response' => $ccvRes->body(),
            ]);
            return response()->json(['message' => 'CVV2 not found'], 500);
        }
    } else {
        Log::error('Failed to fetch CVV2 number', [
            'response' => $ccvRes->body(),
        ]);
        return response()->json(['message' => 'Failed to fetch CVV2 number'], 500);
    }

    //
    // 4) FETCH DEFAULT PIN
    //
    $pinRes = Http::withHeaders([
        'Authorization' => "Bearer {$token}",
    ])->withOptions([
        'verify' => false, // Disable SSL verification for Windows
        'curl' => [
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
        ]
    ])->timeout(30)->get("https://we0dsa28s.forward.securepro.xyz/cards/{$cardData['_id']}/secure-data/defaultPin");

    if ($pinRes->successful()) {
        $pinData           = $pinRes->json('data');
        $defaultPinNumber = isset($pinData['defaultPin']) ? $pinData['defaultPin'] : 1234;

        if (!$defaultPinNumber) {
            Log::error('Default PIN missing in response', [
                'response' => $pinRes->body(),
                'Pin Data' => $pinData
            ]);
            return response()->json(['message' => 'Default PIN not found'], 500);
        }
    } else {
        Log::error('Failed to fetch default PIN number', [
            'response' => $pinRes->body(),
        ]);
        return response()->json(['message' => 'Failed to fetch default PIN number'], 500);
    }

    //
    // 5) SAVE CARD DETAILS TO THE DATABASE
    //
    // Note: Use a different variable name than $card to avoid confusion.
    $cardModel = new Card();
    $cardModel->user_id      = $user->id;
    $cardModel->card_id      = $cardData['_id'];
    $cardModel->customer     = $user->name;
    $cardModel->card_number  = $cardNumber;
    $cardModel->expiry_month = $cardData['expiryMonth'];
    $cardModel->expiry_year  = $cardData['expiryYear'];
    $cardModel->cvv          = $ccvNumber;
    $cardModel->pin          = $defaultPinNumber;
    $cardModel->amount       = 0;
    $cardModel->card_type    = $cardData['type'];
    $cardModel->brand        = $cardData['brand'];
    $cardModel->status       = $cardData['status'];
    $cardModel->save();

    //
    // 6) DEDUCT USER BALANCE
    //
    $user->balance -= 100;
    $user->save();

    //
    // 7) RETURN SUCCESS RESPONSE
    //
    return redirect()->back()->with('success', 'Card created and saved');

}




    return response()->json(['message' => 'Failed to create card', 'response' => $response]);
}

    
    
    

    // 4. Get Cards
    public function getCards()
    {
        return $this->sudoRequest('get', '/cards');
    }

    // 5. Create an Account
    public function createAccount(Request $request)
    {
        $data = $request->only(['customer_id', 'currency']);
        return $this->sudoRequest('post', '/accounts', $data);
    }

    // 6. Get Accounts
    public function getAccounts()
    {
        return $this->sudoRequest('get', '/accounts');
    }

    // 7. Fund Transfer
    public function fundTransfer(Request $request)
    {
        $data = $request->only(['source_account_id', 'destination_account_id', 'amount', 'currency']);
        return $this->sudoRequest('post', '/transfers', $data);
    }

    // 8. Get Transactions
    public function getTransactions()
    {
        return $this->sudoRequest('get', '/transactions');
    }

    // 9. Create a Dispute
    public function createDispute(Request $request)
    {
        $data = $request->only(['transaction_id', 'reason', 'description']);
        return $this->sudoRequest('post', '/disputes', $data);
    }

    // 10. Simulate Authorization (Sandbox Only)
    public function simulateAuthorization(Request $request)
    {
        $data = $request->only(['card_id', 'amount', 'currency']);
        return $this->sudoRequest('post', '/simulator/authorize', $data);
    }

}
