<?php

namespace App\Http\Controllers\Frontend;

use App\Constants\GlobalConst;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Admin\ParlourList;
use App\Http\Helpers\Response;
use Illuminate\Support\Facades\Validator;
use App\Models\ParlourBooking;
use Illuminate\Support\Facades\DB;
use App\Models\Admin\TransactionSetting;
use App\Models\Admin\ParlourListHasSchedule;
use Illuminate\Support\Str;
use Exception;
use App\Models\Admin\PaymentGatewayCurrency;
use App\Constants\PaymentGatewayConst;
use App\Providers\Admin\BasicSettingsProvider;
use App\Models\Transaction;
use App\Models\TemporaryData;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\RedirectResponse;
use App\Models\Admin\CryptoTransaction;
use App\Http\Helpers\PaymentGateway as PaymentGatewayHelper;
use App\Models\Admin\BasicSettings;
use App\Models\UserNotification;
use App\Notifications\EmailNotification;
use Illuminate\Support\Facades\Notification;
use App\Models\Admin\BookingTempData;
use App\Models\Admin\PaymentGateway;
use App\Models\Vendor\VendorWallet;
use App\Traits\PaymentGateway\PaystackGateway;
use net\authorize\api\contract\v1 as AnetAPI;
use net\authorize\api\controller as AnetController;
use App\Traits\PaymentGateway\Authorize;



class ParlourBookingController extends Controller
{

    use PaystackGateway, Authorize;
    /**
     * Method for show parlour booking page
     * @param $slug
     * @param \Illuminate\Http\Request $request
     */
    public function getService(BasicSettingsProvider $basic_settings, Request $request, $slug)
    {
        $page_title         = 'Make Appointment';
        $parlour            = ParlourList::with(['schedules', 'services','parlourImage'])->where('slug', $slug)->first();
        return view('frontend.pages.parlour-booking.index', compact(
            'page_title',
            'parlour',
        ));
    }
    /**
     * Method for get schedule for current schedule
     */
    public function getSchedule(Request $request)
    {
        $validator          = Validator::make($request->all(), [
            'selectedDate'  => 'required'
        ]);
        if ($validator->fails()) return Response::error($validator->errors()->all());
        $validated          = $validator->validate();
        $booking_data       = ParlourBooking::select('schedule_id', DB::raw('count(*) as total'))
            ->where('date', $validated['selectedDate'])
            ->groupBy('schedule_id')
            ->get();
        return Response::success(['Booking data fetch successfully.'], ['data' => $booking_data], 200);
    }

    /**
     * Method for store appointment booking information and passed it to preview page
     * @param \Illuminate\Http\Request $request
     */
    public function store(Request $request)
    {
        if (auth()->check() == false) return back()->with(['error' => ['Please Login First.']]);
        $charge_data            = TransactionSetting::where('slug', 'parlour')->where('status', 1)->first();
        $validator              = Validator::make($request->all(), [
            'parlour'           => 'required',
            'vendor_id'         => 'nullable',
            'price'             => 'required',
            'service'           => "required|array",
            'service.*'         => "required|string|max:255",
            'date'              => "required",
            'schedule'          => 'required',
            'message'           => "nullable"
        ]);
        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput($request->all());
        }
        $validated                  = $validator->validate();
        $validated['slug']          = Str::uuid();
        $slug                       = $validated['parlour'];
        $parlour                    = ParlourList::where('slug', $slug)->first();
        if (!$parlour) return back()->with(['error' => ['Salon Not Found!']]);

        $validated['user_id']       = auth()->user()->id;


        $validated['parlour_id']   = $parlour->id;

        $schedule = ParlourListHasSchedule::where('id', $validated['schedule'])->whereHas('parlour', function ($q) use ($parlour) {
            $q->where('id', $parlour->id);
        })->first();

        if (!$schedule) {
            return back()->with(['error' => ['Schedule Not Found!']]);
        }
        $validated['schedule_id']   = $validated['schedule'];

        $price                      = floatval($validated['price']);
        $fixed_charge               = floatval($charge_data->fixed_charge);
        $percent_charge             = floatval($charge_data->percent_charge);
        $total_percent_charge       = ($percent_charge / 100) * $price;
        $total_charge               = $fixed_charge + $total_percent_charge;
        $total_price                = $price + $total_charge;
        $validated['total_charge']  = $total_charge;
        $validated['price']         = $price;
        $validated['payable_price'] = $total_price;

