<?php

namespace App\Service;

use App\Models\User;
use Illuminate\Http\Request;
use App\Models\FailedBooking;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Service\Windcave\MifMessage;
use App\Service\Windcave\PxPay_Curl;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use App\Service\Windcave\PxPayRequest;
use App\Http\Controllers\Eventmie\BookingsController;


class Flutterwave extends Controller
{
    public $booking_controller, $publicKey, $secretKey, $baseUrl;

    /**
     * __construct
     *
     * @return void
     */
    public function __construct()
    {
        $this->publicKey = setting('apps.flutterwave_key'); //'FLWPUBK_TEST-275f3afd21a44ebb2c04ecc9d9c999d5-X';
        $this->secretKey =  setting('apps.flutterwave_secret_key');  //'FLWSECK_TEST-f847a870a16338639697c0d302f82ea3-X';
        $this->baseUrl = 'https://api.flutterwave.com/v3';
        
        $this->booking_controller = new BookingsController;
    }
    
    /**
     * Request
     *
     * @param  mixed $request
     * @return void
     */
    public function request($order = [], $currency = 'USD')
    {
        $url = route('eventmie.mybookings_index');
        if(Auth::user()->hasRole('organiser'))
            $url = route('eventmie.obookings_index');
        
        if(Auth::user()->hasRole('admin'))
            $url = route('voyager.bookings.index');
        if(Auth::user()->hasRole('pos'))
            $url = route('pos.index');

        
        try {
            
            $amount =  $order['price'];;
            $currency = $currency;
            $txRef = $order['order_number']; // Unique reference for the transaction
            $redirectUrl = route('flutterwave.callback');

            if(checkPrefix())
            {
                $redirectUrl = route('flutterwave.app_callback');;
            }
            $customerEmail = session('payment_method')['customer_email'];

            // Prepare the data for the API request
            $data = [
                'tx_ref' => $txRef,
                'amount' => $amount,
                'currency' => $currency,
                'redirect_url' => $redirectUrl,
                'customer' => [
                    'email' => $customerEmail, // Add customer email
                ],
            ];

            $response = Http::withHeaders([

                'Authorization' => 'Bearer ' . $this->secretKey,
                'Content-Type' => 'application/json',
                'accept' => 'application/json',

            ])->post($this->baseUrl.'/payments', $data);

            
            if($response->ok()) 
            {
                $result = $response->json();
                
                if ($result['status'] == 'success') 
                    return  response()->json(['status' => true, 'url' => $result['data']['link']]);
        
            }
            

        } catch(\Throwable $th) {
            
            // dd($th->getMessage());
        }

        $msg = __('eventmie-pro::em.booking').' '.__('eventmie-pro::em.failed');
        return response()->json(['status' => false, 'url'=>$url, 'message'=>$msg]); 
    }
    
    /**
     * callback
     *
     * @param  mixed $request
     * @return void
     */
    public function callback(Request $request)
    {   
        $flag = [];

        try {

            \DB::table('webhook_test')->insert(['data' => json_encode($request->all())]);

            // if customer then redirect to mybookings
            $url = route('eventmie.mybookings_index');
            if(Auth::user()->hasRole('organiser'))
                $url = route('eventmie.obookings_index');
            
            if(Auth::user()->hasRole('admin'))
                $url = route('voyager.bookings.index');
            if(Auth::user()->hasRole('pos'))
                $url = route('pos.index');


            $flag = [];

            if($request->status == 'successful')
            {
            
                $data =  FailedBooking::whereJsonContains('pre_payment->order_number', $request->tx_ref)->first();

                if(empty($data)) {
                    throw new \Exception();
                }
                
                if(!empty($data->success)) {
                    return success_redirect(__('eventmie-pro::em.booking_success'), $url);
                }
            
                $booking        = json_decode($data->booking, true);
                $pre_payment    = json_decode($data->pre_payment, true);
                $payment_method = json_decode($data->payment_method, true);
                $commission     = json_decode($data->commission, true);
                $seats          = json_decode($data->seats, true);
                $selected_attendees     = json_decode($data->selected_attendees, true);

                session(['booking' => $booking, 'pre_payment' =>  $pre_payment, 'payment_method' =>  $payment_method, 'commission' => $commission, 'selected_attendees' => $selected_attendees, 'seats' => $seats]);

            
                $flag['status'] = true;
                $flag['transaction_id']      = $request->transaction_id;
                $flag['payer_reference']     = $request->tx_ref;
                $flag['message']             = $request->status;
                
                return $this->booking_controller->flutterwaveCallback($flag);
            
            
            }
            
            
            
        } catch (\Throwable $th) {
            // dd($th->getMessage());
        }
        
        $flag['status'] = false;

        return $this->booking_controller->flutterwaveCallback($flag);
    }
    