        $already_appointed = ParlourBooking::where('parlour_id', $parlour->id)->where('schedule_id', $validated['schedule_id'])->where('date', $validated['date'])->count();

        if ($already_appointed >= $schedule->max_client) {
            return back()->with(['error' => ['Booking Limit is over!']]);
        }

        $next_appointment_no = $already_appointed + 1;

        // Add all data to the "data" column as JSON

        $validated['data'] = $validated;
        $validated['data']['serial_number'] = $next_appointment_no;
        $validated['user_id'] = $validated['user_id'];
        $validated['parlour_id'] = $validated['parlour_id'];
        $validated['schedule_id'] = $validated['schedule_id'];
        $validated['slug'] = $validated['slug'];
        $validated['identifier'] = Str::uuid();

        try {
            $booking = BookingTempData::create($validated);
        } catch (Exception $e) {
            return back()->with(['error' => ['Something went wrong! Please try again.']]);
        }
        return redirect()->route('frontend.parlour.booking.preview', $booking->data->slug);
    }

    /**
     * Method for show the preview page
     * @param $slug
     * @param \Illuminate\Http\Request $request
     */
    public function preview(Request $request, $slug)
    {
    
        $page_title         = "Appointment Preview";
        $booking            = BookingTempData::with(['parlour', 'schedule', 'payment_gateway'])->where('slug', $slug)->first();

        if (!$booking) {
            return redirect()->route('frontend.find.parlour')->with(['error' => ['Booking not found']]);
        }
        $payment_gateway   = PaymentGatewayCurrency::whereHas('gateway', function ($gateway) {
            $gateway->where('slug', PaymentGatewayConst::payment_method_slug());
            $gateway->where('status', 1);
        })->get();

        return view('frontend.pages.parlour-booking.preview', compact(
            'page_title',
            'booking',
            'payment_gateway',
        ));
    }
    /**
     * Method for confirm the booking
     * @param $slug
     * @param \Illuminate\Http\Request $request
     */
    public function confirm(Request $request, PaymentGatewayCurrency $gateway_currency, $slug)
    {
        $data        = BookingTempData::with(['payment_gateway', 'parlour', 'schedule', 'user'])->where('slug', $slug)->first();
        $otp_exp_sec = $data->booking_exp_seconds ?? global_const()::BOOKING_EXP_SEC;

        if ($data->created_at->addSeconds($otp_exp_sec) < now()) {
            $data->delete();
            return redirect()->route('frontend.find.parlour')->with(['error' => ['Booking Time Out!']]);
        }

        $validator  = Validator::make($request->all(), [
            'payment_method'    => 'required',
        ]);
        $validated  = $validator->validate();
        $from_time  = $data->schedule->from_time ?? '';

        $to_time    = $data->schedule->to_time ?? '';
        $user       = auth()->user();
        $basic_setting = BasicSettings::first();

        $vendor_wallet  = VendorWallet::where('vendor_id',$data->data->vendor_id)->first();
        $wallet_balance =$vendor_wallet->balance ?? '';

        if ($validated['payment_method'] == GlobalConst::CASH_PAYMENT) {
            if($data->data->vendor_id != null){
                if ($basic_setting->minimum_charge_count >= $wallet_balance) {
                    return redirect()->back()->with(['error' => ['Cash payment Not Available For This Parlour!']]);
                }
            }

            try {
                $trx_id = generateTrxString('parlour_bookings', 'trx_id', 'PB', 8);
                ParlourBooking::create([
                    'trx_id'            => $trx_id,
                    'parlour_id'        => $data->parlour_id,
                    'schedule_id'       => $data->schedule_id,
                    'vendor_id'         => $data->data->vendor_id,
                    'payment_method'    => GlobalConst::CASH_PAYMENT,
                    'date'              => $data->data->date,
                    'serial_number'     => $data->data->serial_number,
                    'slug'              => $data->slug,
                    'service'           => $data->data->service,
                    'type'              => GlobalConst::CASH_PAYMENT,
                    'user_id'           => $user->id,
                    'total_charge'      => $data->data->total_charge,
                    'price'             => $data->data->price,
                    'payable_price'     => $data->data->payable_price,
                    'remark'            => GlobalConst::CASH_PAYMENT,
                    'status'            => PaymentGatewayConst::STATUSPENDING,
                ]);
                UserNotification::create([
                    'user_id'        => auth()->user()->id,
                    'message'          => [
                        'title'     => "Your Booking",
                        'parlour'   => $data->parlour->name,
                        'date'      => $data->data->date,
                        'from_time' => $from_time,
                        'to_time'   => $to_time,
                        'serial_number' => $data->serial_number,
                        'success'       => "Successfully Booked."
                    ],
                ]);

                try {
                    $trx_id = generateTrxString('parlour_bookings', 'trx_id', 'PB', 8);
                    if ($basic_setting->email_notification == true) {
                        Notification::route("mail", $user->email)->notify(new EmailNotification($user, $data, $trx_id));
                    }
                } catch (Exception $e) {

                }
            } catch (Exception $e) {

                return back()->with(['error' => ['Something went wrong! Please try again.']]);
            }
            return redirect()->route('user.my.booking.index')->with(['success' => ['Congratulations! Salon Booking Confirmed Successfully.']]);
        } else {
            $validated = Validator::make($request->all(), [
                'amount'            => 'required|numeric|gt:0',
                'gateway_currency'  => 'required|string|exists:' . $gateway_currency->getTable() . ',alias',
            ])->validate();
            $request->merge([
                'currency' => $validated['gateway_currency'],
                'booking_data' => $data,
            ]);

            try {
                $instance = PaymentGatewayHelper::init($request->all())->type(PaymentGatewayConst::PAYMENTMETHOD)->setProjectCurrency(PaymentGatewayConst::PROJECT_CURRENCY_SINGLE)->gateway()->render();

            } catch (Exception $e) {
                return back()->with(['error' => [$e->getMessage()]]);
            }

            return $instance;
        }
    }

    public function success(Request $request, $gateway)
    {
        
        try {

            $token = PaymentGatewayHelper::getToken($request->all(), $gateway);
            $temp_data = TemporaryData::where("type", PaymentGatewayConst::PAYMENTMETHOD)->where("identifier", $token)->first();

            if (Transaction::where('callback_ref', $token)->exists()) {
                if (!$temp_data) return redirect()->route('user.my.booking.index')->with(['success' => ['Transaction request sended successfully!']]);;
            } else {
                if (!$temp_data) return redirect()->route('frontend.find.parlour')->with(['error' => ['Transaction failed. Record didn\'t saved properly. Please try again.']]);
            }

            $update_temp_data = json_decode(json_encode($temp_data->data), true);
            $update_temp_data['callback_data']  = $request->all();
            $temp_data->update([
                'data'  => $update_temp_data,
            ]);
            $temp_data = $temp_data->toArray();
            $instance = PaymentGatewayHelper::init($temp_data)->type(PaymentGatewayConst::PAYMENTMETHOD)->setProjectCurrency(PaymentGatewayConst::PROJECT_CURRENCY_SINGLE)->responseReceive();
            if ($instance instanceof RedirectResponse) return $instance;

            $slug = $temp_data['data']->booking_data->slug;
            $data        = BookingTempData::with(['payment_gateway', 'parlour', 'schedule', 'user'])->where('slug', $slug)->first();

            $from_time  = $data->schedule->from_time ?? '';

            $to_time    = $data->schedule->to_time ?? '';

            $basic_setting = BasicSettings::first();
            $user       = auth()->user();
            UserNotification::create([
                'user_id'  => auth()->user()->id,
                'message'  => [
                    'title' => "Your Booking",
                    'parlour'   => $data->parlour->name,
                    'date'      => $data->date,
                    'from_time' => $from_time,
                    'to_time'   => $to_time,
                    'serial_number' => $data->serial_number,
                    'success'       => "Successfully Booked."
                ],
            ]);

            if ($basic_setting->email_notification == true) {
                try {
                    $trx_id = generateTrxString('parlour_bookings', 'trx_id', 'PB', 8);
                    Notification::route("mail", $user->email)->notify(new EmailNotification($user, $data, $trx_id));
                } catch (Exception $e) {
                }
            }
            $data->delete();
        } catch (Exception $e) {
            dd($e);
            return back()->with(['error' => [$e->getMessage()]]);
        }

        return redirect()->route("user.my.booking.index")->with(['success' => ['Congratulations! Salon Booking Confirmed Successfully.']]);
    }

    public function cancel(Request $request, $gateway)
    {
        $token = PaymentGatewayHelper::getToken($request->all(), $gateway);
        if ($temp_data = TemporaryData::where("type", PaymentGatewayConst::PAYMENTMETHOD)->where("identifier", $token)->first()) {
            $temp_data->delete();
        }

        return redirect()->route('frontend.find.parlour');
    }

    public function postSuccess(Request $request, $gateway)
    {
        try {
            $token = PaymentGatewayHelper::getToken($request->all(), $gateway);
            $temp_data = TemporaryData::where("type", PaymentGatewayConst::PAYMENTMETHOD)->where("identifier", $token)->first();
            Auth::guard($temp_data->data->creator_guard)->loginUsingId($temp_data->data->creator_id);
        } catch (Exception $e) {
            return redirect()->route('frontend.index');
        }

        return $this->success($request, $gateway);
    }

    public function postCancel(Request $request, $gateway)
    {
        try {
            $token = PaymentGatewayHelper::getToken($request->all(), $gateway);
            $temp_data = TemporaryData::where("type", PaymentGatewayConst::PAYMENTMETHOD)->where("identifier", $token)->first();
            Auth::guard($temp_data->data->creator_guard)->loginUsingId($temp_data->data->creator_id);
        } catch (Exception $e) {
            return redirect()->route('frontend.index');
        }

        return $this->cancel($request, $gateway);
    }

    public function callback(Request $request, $gateway)
    {

        $callback_token = $request->get('token');
        $callback_data = $request->all();

        try {
            PaymentGatewayHelper::init([])->type(PaymentGatewayConst::PAYMENTMETHOD)->setProjectCurrency(PaymentGatewayConst::PROJECT_CURRENCY_SINGLE)->handleCallback($callback_token, $callback_data, $gateway);
        } catch (Exception $e) {
            // handle Error
            logger($e);
        }
    }



    public function cryptoPaymentAddress(Request $request, $trx_id)
    {

        $page_title = "Crypto Payment Address";
        $transaction = Transaction::where('trx_id', $trx_id)->firstOrFail();

        if ($transaction->gateway_currency->gateway->isCrypto() && $transaction->details?->payment_info?->receiver_address ?? false) {
            return view('user.sections.add-money.payment.crypto.address', compact(
                'transaction',
                'page_title',
            ));
        }

        return abort(404);
    }

    public function cryptoPaymentConfirm(Request $request, $trx_id)
    {
        $transaction = Transaction::where('trx_id', $trx_id)->where('status', PaymentGatewayConst::STATUSWAITING)->firstOrFail();

        $dy_input_fields = $transaction->details->payment_info->requirements ?? [];
        $validation_rules = $this->generateValidationRules($dy_input_fields);

        $validated = [];
        if (count($validation_rules) > 0) {
            $validated = Validator::make($request->all(), $validation_rules)->validate();
        }

        if (!isset($validated['txn_hash'])) return back()->with(['error' => ['Transaction hash is required for verify']]);

        $receiver_address = $transaction->details->payment_info->receiver_address ?? "";

        // check hash is valid or not
        $crypto_transaction = CryptoTransaction::where('txn_hash', $validated['txn_hash'])
            ->where('receiver_address', $receiver_address)
            ->where('asset', $transaction->gateway_currency->currency_code)
            ->where(function ($query) {
                return $query->where('transaction_type', "Native")
                    ->orWhere('transaction_type', "native");
            })
            ->where('status', PaymentGatewayConst::NOT_USED)
            ->first();

        if (!$crypto_transaction) return back()->with(['error' => ['Transaction hash is not valid! Please input a valid hash']]);

        if ($crypto_transaction->amount >= $transaction->total_payable == false) {
            if (!$crypto_transaction) return back()->with(['error' => ['Insufficient amount added. Please contact with system administrator']]);
        }

        DB::beginTransaction();
        try {

            // Update user wallet balance
            DB::table($transaction->creator_wallet->getTable())
                ->where('id', $transaction->creator_wallet->id)
                ->increment('balance', $transaction->receive_amount);

            // update crypto transaction as used
            DB::table($crypto_transaction->getTable())->where('id', $crypto_transaction->id)->update([
                'status'        => PaymentGatewayConst::USED,
            ]);

            // update transaction status
            $transaction_details = json_decode(json_encode($transaction->details), true);
            $transaction_details['payment_info']['txn_hash'] = $validated['txn_hash'];

            DB::table($transaction->getTable())->where('id', $transaction->id)->update([
                'details'       => json_encode($transaction_details),
                'status'        => PaymentGatewayConst::STATUSSUCCESS,
            ]);

            DB::commit();
        } catch (Exception $e) {
            DB::rollback();
            return back()->with(['error' => ['Something went wrong! Please try again']]);
        }

        return back()->with(['success' => ['Payment Confirmation Success!']]);
    }

    public function redirectUsingHTMLForm(Request $request, $gateway)
    {
        $temp_data = TemporaryData::where('identifier', $request->token)->first();
        if (!$temp_data || $temp_data->data->action_type != PaymentGatewayConst::REDIRECT_USING_HTML_FORM) return back()->with(['error' => ['Request token is invalid!']]);
        $redirect_form_data = $temp_data->data->redirect_form_data;
        $action_url         = $temp_data->data->action_url;
        $form_method        = $temp_data->data->form_method;

        return view('payment-gateway.redirect-form', compact('redirect_form_data', 'action_url', 'form_method'));
    }

    /**
     * Redirect Users for collecting payment via Button Pay (JS Checkout)
     */
    public function redirectBtnPay(Request $request, $gateway)
    {
        try {
            return PaymentGatewayHelper::init([])->setProjectCurrency(PaymentGatewayConst::PROJECT_CURRENCY_SINGLE)->handleBtnPay($gateway, $request->all());

        } catch (Exception $e) {
            return redirect()->route('user.dashboard')->with(['error' => [$e->getMessage()]]);
        }
    }

      /**
     * Method for paystack pay callback
     */
    public function paystackPayCallBack(Request $request){
        $instance = $this->paystackSuccess($request->all());
        return redirect()->route("user.my.booking.index")->with(['success' => ['Congratulations! Salon Booking Confirmed Successfully.']]);
    }

         /**
     * Method for view authorize card view page
     * @param Illuminate\Http\Request $request,$identifier
     */
    public function authorizeCardInfo(Request $request,$identifier){
        $page_title         = __("Authorize card Information");
        $temp_data          = TemporaryData::where('identifier',$identifier)->first();

        return view('frontend.parlour-booking.automatic.authorize',compact(
            'page_title',
            'temp_data'
        ));
    }
  /**
     * Method function authorize payment submit
     * @param Illuminate\Http\Request $request, $identifier
     */
    public function authorizePaymentSubmit(Request $request,$identifier){

        $temp_data          = TemporaryData::where('identifier',$identifier)->first();
        if(!$temp_data) return back()->with(['error' => ['Sorry ! Data not found.']]);

        $validator          = Validator::make($request->all(),[
            'card_number'   => 'required',
            'date'          => 'required',
            'code'          => 'required'
        ]);

        if($validator->fails()) return back()->withErrors($validator)->withInput($request->all());
        $validated          = $validator->validate();


        $request->merge([
            'token' => $identifier
        ]);

        $request_data = $request->all();



        $gateway_credentials          = $this->authorizeCredentials($temp_data);

        $basic_settings               = BasicSettings::first();

        $validated['card_number']     = str_replace(' ', '', $validated['card_number']);

        $convert_date   = explode('/', $validated['date']);
        $month          = $convert_date[1];
        $year           = $convert_date[0];

        $current_year   = substr(date('Y'), 0, 2);
        $full_year      = $current_year . $year;

        $validated['date'] = $full_year . '-' . $month;

        $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
        $merchantAuthentication->setName($gateway_credentials->app_login_id);
        $merchantAuthentication->setTransactionKey($gateway_credentials->transaction_key);
        $amount = $temp_data->data->amount->total_payable_amount;


        // Set the transaction's refId
        $refId = 'ref' . time();

        // Create the payment data for a credit card
        $creditCard = new AnetAPI\CreditCardType();

        $creditCard->setCardNumber($validated['card_number']);
        $creditCard->setExpirationDate($validated['date']);
        $creditCard->setCardCode($validated['code']);


        // Add the payment data to a paymentType object
        $paymentOne = new AnetAPI\PaymentType();
        $paymentOne->setCreditCard($creditCard);

        $generate_invoice_number        = generate_random_string_number(10) . time();

        // Create order information
        $order = new AnetAPI\OrderType();
        $order->setInvoiceNumber($generate_invoice_number);
        $order->setDescription("Transfer Money");

        // Set the customer's Bill To address
        $customerAddress = new AnetAPI\CustomerAddressType();
        $customerAddress->setFirstName(auth()->user()->firstname ?? '');
        $customerAddress->setLastName(auth()->user()->lastname ?? '');
        $customerAddress->setCompany($basic_settings->site_name ?? '');
        $customerAddress->setAddress(auth()->user()->address->address ?? '');
        $customerAddress->setCity(auth()->user()->address->city ?? '');
        $customerAddress->setState(auth()->user()->address->state ?? '');
        $customerAddress->setZip(auth()->user()->address->zip ?? '');
        $customerAddress->setCountry(auth()->user()->address->country ?? '');


        $make_customer_id       = auth()->user()->id . $gateway_credentials->code;
        // Set the customer's identifying information
        $customerData = new AnetAPI\CustomerDataType();
        $customerData->setType("individual");
        $customerData->setId($make_customer_id);
        $customerData->setEmail(auth()->user()->email);

        // Add values for transaction settings
        $duplicateWindowSetting = new AnetAPI\SettingType();
        $duplicateWindowSetting->setSettingName("duplicateWindow");
        $duplicateWindowSetting->setSettingValue("60");


        // Create a TransactionRequestType object and add the previous objects to it
        $transactionRequestType = new AnetAPI\TransactionRequestType();
        $transactionRequestType->setTransactionType("authCaptureTransaction");
        $transactionRequestType->setAmount($amount);
        $transactionRequestType->setOrder($order);
        $transactionRequestType->setPayment($paymentOne);
        $transactionRequestType->setBillTo($customerAddress);
        $transactionRequestType->setCustomer($customerData);
        $transactionRequestType->addToTransactionSettings($duplicateWindowSetting);


        // Assemble the complete transaction request
        $request = new AnetAPI\CreateTransactionRequest();
        $request->setMerchantAuthentication($merchantAuthentication);
        $request->setRefId($refId);
        $request->setTransactionRequest($transactionRequestType);



        // Create the controller and get the response
        $controller = new AnetController\CreateTransactionController($request);

        if($gateway_credentials->mode == GlobalConst::ENV_SANDBOX){
            $environment = \net\authorize\api\constants\ANetEnvironment::SANDBOX;
            
        }else{
            $environment = \net\authorize\api\constants\ANetEnvironment::PRODUCTION;
        }
        $response   = $controller->executeWithApiResponse($environment);
      
        if ($response != null) {
            // Check to see if the API request was successfully received and acted upon
            if ($response->getMessages()->getResultCode() == "Ok") {
                // Since the API request was successful, look for a transaction response
                // and parse it to display the results of authorizing the card
                $tresponse = $response->getTransactionResponse();

                if ($tresponse != null && $tresponse->getMessages() != null) {
                    $request_data = new Request($request_data);
                    return $this->success($request_data, PaymentGatewayConst::AUTHORIZE);
                }else {
                    return back()->with(['error' => ['Transaction Failed']]);
                    if ($tresponse->getErrors() != null) {
                        return back()->with(['error' => [$tresponse->getErrors()[0]->getErrorText()]]);
                    }
                }
            }else {
                return back()->with(['error' => ['Transaction Failed']]);
                $tresponse = $response->getTransactionResponse();

                if ($tresponse != null && $tresponse->getErrors() != null) {
                    return back()->with(['error' => [$tresponse->getErrors()[0]->getErrorText()]]);
                } else {
                    return back()->with(['error' => [$response->getMessages()->getMessage()[0]->getText()]]);
                }
            }
        }else {
            return redirect()->back()->with(['error' => ['No response returned']]);
        }


    }

    // For get the gateway credentials
    
    

    
}