    /**
     * webhook
     *
     * @param  mixed $request
     * @return void
     */
    public function webhook(Request $request)
    {
        
        try  {

            DB::table('webhook_test')->insert(['data' => json_encode($request->all())]);

            $data = FailedBooking::whereJsonContains('pre_payment->order_number', $request->txRef)->where(['success' => 0, 'payment_failed' => 0])->first();
            
            if(empty($data)) {
                throw new \Exception();
            }
            $user = User::find($data->customer_id);
                
            Auth::login($user);
    
            $booking        = json_decode($data->booking, true);
            $pre_payment    = json_decode($data->pre_payment, true);
            $payment_method = json_decode($data->payment_method, true);
            $commission     = json_decode($data->commission, true);
            $seats          = json_decode($data->seats, true);
            $selected_attendees     = json_decode($data->selected_attendees, true);

            session(['booking' => $booking, 'pre_payment' =>  $pre_payment, 'payment_method' =>  $payment_method, 'commission' => $commission, 'selected_attendees' => $selected_attendees, 'seats' => $seats]);

            $flag           = [];
        
            // set data
            
            if($request->status == 'successful')
            {
                $flag['status'] = true;
                $flag['transaction_id']      = $request->id;
                $flag['payer_reference']     = $request->txRef;
                $flag['message']             = $request->status;
                
            }
            else
            {
                $flag = [
                    'status'    => false,
                    'error'     => '',
                ];
            }    
            
            $this->booking_controller->flutterwaveCallback($flag); 
            
            if($request->status == 'successful')
                return response()->json(['status' => true]);
        
        } catch(\Throwable $th)   {
            
            
        }

        return response()->json(['status' => false]);
    }

     
    /**
     * appFlutterwaveCallback
     *
     * @param  mixed $request
     * @return void
     */
    public function appFlutterwaveCallback(Request $request)
    {
        try
        {
            $data = FailedBooking::where(['orderId' => $request->tx_ref])->first();
            
            if(empty($data)) 
                throw new \Exception();
            
            if(empty($data->success))
            {
                if($request->status == 'successful')
                {
                    $booking        = json_decode($data->booking, true);
                    $pre_payment    = json_decode($data->pre_payment, true);
                    $payment_method = json_decode($data->payment_method, true);
                    $commission     = json_decode($data->commission, true);
                    $seats          = json_decode($data->seats, true);
                    $selected_attendees     = json_decode($data->selected_attendees, true);

                    $user = User::find($data->customer_id);
                    
                    Auth::login($user);
                    
                    session(['booking' => $booking, 'pre_payment' =>  $pre_payment, 'payment_method' =>  $payment_method, 'commission' => $commission, 'selected_attendees' => $selected_attendees, 'seats' => $seats]);
                
                    $flag['status'] = true;
                    $flag['transaction_id']      = $request->transaction_id;
                    $flag['payer_reference']     = $request->tx_ref;
                    $flag['message']             = $request->status;
                    
                    $this->booking_controller->flutterwaveCallback($flag);

                }

                if($request->status == 'cancelled')
                    return redirect()->route('stripe.fail');
            }
            
            return redirect()->route('stripe.success');
            
                
        }
        catch(\Throwable $th)
        {
            return redirect()->route('stripe.fail');
        }

    }
}