• File: PaymentController.php
  • Full Path: /var/www/imaliapi/app/Http/Controllers/PaymentController.php
  • Date Modified: 12/15/2025 5:21 PM
  • File size: 321.78 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App\Http\Controllers;

use App\AllTransaction;
use App\Bank\HistoryPayment;
use App\Bank\MasterAccount;
use App\Bank\Payment;
use App\Bank\Profit;
use App\BeginSolicitation;
use App\Classes\Auth as ClassesAuth;
use App\Classes\Kyc;
use App\Classes\FCMNotifcation;
use App\Classes\ImageUploader;
use App\Classes\PaymentKyc;
use App\Classes\PushNotification;
use App\Classes\Record;
use App\Classes\SendResponse;
use App\Classes\SendSMS;
use App\Classes\SendSMSSislog;
use App\Classes\SmsManager;
use App\Classes\StoreKyc;
use App\Classes\TransactionGeneration;
use App\Classes\UserKyc;
use App\Http\Controllers\Api\Auth\LoginController;
use App\Imali\BusinessAccount;
use App\Imali\ImaliAccount;
use App\Imali\ImaliAccountConfig;
use App\Imali\MerchantAccount;
use App\Imali\MerchantContract;
use App\Imali\RamoActivity;
use App\Imali\RechargeImaliAccount;
use App\Imali\Transfer;
use App\Mail\Pagamento;
use App\Mail\PagamentoConfirmado;
use App\MoneyRequest;
use App\PrepaidCardDeposit;
use App\PurchaseVoucher;
use App\Store;
use Google\Client as GoogleClient;
use App\StoreAmountGeneration;
use App\StoreConfig;
use App\StoreDevice;
use App\SubAccountType;
use App\TransactionHistory;
use App\TransferHistory;
use App\User;
use App\WithdrawalsRequest;
use Illuminate\Http\Request;
//use DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use QRCode;
use App\ImaliTariff;
use App\Link;
use App\PaymentRequest;
use App\PaymentType;
use App\PushPaymentRequest;
use App\Qrcode as AppQrcode;
use App\UserClient;
use DateTime;

class PaymentController extends Controller
{
    protected $request;
    protected $createTransaction;
    protected $generatedTransaction;
    protected $log;
    protected $trasactionGeneration;

    protected SmsManager $smsManager;


    public function __construct()
    {
        $this->log = new Record();
        $this->trasactionGeneration = new TransactionGeneration();

        $this->smsManager = new SmsManager();
    }

    public function getExtrato()
    {

        $user = User::query()
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
            ->leftJoin('credelecs', 'credelecs.user_id', '=', 'users.id')
            ->leftJoin('payments', 'payments.sender_id', '=', 'users.id')
            ->where('users.id', 1)
            ->select('credelecs.*', 'payments.*')
            ->get();

        return response()->json($user);
    }

    public function getTesteTransaction($id)
    {
        $u = Payment::query()->where('sender_id', '=', 1)->get();
        $transactons = DB::table('payments')
            ->join('history_payments', 'history_payments.user_id', '=', 'payments.sender_id')
            ->where('payments.sender_id', $id)
            ->where('history_payments.user_id', $id)
            ->select('payments.*', 'history_payments.status_user as type')
            ->orderBy('payments.created_at', 'desc')
            ->get();

        return response()->json($transactons);
    }

    public function getUser($id)
    {
        $user = User::query()->where('user_id', $id)->first();
        return response()->json($user);
    }

    public function getMyTransactions($id)
    {

        //        $user = User::query()->where('user_id', $id)->first();
        $transactons = DB::table('users')
            ->join('payments', 'users.id', '=', 'payments.sender_id')
            ->where('user_id', $id)
            ->select('payments.*')
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json(['data' => $transactons], 200, [], JSON_NUMERIC_CHECK);
    }

    public function makePayment(Request $request)
    {
        $trasactionGeneration = new TransactionGeneration();

        $payerUser = User::query()->where('user_id', $request->user_id)->first();
        $comerciante = MerchantAccount::query()->where('account_number', $request->account_number)->first();
        $payer_id = $payerUser->id;

        $imali = ImaliAccount::query()->where('user_id', $payer_id)->first();
        $kyc = new Kyc();
        $kycCheck = $kyc->checkSenderPayment($request);

        if ($kycCheck) {

            $log = new Record();
            $log->createLog([
                'description' => $imali->account_number . ' ' . $comerciante->name,
                'details' => $kycCheck,
                'operation' => 'Payment',
                //                'properties' => $request->all(),
                'properties' => json_encode($request->except(['pin'])),
                'status' => 'Error',
                'user_id' => $request->user()->id
            ]);

            return $kycCheck;
        } else {
            if ($payerUser) {
                if ($imali->balance < $request->amount) {

                    $log = new Record();
                    $log->createLog([
                        'description' => $imali->account_number . ' ' . $comerciante->name,
                        'details' => 'Saldo Insuficiente',
                        'operation' => 'Payment',
                        //                        'properties' => $request->all(),
                        'properties' => json_encode($request->except(['pin'])),
                        'status' => 'Error',
                        'user_id' => $request->user()->id
                    ]);

                    return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402, [], JSON_NUMERIC_CHECK);
                } else {
                    $valorAPagar = $request->amount;
                    $points = round($valorAPagar);

                    // Payer or Sender Section
                    DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
                    DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

                    $contractoComerciante = MerchantContract::query()->where('merchant_account_id', $comerciante->id)->first();

                    $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                    $valorMin = $contractoComerciante->valor_min;
                    $valorMax = $contractoComerciante->valor_max;

                    if ($taxaDesconto < $valorMin) {
                        $taxaDesconto = $valorMin;
                    }
                    if ($taxaDesconto > $valorMax) {
                        $taxaDesconto = $valorMax;
                    }

                    //                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                    $valorFinal = $valorAPagar - $taxaDesconto;

                    // Recever User Merchante
                    DB::table('merchant_accounts')->where('account_number', $comerciante->account_number)->increment('balance', $valorFinal);

                    //                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

                    $transaction = $trasactionGeneration->generateTransaction();

                    $createTransaction = Payment::create([
                        'transaction_id' => $transaction,
                        'sender_id' => $payer_id,
                        'merchant_account_id' => $comerciante->id,
                        'received_points' => $points,
                        'amount' => $valorAPagar,
                        'amount_credited' => $valorFinal,
                        'comissao' => $taxaDesconto,
                        'description' => $request->description,
                        'used_points' => $request->used_points,
                        'estado' => 'pago',
                        'estado_color' => '#388E3C',
                        'created_at' => now(),
                        'updated_at' => now()
                    ]);

                    $actualPoints = $imali->points + $points;
                    $createTransaction->paymentHistoric()->create([
                        'sender_account' => $imali->account_number,
                        'sender_name' => $payerUser->name,
                        'amount_credited' => $valorFinal,
                        'status_user' => 'sender',
                        'status' => 'done',
                        'comissao' => $taxaDesconto,
                        'amount' => $valorAPagar,
                        'user_id' => $payerUser->id,
                        'actual_points' => $actualPoints,
                        'last_points' => $imali->points,
                        'win_points' => $points,
                        'transaction_id' => $transaction
                    ]);

                    $saveProfit = $createTransaction->profit()->create([
                        'payer_id' => $payer_id,
                        'payer_account' => $comerciante->account_number,
                        'amount' => $valorAPagar,
                        'amount_credited' => $valorFinal,
                        'comissao' => $taxaDesconto,
                        'profit_id' => $trasactionGeneration->generateTransaction(),
                        'payment_id' => $createTransaction->id,
                    ]);
                    if ($saveProfit) {

                        $sms = new SendSMS();
                        $sms->sendMessageToClientePayment($createTransaction);
                        $sms->sendMessageToComerciante($createTransaction);
                        //                    $sms->sendMessageToClientePayment($payerUser);
                        Mail::to($comerciante->email_loja)->send(new PagamentoConfirmado($createTransaction));
                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));

                        $log = new Record();
                        $log->createLog([
                            'description' => $imali->account_number . ' ' . $comerciante->name,
                            'details' => 'Pagamento Feito com Sucesso',
                            'operation' => 'Payment',
                            //                            'properties' => $request->all(),
                            'properties' => json_encode($request->except(['pin'])),
                            'status' => 'Success',
                            'user_id' => $request->user()->id
                        ]);

                        return response()->json([
                            'message' => 'Pagamento Feito com Sucesso!',
                            'transaction' => $transaction,
                            'created_at' => $createTransaction->created_at,
                            'duration' => 3000
                        ], 200);
                    }
                }
            }
        }
    }

    public function makePaymentStoreNEW(Request $request)
    {

        DB::transaction(function ($request) {
            $user = User::find($request->user()->id);
            //            $user = DB::table('users')->
            if (Hash::check($request->pin, $user->pin)) {
                $trasactionGeneration = new TransactionGeneration();

                $payerUser = User::query()->where('user_id', $request->user()->user_id)->first();
                $store = Store::query()->where('account_number', $request->account_number)->first();
                $payer_id = $payerUser->id;

                $imali = ImaliAccount::query()->where('user_id', $payer_id)->first();
                $kyc = new Kyc();
                $kycCheck = $kyc->checkSenderPayment($request);

                if ($kycCheck) {
                    $log = new Record();
                    $log->createLog([
                        'description' => $imali->account_number . ' ' . $store->name,
                        'details' => $kycCheck,
                        'operation' => 'Payment',
                        //                        'properties' => $request->all(),
                        'properties' => json_encode($request->except(['pin'])),
                        'status' => 'Error',
                        'user_id' => $request->user()->id
                    ]);

                    return $kycCheck;
                } else {
                    if ($payerUser) {
                        if ($imali->balance < $request->amount) {

                            $log = new Record();
                            $log->createLog([
                                'description' => $imali->account_number . ' ' . $store->name,
                                'details' => 'Saldo Insuficiente',
                                'operation' => 'Payment',
                                //                                'properties' => $request->all(),
                                'properties' => json_encode($request->except(['pin'])),
                                'status' => 'Error',
                                'user_id' => $request->user()->id
                            ]);

                            return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402, [], JSON_NUMERIC_CHECK);
                        } else {
                            $valorAPagar = $request->amount;
                            $points = round($valorAPagar);

                            // Payer or Sender Section
                            DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
                            DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

                            $contractoComerciante = MerchantContract::query()->where('store_id', $store->id)->first();

                            $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                            $valorMin = $contractoComerciante->min_amount;
                            $valorMax = $contractoComerciante->max_amount;

                            if ($taxaDesconto < $valorMin) {
                                $taxaDesconto = $valorMin;
                            }
                            if ($taxaDesconto > $valorMax) {
                                $taxaDesconto = $valorMax;
                            }

                            //                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                            $valorFinal = $valorAPagar - $taxaDesconto;

                            // Recever User Merchante
                            DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);
                            $storeT = Store::query()->where('account_number', $store->account_number)->first();
                            DB::table('merchant_accounts')->where('id', $storeT->merchant_account_id)->increment('balance', $valorFinal);

                            //                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

                            $transaction = $trasactionGeneration->generateTransaction();

                            $createTransaction = Payment::create([
                                'transaction_id' => $transaction,
                                'sender_id' => $payer_id,
                                'store_id' => $store->id,
                                'client_id' => $request->user_client_id,
                                'received_points' => $points,
                                'amount' => $valorAPagar,
                                'amount_credited' => $valorFinal,
                                'comissao' => $taxaDesconto,
                                'description' => $request->description,
                                'used_points' => $request->used_points,
                                'estado' => 'pago',
                                'payment_type' => 'payment',
                                'estado_color' => '#388E3C',
                                'created_at' => now(),
                                'updated_at' => now(),
                                'category_id' => $store->industry_activity
                            ]);

                            //                        TransactionHistory::create([
                            //                            'user_id' => $request->user()->id,
                            //                            'payment_id' => $createTransaction->id,
                            //                            'category_id' => $createTransaction->category_id,
                            //                            'transaction_type' => 'payment'
                            //                        ]);


                            $actualPoints = $imali->points + $points;
                            $re = $createTransaction->paymentHistoric()->create([
                                'sender_account' => $imali->account_number,
                                'sender_name' => $payerUser->name,
                                'amount_credited' => $valorFinal,
                                'status_user' => 'sender',
                                'status' => 'done',
                                'comissao' => $taxaDesconto,
                                'amount' => $valorAPagar,
                                'user_id' => $payerUser->id,
                                'actual_points' => $actualPoints,
                                'last_points' => $imali->points,
                                'win_points' => $points,
                                'transaction_id' => $transaction,
                                'category_id' => $store->industry_activity
                            ]);


                            $saveProfit = $createTransaction->profit()->create([
                                'payer_id' => $payer_id,
                                'payer_account' => $store->account_number,
                                'amount' => $valorAPagar,
                                'amount_credited' => $valorFinal,
                                'comissao' => $taxaDesconto,
                                'profit_id' => $trasactionGeneration->generateTransaction(),
                                'payment_id' => $createTransaction->id,
                                'profit_payer_id' => $createTransaction->store_id
                            ]);
                            if ($saveProfit) {

                                $this->smsManager->sendSMSToComerciante($createTransaction);
                                //                        $sms = new SendSMS();
                                //                        $sms->sendMessageToClientePayment($createTransaction);
                                //                        $sms->sendMessageToComerciante($createTransaction);
                                //                        $sms->sendMessageToClientePayment($payerUser);
                                //                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
                                //                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));


                                $generate = StoreAmountGeneration::query()
                                    ->where('id', $request->store_amount_generation_id)
                                    ->first();

                                if ($generate) {

                                    $generate->update([
                                        'status' => 'sucesso'
                                    ]);
                                }


                                $log = new Record();
                                $log->createLog([
                                    'description' => $imali->account_number . ' ' . $store->name,
                                    'details' => 'Pagamento Feito com Sucesso',
                                    'operation' => 'Payment',
                                    //                                    'properties' => $request->all(),
                                    'properties' => json_encode($request->except(['pin'])),
                                    'status' => 'Success',
                                    'user_id' => $request->user()->id
                                ]);

                                $notification = array(
                                    'icon' => 'ic_imali_logo_verde_01',
                                    //                            'icon' => 'ic_i_mali_cover',
                                    'title' => 'Pagemento ' . $request->amount . ' MT',
                                    'body' => 'Parabéns, ' . ' fez o pagamento de ' . $request->amount . ' MT ' . ' na loja ' . $store->name,
                                    'click_action' => 'com.imali.payapp.payment_PAGAR_NOTIFICATION',
                                    //                            'color' => '#008577'
                                    'color' => '#ffffff'
                                );


                                $data = array(
                                    'transaction' => $createTransaction->transaction_id,
                                    'loja' => $store->name,
                                    'loja_account' => $store->account_number,
                                    'pontos' => $createTransaction->received_points,
                                    'pontos_usados' => $createTransaction->used_points,
                                    'amount' => $createTransaction->amount,
                                    'amount_debited' => $createTransaction->amount_credited,
                                    'account_number' => $imali->account_number,
                                    'phone' => $request->user()->phone,
                                    'descricao' => $createTransaction->description,
                                    'data' => $createTransaction->created_at,
                                    'estado' => $createTransaction->estado,
                                    'comissao' => $createTransaction->comissao,
                                    'route' => 'PAGAR_NOTIFICATION',
                                    'terminal' => 'firebase'
                                );

                                $this->pushNotifification($user->firebase_token, $notification, $data);

                                return response()->json([
                                    'message' => 'Pagamento Feito com Sucesso!',
                                    'transaction' => $transaction,
                                    'created_at' => $createTransaction->created_at,
                                    'duration' => 3000
                                ], 200);
                            }
                        }
                    }
                }
            } else {
                return response()->json(['message' => 'Pin Incorrecto'], 400);
            }
        });
    }


    private function checkExpiredLink($push)
    {
        if ($push) {
            $expirationDate = (int)strtotime($push->expiration_datetime);
            $todayDate = (int)strtotime(date('Y-m-d H:i:s'));
            $remaningtime =  $todayDate > $expirationDate;
            if ($remaningtime && ($push->status == 'PENDING')) {
                $push->status = 'EXPIRED';
                $push->update();
            }
        }
    }


    // PAGAMENTO PARA KRB -- 15 / 05 / 2024
    // TODO -- 15-Setembro-2024
    public function makePaymentStoreAppKRB2024(Request $request)
    {
        /**
         * adicionar variavel 
         * @payment_type : PAYMENT_STORE -- para fazer pagamento na loja
         * @payment_type : PAYMENT_NFC_CARD -- para fazer pagamento na Escola Americana
         * @payment_type : PAYMENT_BNPL -- para fazer pagamento/deposito na KRB
         */
        $this->validate($request, [
            'payer_account_number' => 'required|numeric',
            'payment_type' => 'required|in:PAYMENT_STORE,PAYMENT_NFC_CARD,PAYMENT_QRCODE,PAYMENT_LINK,PAYMENT_PUSH',
            'amount' => 'required|numeric|min:1',
        ], [
            'payer_account_number.required' => 'O numero da conta e obrigatorio',
            'payer_account_number.numeric' => 'O numero da conta deve ser numerico',
            'payment_type.required' => 'O tipo de pagamento e obrigatorio',
            'payment_type.in' => 'O tipo de pagamento deve ter um tipo valido: PAYMENT_STORE, PAYMENT_NFC_CARD,PAYMENT_QRCODE,PAYMENT_LINK,PAYMENT_PUSH',

            'amount.required' => 'O montante e obrigatorio',
            'amount.numeric' => 'O montante deve ser numerico',
            'amount.min' => 'O montante tem que ser maior que zero (0)',
        ]);

        $generated_payment = Payment::query()->where('transaction_id', $request->transaction)->first();

        if ($generated_payment && $generated_payment->status === 'success') return SendResponse::errorResp400('Este pagamento já foi efetuado.', 'This payment has already been paid.'); // LINHA A SER ANALISADA..
        if ($generated_payment && $generated_payment->status === 'expired') return SendResponse::errorResp400('Este pagamento está expirado.', 'This payment is expided'); // LINHA A SER ANALISADA..
        if ($generated_payment && $generated_payment->status === 'rejected') return SendResponse::errorResp400('Este pagamento foi rejeitado.', 'This payment was rejected.'); // LINHA A SER ANALISADA..


        // $generated_push_payment = PushPaymentRequest::query()->where('push_id', $request->transaction)->first();
        $generated_push_payment = PaymentRequest::query()->where('transaction_id', $request->transaction)->first();

        Log::info('TRANSACAO DE RETORNO', ['TRANSACAO DE RETORNO' => $generated_push_payment]);


        $generated_qrcode_payment = AppQrcode::query()->where('qrcode_id', $request->transaction)->first();

        // Buscar a loja onde se fara o pagamento
        $store_account = Store::getStoreAccount($generated_push_payment->store_account_number ?? $request->store_account_number);
        if (!$store_account) return SendResponse::errorResp404notfound(
            'Conta da loja não encontrada',
            'StoreAccount Not Found',
        );

        $store_account_old = Store::getStoreAccount($generated_push_payment->store_account_number ?? $request->store_account_number);
        $store_contract = Store::getStoreContractsAndConfigs($store_account->account_number);

        $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
        if (!$business) return SendResponse::errorResp404notfound(
            'Conta da loja não associada a conta Empresa',
            'Store account not associated with Company account',
        );

        // todo ----- PUSH
        if ($generated_push_payment && ($generated_push_payment->payment_methods_id != 1)) {

            Log::info('ENTROU NO GENERATED PUSH ✅🌿', ['ENTROU NO GENERATED PUSH ✅🌿' => $generated_push_payment]);

            $this->checkExpiredLink($generated_push_payment);

            if ($generated_push_payment->status === 'SUCCESS') return SendResponse::errorResp400('Este push já foi pago.', 'This push has already been paid.'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este push está expirado.', 'This push is expided'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'REJECTED') return SendResponse::errorResp400('Este push foi rejeitado.', 'This push was rejected.'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'FAILED') return SendResponse::errorResp400('Este push falhou', 'This Push failed'); // LINHA A SER ANALISADA..

            try {
                //code...
                DB::beginTransaction();

                // retirar o valor a pagar do saldo do User que esta a pagar
                // $accountPayer->balance -= $request->amount;
                // $accountPayer->update();

                // Calculos para efectuar pagamento
                $imali_commission = $request->amount * ($store_contract->taxa) / 100;
                $points = round($request->amount);

                $store_account->balance += ($request->amount - $imali_commission);
                $store_account->update();

                // adicionar o valor retirado na conta do accountPayer no balance da Loja
                $business->balance += ($request->amount - $imali_commission);
                $business->update();

                $created_payment = $this->create_payment_store_wallets_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_push_payment);

                DB::commit();

                Log::info('Outgoing response', [
                    'content' => [
                        'message' => trans('payment_done'),
                        'transaction' => $created_payment->transaction_id,
                        'created_at' => $created_payment->created_at
                    ],
                ]);
            } catch (\Throwable $th) {

                DB::rollBack();

                Log::info('Error response', [
                    'content' => [
                        'message' => 'Falha no pagamento',
                        'data' => $th->getMessage(),
                    ],
                ]);

                // Escrever no ficheiro de log as mensagens de erro.
                return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
                //throw $th;
            }

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        }
        // todo ----- PUSH

        // todo rever PUSH IMALI....

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;


        // Contas a Pagar
        $accountPayer = User::getAccount($request->payer_account_number);
        if (!$accountPayer) return SendResponse::errorResp404notfound(
            'Conta não encontrada',
            'Account Not Found',
        );

        $accountPayerOld = User::getAccount($request->payer_account_number);
        $userPayer = User::getUserDetails($accountPayer->user_id);

        // ----------------------------------------------------
        if (User::is_subAccount($request->payer_account_number)) $userPayer = User::getUserDetails($accountPayer->user_id, $accountPayer->account_id);
        // ----------------------------------------------------

        // Validar KYC do userPayer
        $kyc = new UserKyc($userPayer);
        $kycResp = $kyc->checkSenderKYC($request->amount);
        if ($kycResp->getStatusCode() != 200) return $kycResp;

        // Validacao do saldo do User
        $kycRespBalance = $kyc->checkUserBalance($request->amount);
        if ($kycRespBalance->getStatusCode() != 200) return $kycRespBalance;


        // todo ----- QRCODE
        if ($generated_qrcode_payment) {

            $this->checkExpiredLink($generated_qrcode_payment);

            if ($generated_qrcode_payment && $generated_qrcode_payment->status === 'USED') return SendResponse::errorResp400('Este QRcode já foi pago.', 'This QRcode has already been paid.'); // LINHA A SER ANALISADA..
            if ($generated_qrcode_payment && $generated_qrcode_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este QRcode está expirado.', 'This QRcode is expided'); // LINHA A SER ANALISADA..
            if ($generated_qrcode_payment && $generated_qrcode_payment->status === 'INACTIVE') return SendResponse::errorResp400('Este QRcode está inactivo.', 'This QRcode is inactive.'); // LINHA A SER ANALISADA..

            try {
                //code...
                DB::beginTransaction();

                // retirar o valor a pagar do saldo do User que esta a pagar
                // $accountPayer->balance -= $request->amount;
                // $accountPayer->update();

                // Calculos para efectuar pagamento
                $imali_commission = $request->amount * ($store_contract->taxa) / 100;
                $points = round($request->amount);

                $store_account->balance += ($request->amount - $imali_commission);
                $store_account->update();

                // adicionar o valor retirado na conta do accountPayer no balance da Loja
                $business->balance += ($request->amount - $imali_commission);
                $business->update();

                $created_payment = $this->create_payment_store_qrcode_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_qrcode_payment, $accountPayer);

                DB::commit();

                Log::info('Outgoing response', [
                    'content' => [
                        'message' => trans('payment_done'),
                        'transaction' => $created_payment->transaction_id,
                        'created_at' => $created_payment->created_at
                    ],
                ]);
            } catch (\Throwable $th) {

                DB::rollBack();

                Log::info('Error response', [
                    'content' => [
                        'message' => 'Falha no pagamento',
                        'data' => $th->getMessage(),
                    ],
                ]);

                // Escrever no ficheiro de log as mensagens de erro.
                return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
                //throw $th;
            }

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        }
        // todo ----- QRCODE


        if ($generated_push_payment && ($generated_push_payment->payment_methods_id == 1)) {

            Log::info('ENTROU NO GENERATED PUSH ✅🌿', ['ENTROU NO GENERATED PUSH ✅🌿' => $generated_push_payment]);

            $this->checkExpiredLink($generated_push_payment);

            if ($generated_push_payment->status === 'SUCCESS') return SendResponse::errorResp400('Este push já foi pago.', 'This push has already been paid.'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este push está expirado.', 'This push is expided'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'REJECTED') return SendResponse::errorResp400('Este push foi rejeitado.', 'This push was rejected.'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'FAILED') return SendResponse::errorResp400('Este push falhou', 'This Push failed'); // LINHA A SER ANALISADA..

            try {
                //code...
                DB::beginTransaction();

                // retirar o valor a pagar do saldo do User que esta a pagar
                $accountPayer->balance -= $request->amount;
                $accountPayer->update();

                // Calculos para efectuar pagamento
                $imali_commission = $request->amount * ($store_contract->taxa) / 100;
                $points = round($request->amount);

                $store_account->balance += ($request->amount - $imali_commission);
                $store_account->update();

                // adicionar o valor retirado na conta do accountPayer no balance da Loja
                $business->balance += ($request->amount - $imali_commission);
                $business->update();

                $created_payment = $this->create_payment_store_wallets_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_push_payment, $userPayer, $accountPayer, $accountPayerOld);

                DB::commit();

                Log::info('Outgoing response', [
                    'content' => [
                        'message' => trans('payment_done'),
                        'transaction' => $created_payment->transaction_id,
                        'created_at' => $created_payment->created_at
                    ],
                ]);
            } catch (\Throwable $th) {

                DB::rollBack();

                Log::info('Error response', [
                    'content' => [
                        'message' => 'Falha no pagamento',
                        'data' => $th->getMessage(),
                    ],
                ]);

                // Escrever no ficheiro de log as mensagens de erro.
                return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
                //throw $th;
            }

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        }

        // todo rever PUSH IMALI....

        switch ($request->payment_type) {
            case 'PAYMENT_STORE':
                return $this->makePaymentToStore($request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld, $generated_push_payment);
                break;
            case 'PAYMENT_NFC_CARD':
                return $this->makeCardPayment($request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld);
                break;
            default:
                return SendResponse::errorResp400(
                    'O tipo de pagamento deve ter um tipo valido: PAYMENT_STORE, PAYMENT_NFC_CARD',
                    'The payment type must have a valid type: PAYMENT_STORE, PAYMENT_NFC_CARD'
                );
                break;
        }
    }


    public function makePaymentStoreAppKRB2024OLD2025May(Request $request)
    {
        /**
         * adicionar variavel 
         * @payment_type : PAYMENT_STORE -- para fazer pagamento na loja
         * @payment_type : PAYMENT_NFC_CARD -- para fazer pagamento na Escola Americana
         * @payment_type : PAYMENT_BNPL -- para fazer pagamento/deposito na KRB
         */
        $this->validate($request, [
            'payer_account_number' => 'required|numeric',
            'payment_type' => 'required|in:PAYMENT_STORE,PAYMENT_NFC_CARD,PAYMENT_QRCODE,PAYMENT_LINK,PAYMENT_PUSH',
            'amount' => 'required|numeric|min:1',
        ], [
            'payer_account_number.required' => 'O numero da conta e obrigatorio',
            'payer_account_number.numeric' => 'O numero da conta deve ser numerico',
            'payment_type.required' => 'O tipo de pagamento e obrigatorio',
            'payment_type.in' => 'O tipo de pagamento deve ter um tipo valido: PAYMENT_STORE, PAYMENT_NFC_CARD,PAYMENT_QRCODE,PAYMENT_LINK,PAYMENT_PUSH',

            'amount.required' => 'O montante e obrigatorio',
            'amount.numeric' => 'O montante deve ser numerico',
            'amount.min' => 'O montante tem que ser maior que zero (0)',
        ]);

        $generated_payment = Payment::query()->where('transaction_id', $request->transaction)->first();

        if ($generated_payment && $generated_payment->status === 'success') return SendResponse::errorResp400('Este pagamento já foi efetuado.', 'This payment has already been paid.'); // LINHA A SER ANALISADA..
        if ($generated_payment && $generated_payment->status === 'expired') return SendResponse::errorResp400('Este pagamento está expirado.', 'This payment is expided'); // LINHA A SER ANALISADA..
        if ($generated_payment && $generated_payment->status === 'rejected') return SendResponse::errorResp400('Este pagamento foi rejeitado.', 'This payment was rejected.'); // LINHA A SER ANALISADA..


        // $generated_push_payment = PushPaymentRequest::query()->where('push_id', $request->transaction)->first();
        $generated_push_payment = PaymentRequest::query()->where('transaction_id', $request->transaction)->first();

        Log::info('TRANSACAO DE RETORNO', ['TRANSACAO DE RETORNO' => $generated_push_payment]);

        // if ($generated_push_payment && $generated_push_payment->status === 'SUCCESS') return SendResponse::errorResp400('Este pagamento push já foi efetuado.', 'This payment push has already been paid.'); // LINHA A SER ANALISADA..
        // if ($generated_push_payment && $generated_push_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este pagamento push está expirado.', 'This payment push is expided'); // LINHA A SER ANALISADA..
        // if ($generated_push_payment && $generated_push_payment->status === 'REJECTED') return SendResponse::errorResp400('Este pagamento push foi rejeitado.', 'This payment push was rejected.'); // LINHA A SER ANALISADA..
        // if ($generated_push_payment && $generated_push_payment->status === 'FAILED') return SendResponse::errorResp400('Este pagamento push falhou.', 'This payment push is failed.'); // LINHA A SER ANALISADA..


        // todo --- 14/03/2025 -- QRCODE

        $generated_qrcode_payment = AppQrcode::query()->where('qrcode_id', $request->transaction)->first();

        // todo --- 14/03/2025 -- QRCODE

        // $generated_link_payment = Link::query()->where('link_id', $request->transaction)->orWhere('customer_link_id', $request->transaction)->first();

        // if ($generated_link_payment) {
        //     $this->checkExpiredLink($generated_link_payment);

        //     if ($generated_link_payment->status === 'USED') return SendResponse::errorResp400('Este link já foi usado.', 'This link has already been used.'); // LINHA A SER ANALISADA..
        //     if ($generated_link_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este link está expirado.', 'This link is expired'); // LINHA A SER ANALISADA..
        //     if ($generated_link_payment->status === 'INACTIVE') return SendResponse::errorResp400('Este link esta inactivo.', 'This link is inactive.'); // LINHA A SER ANALISADA..


        // } else 




        // $check_payment = ($generated_payment && $generated_payment->status === 'rejected') || ($generated_payment && $generated_payment->status === 'expired') || ($generated_payment && $generated_payment->status === 'success');
        // if ($check_payment) return SendResponse::errorResp402rejected(
        //     'Pagamento invalido',
        //     'Invalid Payment',
        // );

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;

        // Contas a Pagar
        $accountPayer = User::getAccount($request->payer_account_number);
        if (!$accountPayer) return SendResponse::errorResp404notfound(
            'Conta não encontrada',
            'Account Not Found',
        );

        // if ($accountPayer->account_number == $request->payer_account_number) return SendResponse::errorResp404notfound(

        $accountPayerOld = User::getAccount($request->payer_account_number);
        $userPayer = User::getUserDetails($accountPayer->user_id);

        // ----------------------------------------------------
        if (User::is_subAccount($request->payer_account_number)) $userPayer = User::getUserDetails($accountPayer->user_id, $accountPayer->account_id);
        // ----------------------------------------------------

        // Validar KYC do userPayer
        $kyc = new UserKyc($userPayer);
        $kycResp = $kyc->checkSenderKYC($request->amount);
        if ($kycResp->getStatusCode() != 200) return $kycResp;

        // Validacao do saldo do User
        $kycRespBalance = $kyc->checkUserBalance($request->amount);
        if ($kycRespBalance->getStatusCode() != 200) return $kycRespBalance;

        // todo ----- PUSH
        if ($generated_push_payment) {

            $this->checkExpiredLink($generated_push_payment);

            if ($generated_push_payment->status === 'SUCCESS') return SendResponse::errorResp400('Este push já foi pago.', 'This push has already been paid.'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este push está expirado.', 'This push is expided'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'REJECTED') return SendResponse::errorResp400('Este push foi rejeitado.', 'This push was rejected.'); // LINHA A SER ANALISADA..
            if ($generated_push_payment->status === 'FAILED') return SendResponse::errorResp400('Este push falhou', 'This Push failed'); // LINHA A SER ANALISADA..


            // Buscar a loja onde se fara o pagamento
            $store_account = Store::getStoreAccount($generated_push_payment->store_account_number);
            if (!$store_account) return SendResponse::errorResp404notfound(
                'Conta da loja não encontrada',
                'StoreAccount Not Found',
            );

            $store_account_old = Store::getStoreAccount($generated_push_payment->store_account_number);
            $store_contract = Store::getStoreContractsAndConfigs($store_account->account_number);

            $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
            if (!$business) return SendResponse::errorResp404notfound(
                'Conta da loja não associada a conta Empresa',
                'Store account not associated with Company account',
            );

            // if (!$business) return response()->json(['message' => 'Conta da loja não associada a conta Empresa']);

            try {
                //code...
                DB::beginTransaction();

                // retirar o valor a pagar do saldo do User que esta a pagar
                $accountPayer->balance -= $request->amount;
                $accountPayer->update();

                // Calculos para efectuar pagamento
                $imali_commission = $request->amount * ($store_contract->taxa) / 100;
                $points = round($request->amount);

                $store_account->balance += ($request->amount - $imali_commission);
                $store_account->update();

                // adicionar o valor retirado na conta do accountPayer no balance da Loja
                $business->balance += ($request->amount - $imali_commission);
                $business->update();

                $created_payment = $this->create_payment_store_wallets_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_push_payment);

                DB::commit();

                Log::info('Outgoing response', [
                    'content' => [
                        'message' => trans('payment_done'),
                        'transaction' => $created_payment->transaction_id,
                        'created_at' => $created_payment->created_at
                    ],
                ]);
            } catch (\Throwable $th) {

                DB::rollBack();

                Log::info('Error response', [
                    'content' => [
                        'message' => 'Falha no pagamento',
                        'data' => $th->getMessage(),
                    ],
                ]);

                // Escrever no ficheiro de log as mensagens de erro.
                return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
                //throw $th;
            }

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        }
        // todo ----- PUSH

        // todo ----- QRCODE
        if ($generated_qrcode_payment) {

            $this->checkExpiredLink($generated_qrcode_payment);

            if ($generated_qrcode_payment && $generated_qrcode_payment->status === 'USED') return SendResponse::errorResp400('Este QRcode já foi pago.', 'This QRcode has already been paid.'); // LINHA A SER ANALISADA..
            if ($generated_qrcode_payment && $generated_qrcode_payment->status === 'EXPIRED') return SendResponse::errorResp400('Este QRcode está expirado.', 'This QRcode is expided'); // LINHA A SER ANALISADA..
            if ($generated_qrcode_payment && $generated_qrcode_payment->status === 'INACTIVE') return SendResponse::errorResp400('Este QRcode está inactivo.', 'This QRcode is inactive.'); // LINHA A SER ANALISADA..


            // Buscar a loja onde se fara o pagamento
            $store_account = Store::getStoreAccount($generated_qrcode_payment->store_account_number);
            if (!$store_account) return SendResponse::errorResp404notfound(
                'Conta da loja não encontrada',
                'StoreAccount Not Found',
            );

            $store_account_old = Store::getStoreAccount($generated_qrcode_payment->store_account_number);
            $store_contract = Store::getStoreContractsAndConfigs($store_account->account_number);

            $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
            if (!$business) return SendResponse::errorResp404notfound(
                'Conta da loja não associada a conta Empresa',
                'Store account not associated with Company account',
            );

            // if (!$business) return response()->json(['message' => 'Conta da loja não associada a conta Empresa']);

            try {
                //code...
                DB::beginTransaction();

                // retirar o valor a pagar do saldo do User que esta a pagar
                $accountPayer->balance -= $request->amount;
                $accountPayer->update();

                // Calculos para efectuar pagamento
                $imali_commission = $request->amount * ($store_contract->taxa) / 100;
                $points = round($request->amount);

                $store_account->balance += ($request->amount - $imali_commission);
                $store_account->update();

                // adicionar o valor retirado na conta do accountPayer no balance da Loja
                $business->balance += ($request->amount - $imali_commission);
                $business->update();

                $created_payment = $this->create_payment_store_qrcode_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_qrcode_payment, $accountPayer);

                DB::commit();

                Log::info('Outgoing response', [
                    'content' => [
                        'message' => trans('payment_done'),
                        'transaction' => $created_payment->transaction_id,
                        'created_at' => $created_payment->created_at
                    ],
                ]);
            } catch (\Throwable $th) {

                DB::rollBack();

                Log::info('Error response', [
                    'content' => [
                        'message' => 'Falha no pagamento',
                        'data' => $th->getMessage(),
                    ],
                ]);

                // Escrever no ficheiro de log as mensagens de erro.
                return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
                //throw $th;
            }

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        }
        // todo ----- QRCODE

        switch ($request->payment_type) {
            case 'PAYMENT_STORE':
                return $this->makePaymentToStore($request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld, $generated_push_payment);
                break;
            case 'PAYMENT_NFC_CARD':
                return $this->makeCardPayment($request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld);
                break;
            default:
                return SendResponse::errorResp400(
                    'O tipo de pagamento deve ter um tipo valido: PAYMENT_STORE, PAYMENT_NFC_CARD',
                    'The payment type must have a valid type: PAYMENT_STORE, PAYMENT_NFC_CARD'
                );
                break;
        }
    }

    // TODO -- 15-Setembro-2024
    public function payment_guard(Request $request)
    {

        Log::info('LOG DO GUARD', ['DADOS' => $request->all()]);

        if (!($request->has('payment_type') && $request->payment_type)) {

            //! NOVO 02-08-2024 - Por remover
            $user = User::getUserAccount();
            if (!$user) {
                $new_request = new Request([
                    'store_account_number' => $request->store_account_number,
                    'payer_account_number' => $request->payer_account_number,

                    'payment_type' => 'PAYMENT_STORE',
                    'amount' => $request->amount
                ]);

                return $this->makePaymentStoreWallets($new_request);
            }

            $payer_account_number = ($request->has('payer_account_number') && $request->payer_account_number) ? $request->payer_account_number : $user->account_number;
            $payment_type = ($request->has('sub_account_number') && $request->sub_account_number) ? 'PAYMENT_NFC_CARD' : 'PAYMENT_STORE';

            $request->request->add([
                'sub_account_number' => $request->sub_account_number,
                'store_account_number' => $request->account_number,
                'payer_account_number' => $payer_account_number,
                'payment_type' => $payment_type,
            ]);

            Log::info('LOG DO dados II', ['DADOS' => $request->all()]);

            return $this->makePaymentStoreAppKRB2024($request);
        }

        return $this->makePaymentStoreAppKRB2024($request);
    }

    //---------------------------------------------    rodrigues -----------------------------------------------------------
    public function payment_guard_new25(Request $request)
    {
        if (!($request->has('payment_type') && $request->payment_type)) {

            //! NOVO 02-08-2024 - Por remover
            $user = User::getUserAccount();
            if (!$user) {
                $new_request = new Request([
                    'store_account_number' => $request->store_account_number,
                    'payer_account_number' => $request->payer_account_number,

                    'payment_type' => 'PAYMENT_STORE',
                    'amount' => $request->amount
                ]);

                return $this->makePaymentStoreWallets($new_request);
            }

            $payer_account_number = ($request->has('payer_account_number') && $request->payer_account_number) ? $request->payer_account_number : $user->account_number;
            $payment_type = ($request->has('sub_account_number') && $request->sub_account_number) ? 'PAYMENT_NFC_CARD' : 'PAYMENT_STORE';

            $request->request->add([
                'sub_account_number' => $request->sub_account_number,
                'store_account_number' => $request->account_number,
                'payer_account_number' => $payer_account_number,
                'payment_type' => $payment_type,
            ]);

            return $this->makePaymentStoreAppKRB2024($request);
        }

        return $this->makePaymentStoreAppKRB2024($request);
    }


    /**
     * adicionar variavel 
     * @payment_type : DIRECT -- para fazer pagamento na loja
     * @payment_type : NFC_CARD -- para fazer pagamento na Escola Americana
     * @payment_type : BNPL -- para fazer pagamento/deposito na KRB
     * @payment_type : PUSH -- para fazer pagamentos por push
     * @payment_type : QRCODE -- para fazer pagamento por qrcode
     * @payment_type : LINK -- para fazer pagamento por link
     */
    public function make_payment_to_store_many_forms_new25(Request $request, $store, $store_old, $store_account)
    {
        $this->validate($request, [

            'store_account_number' => 'required|numeric|exists:stores,account_number',
            'payment_type' => 'required|in:DIRECT,QRCODE,LINK,PUSH,NFC_CARD,BNPL|exists:payment_types,name',
            'payment_method' => 'required|in:IMALI,MPESA,EMOLA,MKESH|exists:payment_methods,name',
            'amount' => 'required|numeric|min:0.50|regex:/^\d+(\.\d{1,2})?$/',
            'sub_account_number' => 'required_if:payment_type,NFC_CARD|numeric',
            'qrcode_token' => 'required_if:payment_type,QRCODE|size:112',
            'payer_account_number' => 'required|string',

        ], [

            'payer_account_number.required' => 'O numero da conta e obrigatorio',
            'payer_account_number.numeric' => 'O numero da conta deve ser numerico',
            'payment_type.required' => 'O tipo de pagamento e obrigatorio',
            'payment_type.in' => 'O tipo de pagamento deve ter um tipo valido: DIRECT,QRCODE,LINK,PUSH,NFC_CARD,BNPL',

            'amount.required' => 'O montante e obrigatorio',
            'amount.numeric' => 'O montante deve ser numerico',
            'amount.min' => 'O montante tem que ser maior que zero (0.50)',
            'amount.regex' => 'O montante tem que ter duas casas decimais'
        ]);


        // Buscar a loja onde se fara o pagamento
        if (!$store_account) return SendResponse::errorResp404notfound(
            'Conta da loja não encontrada',
            'StoreAccount Not Found',
        );

        $store_account_old = Store::getStoreAccount($request->store_account_number);
        $store_contract = Store::getStoreContractsAndConfigs($store_account->account_number);

        $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
        if (!$business) return SendResponse::errorResp404notfound(
            'Conta da loja não associada a conta Empresa',
            'Store account not associated with Company account',
        );

        //validar KYC da Loja
        $storeKyc = new StoreKyc($store_contract);
        $respStoreKyc = $storeKyc->checkStoreKYC($request->amount);
        if ($respStoreKyc->getStatusCode() != 200) return $respStoreKyc;

        switch ($request->payment_type) {
            case 'DIRECT':
                return $this->make_direct_payment_to_store_new25($request, $store, $store_old, $business);
                break;
            case 'PUSH':
                return $this->make_push_payment_to_store_new25($request, $store, $store_old, $business);
                break;
            case 'QRCODE':
                return $this->make_payment_qrcode_to_store_new25($request, $store, $store_old, $business);
                break;
            case 'LINK':
                return $this->make_payment_link_to_store_new25($request, $store, $store_old, $business);
                break;
            case 'BNPL':
                return $this->make_payment_bnpl_to_store_new25($request, $store, $store_old, $business);
                break;
            case 'NFC_CARD':
                return $this->make_payment_card_to_store_new25($request, $store, $store_old, $business);
                break;
            default:
                return SendResponse::errorResp400(
                    'O tipo de pagamento deve ter um tipo valido: DIRECT,QRCODE,LINK,PUSH,NFC_CARD,BNPL',
                    'The payment type must have a valid type: DIRECT,QRCODE,LINK,PUSH,NFC_CARD,BNPL'
                );
                break;
        }
    }

    private function make_push_payment_to_store_new25($request, $store, $store_old, $business) {}
    // -----------------------------------------------fim rodrigues-----------------------------------------------------------------------

    // TODO -- 15-Setembro-2024
    private function makePaymentToStore(Request $request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld, $generated_push_payment)
    {

        $this->validate($request, [
            'store_account_number' => 'required|numeric',
        ], [
            'store_account_number.required' => 'O numero da loja e obrigatorio',
            'store_account_number.numeric' => 'O numero da loja deve ser numerico',
        ]);

        // Buscar a loja onde se fara o pagamento
        $store_account = Store::getStoreAccount($request->store_account_number);
        if (!$store_account) return SendResponse::errorResp404notfound(
            'Conta da loja não encontrada',
            'StoreAccount Not Found',
        );

        $store_account_old = Store::getStoreAccount($request->store_account_number);
        $store_contract = Store::getStoreContractsAndConfigs($store_account->account_number);

        $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
        if (!$business) return SendResponse::errorResp404notfound(
            'Conta da loja não associada a conta Empresa',
            'Store account not associated with Company account',
        );

        if (!$business) return response()->json(['message' => 'Conta da loja não associada a conta Empresa']);


        // Se o id da conta (Empresa) que esta a fazer pagamento for o mesmo id (business_account_id) associado a conta da Loja entao...
        // if ($accountPayer->id == $store_account->business_account_id) return SendResponse::errorResp404notfound(
        if ($accountPayer->account_number == $business->account_number) return SendResponse::errorResp404notfound(
            'Não está permitido a fazer pagamentos nesta loja',
            'You are not allowed to make payments in this store',
        );

        if (User::is_subAccount($request->payer_account_number)) {
            $subC_type = SubAccountType::query()->where('id', $accountPayer->sub_account_types_id)->first();
            // if ((!$subC_type->can_pay) || ($subC_type->type_id != 'BNPL')) return SendResponse::errorResp400(
            if (!$subC_type->can_pay) return SendResponse::errorResp400(
                'A conta seleciona nao pode efectuar pagamentos',
                'The selected account can not make payments'
            );

            $user_client = UserClient::query()->where('id', $store_account->user_client_id)->where('user_type', 'KRB')->first();
            if (!$user_client) return SendResponse::errorResp400(
                'Loja não permite pagamento de contas de empréstimo',
                'Store does not allow payment of lending accounts'
            );
        }

        //validar KYC da Loja
        $storeKyc = new StoreKyc($store_contract);
        $respStoreKyc = $storeKyc->checkStoreKYC($request->amount);
        if ($respStoreKyc->getStatusCode() != 200) return $respStoreKyc;

        // Calculos para efectuar pagamento
        $imali_commission = $request->amount * ($store_contract->taxa) / 100;
        $points = round($request->amount);

        // Efectuar o Pagamento..
        try {
            DB::beginTransaction();

            // retirar o valor a pagar do saldo do User que esta a pagar
            $accountPayer->balance -= $request->amount;
            $accountPayer->update();

            // adicionar o valor retirado na conta do accountPayer no balance da Loja
            // $store_account->balance += ($request->amount - $imali_commission);
            // $store_account->update();

            $store_account->balance += ($request->amount - $imali_commission);
            $store_account->update();

            // adicionar o valor retirado na conta do accountPayer no balance da Loja
            $business->balance += ($request->amount - $imali_commission);
            $business->update();

            // Criar pagamento
            $created_payment = $this->create_payment_store_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points, null, null, $generated_push_payment);

            // criar dependencias de pagamentos
            $this->create_payment_dependences($userPayer, $created_payment, $accountPayer, $request, $imali_commission, $points);

            // envio de notificacoes
            $this->send_payment_notifications($request, $store_contract, $userPayer, $accountPayer, $created_payment);

            DB::commit();

            Log::info('Outgoing response', [
                'content' => [
                    'message' => trans('payment_done'),
                    'transaction' => $created_payment->transaction_id,
                    'created_at' => $created_payment->created_at
                ],
            ]);

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        } catch (\Throwable $th) {

            DB::rollBack();

            Log::info('Error response', [
                'content' => [
                    'message' => 'Falha no pagamento',
                    'data' => $th->getMessage(),
                ],
            ]);

            // Escrever no ficheiro de log as mensagens de erro.
            return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
        }
    }


    // TODO -- 15-Setembro-2024
    private function makeCardPayment(Request $request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld)
    {

        $this->validate($request, [
            'sub_account_number' => 'required|numeric',

        ], [
            'sub_account_number.required' => 'O numero da subconta e obrigatorio',
            'sub_account_number.numeric' => 'O numero da subconta deve ser numerico',
        ]);

        if (User::is_subAccount($request->payer_account_number)) return SendResponse::errorResp400(
            'A conta seleciona nao pode efectuar pagamentos',
            'The selected account can not make payments'
        );

        if ($userPayer->profile != 'client') return SendResponse::errorResp400(
            'Esta conta nao pode fazer depositos em cartoes NFC',
            'The selected account can not make deposit in NFC cards',
        );

        $sub_account = User::getAccount($request->sub_account_number);
        if (!$sub_account) return SendResponse::errorResp404notfound(
            'Conta não encontrada',
            'Account Not Found',
        );
        $sub_account_old = User::getAccount($request->sub_account_number);

        $subC_type = SubAccountType::query()->where('id', $sub_account->sub_account_types_id)->where('type_id', 'NFC_CARD')->first();

        if (!$subC_type) return SendResponse::errorResp400(
            'A tua subconta deve ser do tipo Cartao',
            'Your subaccount must be of the Card type'
        );

        $user_sub_account = User::getSubAccountByUser($userPayer->id, $sub_account->id);
        if (!$user_sub_account) return SendResponse::errorResp400(
            'Conta de origem invalida',
            'Invalid Source Account'
        );


        $st = Store::query()->where('id', $sub_account->store_id)->first();
        if (!$st) return SendResponse::errorResp404notfound(
            'Conta não associada a uma loja',
            'Account not associated with a store',
        );

        // todo --- verificar se a loja é da Escola Americana::.
        if ($st->id == 135) return SendResponse::errorResp404notfound(
            'Depósitos temporariamente indisponíveis',
            'Deposits temporarily unavailable',
        );
        // todo --- verificar se a loja é da Escola Americana::.

        $store_account = Store::getStoreAccount($st->account_number);
        if (!$store_account) return SendResponse::errorResp404notfound(
            'Conta da loja não encontrada',
            'StoreAccount Not Found',
        );

        $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
        if (!$business) return SendResponse::errorResp404notfound(
            'Conta da loja não associada a conta Empresa',
            'Store account not associated with Company account',
        );

        if ($sub_account->store_id != $store_account->id) return SendResponse::errorResp400(
            'Numero de Comerciante/Loja invalido',
            'Invalid Merchant/Store number'
        );

        // Loja da subconta
        $store_account_old = Store::getStoreAccount($st->account_number);
        $store_contract = Store::getStoreContractsAndConfigs($st->account_number);

        //validar KYC da Loja
        $storeKyc = new StoreKyc($store_contract);
        $respStoreKyc = $storeKyc->checkStoreKYC($request->amount);
        if ($respStoreKyc->getStatusCode() != 200) return $respStoreKyc;

        // Calculos para efectuar pagamento
        $imali_commission = $request->amount * ($store_contract->taxa) / 100;
        $points = round($request->amount);

        // Efectuar o Pagamento..
        try {
            DB::beginTransaction();

            // retirar o valor a pagar do saldo do User que esta a pagar
            $accountPayer->balance -= $request->amount;
            $accountPayer->update();

            // adicionar o valor retirado na conta do accountPayer no balance da Loja
            $store_account->balance += ($request->amount - $imali_commission);
            $store_account->update();

            // adicionar o valor no Saldo da Conta Empresa
            $business->balance += ($request->amount - $imali_commission);
            $business->update();

            // DEPOSITAR NA SUBCONTA
            $sub_account->balance += $request->amount;
            $sub_account->update();


            // Criar pagamento
            $created_payment = $this->create_payment_nfc_card_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points, $sub_account, $sub_account_old);

            // criar dependencias de pagamentos
            $this->create_payment_dependences($userPayer, $created_payment, $accountPayer, $request, $imali_commission, $points);

            // envio de notificacoes
            $this->send_payment_notifications($request, $store_contract, $userPayer, $accountPayer, $created_payment);

            DB::commit();

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        } catch (\Throwable $th) {

            DB::rollBack();

            // Escrever no ficheiro de log as mensagens de erro.
            return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
        }
    }

    // TODO -- 15-Setembro-2024
    private function create_payment_nfc_card_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points, $sub_account = null, $sub_account_old = null)
    {
        $created_payment = new Payment();

        // Registar o pagamento na tabela de Payment
        if ($generated_payment) {

            $generated_payment->update([
                'received_points' => $points,
                'amount_credited' => $request->amount,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'estado_color' => '#388E3C',
                'sender_id' => $userPayer->id,
                'old_balance' => $accountPayerOld->balance,
                'new_balance' => $accountPayer->balance
            ]);

            $created_payment = $generated_payment;
        } else {

            $new_payment = Payment::create([
                'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                'partner_transaction_id' => $request->partner_transaction_id,
                'terminalID' => $request->terminal_id,
                'sender_id' => $userPayer->id,
                'sender_name' => $userPayer->name,
                'sender_account_number' => $accountPayer->account_number,
                'sender_card_number' => $accountPayer->card_number,
                'store_id' => $store_account->id,
                'received_points' => $points,
                'amount' => $request->amount,
                'amount_debited' => $request->amount,
                'amount_credited' => $request->amount - $imali_commission,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'payment_type' => 'directo',
                'estado_color' => '#388E3C',
                'old_balance' => $accountPayerOld->balance,
                'new_balance' => $accountPayer->balance,
                'old_store_balance' => $store_account_old->balance,
                'new_store_balance' => $store_account->balance,
                'category_id' => $store_account->industry_activity,

                'transaction_type' => 'debit',
                'transaction_name' => 'Pagamento'
            ]);


            Payment::create([
                'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                'partner_transaction_id' => $request->partner_transaction_id,
                'terminalID' => $request->terminal_id,
                'sender_id' => $userPayer->id,
                'sender_name' => $userPayer->name,
                'sender_account_number' => $accountPayer->account_number,
                'sender_card_number' => $sub_account ? $sub_account->card_number : null,
                'store_id' => $store_account->id,
                'received_points' => $points,
                'amount' => $request->amount,
                'amount_debited' => $request->amount,
                'amount_credited' => $request->amount - $imali_commission,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'is_real_payment' => 0,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'payment_type' => 'directo',
                'estado_color' => '#388E3C',
                'old_balance' => $accountPayerOld->balance,
                'new_balance' => $accountPayer->balance,
                'old_store_balance' => $store_account_old->balance,
                'new_store_balance' => $store_account->balance,
                'category_id' => $store_account->industry_activity,

                'transaction_type' => 'credit',
                'transaction_name' => 'Depósito',
            ]);

            PrepaidCardDeposit::create([
                'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                'payment_transaction_id' => $new_payment->transaction_id,
                'imali_account_number' => $accountPayer->account_number,
                'imali_sub_account_number' => $sub_account->account_number,
                'store_account_number' => $store_account->account_number,
                'imali_account_id' => $accountPayer->id,
                'imali_sub_account_id' => $sub_account->id,
                'store_id' => $store_account->id,
                'last_unreal_balance' => $sub_account_old->balance,
                'unreal_balance' => $sub_account->balance,
                'unreal_amount_credited' => $request->amount,
                'real_amount_debited' => $request->amount,
                'real_amount_credited' => $request->amount - $imali_commission
            ]);

            $created_payment = $new_payment;
        }

        return $created_payment;
    }


    // TODO -- 15-Setembro-2024
    public function makePaymentStoreWallets(Request $request)
    {

        $this->validate($request, [
            'payer_account_number' => 'required|numeric',
            'payment_type' => 'required|in:PAYMENT_STORE,PAYMENT_NFC_CARD',
            'amount' => 'required|numeric|min:1',
        ], [
            'payer_account_number.required' => 'O numero da conta e obrigatorio',
            'payer_account_number.numeric' => 'O numero da conta deve ser numerico',
            'payment_type.required' => 'O tipo de pagamento e obrigatorio',
            'payment_type.in' => 'O tipo de pagamento deve ter um tipo valido: PAYMENT_STORE, PAYMENT_NFC_CARD',

            'amount.required' => 'O montante e obrigatorio',
            'amount.numeric' => 'O montante deve ser numerico',
            'amount.min' => 'O montante tem que ser maior que zero (0)',
        ]);

        $generated_payment = Payment::query()->where('transaction_id', $request->transaction)->first();
        $check_payment = ($generated_payment && $generated_payment->status === 'rejected') || ($generated_payment && $generated_payment->status === 'expired') || ($generated_payment && $generated_payment->status === 'success');
        if ($check_payment) return SendResponse::errorResp402rejected(
            'Pagamento invalido',
            'Invalid Payment',
        );

        return $this->makePaymentToStoreWallets($request, $generated_payment, null, null, null);
    }


    // TODO -- 15-Setembro-2024
    private function makePaymentToStoreWallets(Request $request, $generated_payment, $userPayer, $accountPayer, $accountPayerOld)
    {

        $this->validate($request, [
            'store_account_number' => 'required|numeric',
        ], [
            'store_account_number.required' => 'O numero da loja e obrigatorio',
            'store_account_number.numeric' => 'O numero da loja deve ser numerico',
        ]);

        // Buscar a loja onde se fara o pagamento
        $store_account = Store::getStoreAccount($request->store_account_number);
        if (!$store_account) return SendResponse::errorResp404notfound(
            'Conta da loja não encontrada',
            'StoreAccount Not Found',
        );

        $store_account_old = Store::getStoreAccount($request->store_account_number);
        $store_contract = Store::getStoreContractsAndConfigs($store_account->account_number);

        $business = BusinessAccount::getBusinessAccountByID($store_account->business_account_id);
        if (!$business) return SendResponse::errorResp404notfound(
            'Conta da loja não associada a conta Empresa',
            'Store account not associated with Company account',
        );

        //validar KYC da Loja
        $storeKyc = new StoreKyc($store_contract);
        $respStoreKyc = $storeKyc->checkStoreKYC($request->amount);
        if ($respStoreKyc->getStatusCode() != 200) return $respStoreKyc;

        // Calculos para efectuar pagamento
        $imali_commission = $request->amount * ($store_contract->taxa) / 100;
        $points = round($request->amount);

        // Efectuar o Pagamento..
        try {
            DB::beginTransaction();

            // adicionar o valor retirado na conta do accountPayer no balance da Loja
            $store_account->balance += ($request->amount - $imali_commission);
            $store_account->update();

            // adicionar o valor retirado na conta do accountPayer no balance da Loja
            $business->balance += ($request->amount - $imali_commission);
            $business->update();

            // Criar pagamento
            $created_payment = $this->create_payment_store_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points);

            // criar dependencias de pagamentos
            $this->create_payment_dependences($userPayer, $created_payment, $accountPayer, $request, $imali_commission, $points);

            // envio de notificacoes
            $this->send_payment_notifications($request, $store_contract, $userPayer, $accountPayer, $created_payment);

            DB::commit();

            Log::info('Outgoing response', [
                'content' => [
                    'message' => trans('payment_done'),
                    'transaction' => $created_payment->transaction_id,
                    'created_at' => $created_payment->created_at
                ],
            ]);

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        } catch (\Throwable $th) {

            DB::rollBack();

            Log::info('Error response', [
                'content' => [
                    'message' => 'Falha no pagamento',
                    'data' => $th->getMessage(),
                ],
            ]);

            // Escrever no ficheiro de log as mensagens de erro.
            return response()->json(['message' => 'Falha no pagamento', $th->getMessage(), $th->getLine()], 500);
        }
    }

    // TODO --  NEW 25
    private function create_payment_store_wallets_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_push_payment, $userPayer = null, $accountPayer = null, $accountPayerOld = null)
    {
        // Registar o pagamento na tabela de Payment
        $payment_type = PaymentType::query()->where('id', $generated_push_payment->payment_types_id)->first();

        $created_payment = Payment::create([
            'transaction_id' => $generated_push_payment->transaction_id,
            'service_transaction_id' => $generated_push_payment->thirdparty_transaction_id,
            'partner_transaction_id' => $request->partner_transaction_id,
            'sender_account_number' => $generated_push_payment->client_account_number,
            'store_id' => $store_account->id,
            'received_points' => $points,
            'amount' => $request->amount,
            'amount_debited' => $request->amount,
            'amount_credited' => $request->amount - $imali_commission,
            'comissao' => $imali_commission,
            'description' => $request->description,
            'used_points' => $request->used_points,
            'estado' => 'success',
            'status' => 'success',
            'payment_type' => $payment_type->name,
            'estado_color' => '#388E3C',
            'sender_id' => $userPayer ? $userPayer->id : null,
            'sender_name' => $userPayer ? $userPayer->name : null,
            'old_balance' => $accountPayerOld ? $accountPayerOld->balance : 0,
            'new_balance' => $accountPayer ? $accountPayer->balance : 0,
            'old_store_balance' => $store_account_old->balance,
            'new_store_balance' => $store_account->balance,
            'category_id' => $store_account->industry_activity,
            'business_account_id' => $business->id,

            'payment_requests_id' => $generated_push_payment ? $generated_push_payment->id : null,

            'transaction_type' => 'debit',
            'transaction_name' => 'Pagamento'
        ]);


        if ($generated_push_payment) {

            $convert = strtotime(date('Y-m-d H:i:s')) - (60 * 4);
            $duration = date("Y-m-d H:i:s", $convert);

            $generated_push_payment->status = 'SUCCESS';
            $generated_push_payment->is_payment_confirmed = 1;
            $generated_push_payment->expiration_datetime = $duration;
            $generated_push_payment->update();


            if ($generated_push_payment->link_id) {
                $link = Link::query()
                    ->where('link_id', $generated_push_payment->link_id)
                    ->where('status', 'PENDING')
                    ->first();

                if ($link) {
                    $link->status = 'USED';
                    $link->update();

                    $payment_link = Payment::where('transaction_id', $created_payment->transaction_id)->first();
                    $payment_link->links_id = $link->id;
                    $payment_link->link_id_key = $link->link_id;
                    $payment_link->save();
                }
            }
        }


        // Dados para nova tabela de All Transactions

        // REGISTO DE DEBITO PARA O CLIENTE
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            1,
            1,
            $created_payment->sender_name,
            $created_payment->sender_account_number,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            $created_payment->amount,
            'Pagamento ' . $created_payment->source,
            $created_payment->old_balance,
            $created_payment->new_balance,
            $created_payment->old_store_balance,
            $created_payment->new_store_balance + $imali_commission,
            $created_payment->status,
            $created_payment->created_at,
            'DEBIT',
        );

        // REGISTO DE CREDITO PARA LOJA
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            1,
            1,
            $created_payment->sender_name,
            $created_payment->sender_account_number,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            $created_payment->amount,
            'Pagamento ' . $created_payment->source,
            $created_payment->old_balance,
            $created_payment->new_balance,
            $created_payment->old_store_balance,
            $created_payment->new_store_balance  + $imali_commission,
            $created_payment->status,
            $created_payment->created_at,
            'CREDIT',
        );

        // REGISTO DE DEBITO PARA A LOJA
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            7,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            'iMali',
            '11900',
            9,
            $created_payment->comissao,
            'Pagamento ' . $created_payment->source,
            $created_payment->new_store_balance + $created_payment->comissao,
            $created_payment->new_store_balance,
            0,
            0,
            $created_payment->status,
            $created_payment->created_at,
            'DEBIT',
        );

        // REGISTO DE DEBITO DA TAXA PARA LOJA
        // $store_account->balance -= $imali_commission;
        // $store_account->update();

        return $created_payment;
    }


    private function create_payment_store_qrcode_transaction($request, $store_account, $store_account_old, $business, $imali_commission, $points, $generated_qrcode_payment, $accountPayer)
    {
        // Registar o pagamento na tabela de Payment
        $payment_type = PaymentType::query()->where('id', 1)->first();

        $created_payment = Payment::create([
            'transaction_id' => $generated_qrcode_payment->qrcode_id,
            // 'service_transaction_id' => $generated_qrcode_payment->thirdparty_transaction_id,
            'partner_transaction_id' => $generated_qrcode_payment->partner_transaction_id,
            'sender_account_number' => $accountPayer->account_number,
            'store_id' => $store_account->id,
            'received_points' => $points,
            'amount' => $request->amount,
            'amount_debited' => $request->amount,
            'amount_credited' => $request->amount - $imali_commission,
            'comissao' => $imali_commission,
            'description' => $generated_qrcode_payment->description,
            'used_points' => $request->used_points,
            'estado' => 'success',
            'status' => 'success',
            'payment_type' => $payment_type->name,
            'estado_color' => '#388E3C',
            'old_store_balance' => $store_account_old->balance,
            'new_store_balance' => $store_account->balance,
            'category_id' => $store_account->industry_activity,
            'business_account_id' => $business->id,

            'payment_requests_id' => $generated_qrcode_payment ? $generated_qrcode_payment->id : null,
            'links_id' => $generated_qrcode_payment ? $generated_qrcode_payment->id : null,
            'links_id_key' => $generated_qrcode_payment ? $generated_qrcode_payment->link_id : null,

            'transaction_type' => 'debit',
            'transaction_name' => 'Pagamento'
        ]);


        if ($generated_qrcode_payment) {

            $convert = strtotime(date('Y-m-d H:i:s')) - (60 * 4);
            $duration = date("Y-m-d H:i:s", $convert);

            $generated_qrcode_payment->status = 'USED';
            $generated_qrcode_payment->expiration_datetime = $duration;
            $generated_qrcode_payment->update();

            if ($generated_qrcode_payment->link_id) {
                $link = Link::query()
                    ->where('link_id', $generated_qrcode_payment->link_id)
                    ->where('status', 'PENDING')
                    ->first();

                if ($link) {
                    $link->status = 'USED';
                    $link->update();
                }
            }
        }


        // Dados para nova tabela de All Transactions

        // REGISTO DE DEBITO PARA O CLIENTE
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            1,
            1,
            $created_payment->sender_name,
            $created_payment->sender_account_number,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            $created_payment->amount,
            'Pagamento ' . $created_payment->source,
            $created_payment->old_balance,
            $created_payment->new_balance,
            $created_payment->old_store_balance,
            $created_payment->new_store_balance + $imali_commission,
            $created_payment->status,
            $created_payment->created_at,
            'DEBIT',
        );

        // REGISTO DE CREDITO PARA LOJA
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            1,
            1,
            $created_payment->sender_name,
            $created_payment->sender_account_number,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            $created_payment->amount,
            'Pagamento ' . $created_payment->source,
            $created_payment->old_balance,
            $created_payment->new_balance,
            $created_payment->old_store_balance,
            $created_payment->new_store_balance  + $imali_commission,
            $created_payment->status,
            $created_payment->created_at,
            'CREDIT',
        );

        // REGISTO DE DEBITO PARA A LOJA
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            7,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            'iMali',
            '11900',
            9,
            $created_payment->comissao,
            'Pagamento ' . $created_payment->source,
            $created_payment->new_store_balance + $created_payment->comissao,
            $created_payment->new_store_balance,
            0,
            0,
            $created_payment->status,
            $created_payment->created_at,
            'DEBIT',
        );

        // REGISTO DE DEBITO DA TAXA PARA LOJA
        // $store_account->balance -= $imali_commission;
        // $store_account->update();

        return $created_payment;
    }


    // TODO -- 15-Setembro-2024
    private function create_payment_store_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points, $sub_account = null, $sub_account_old = null, $generated_push_payment = null)
    {
        // $created_payment = new Payment();

        // Registar o pagamento na tabela de Payment
        if ($generated_payment) {

            $generated_payment->update([
                'received_points' => $points,
                'amount_credited' => $request->amount,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'estado_color' => '#388E3C',
                'old_balance' => $accountPayerOld->balance,
                'new_balance' => $accountPayer->balance,

                'sender_id' => $userPayer ? $userPayer->id : $userPayer,
                'sender_name' => $userPayer ? $userPayer->name : $userPayer,
                'sender_account_number' => $accountPayer ? $accountPayer->account_number : $accountPayer,
                'sender_card_number' => $accountPayer ? $accountPayer->card_number : $accountPayer,
                'transaction_type' => 'debit',
                'transaction_name' => 'Pagamento',
                'category_id' => $store_account->industry_activity
            ]);

            $created_payment = $generated_payment;
        } else if ($generated_push_payment) {

            $created_payment = Payment::create([
                // 'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                'transaction_id' => $generated_push_payment->transaction_id,
                'service_transaction_id' => $generated_push_payment->thirdparty_transaction_id,
                'partner_transaction_id' => $request->partner_transaction_id,
                'terminalID' => $request->terminal_id,
                'sender_id' => $userPayer ? $userPayer->id : $userPayer,
                'sender_name' => $userPayer ? $userPayer->name : $userPayer,
                'sender_account_number' => $accountPayer ? $accountPayer->account_number : $accountPayer,
                'sender_card_number' => $accountPayer ? $accountPayer->card_number : $accountPayer,
                'store_id' => $store_account->id,
                'received_points' => $points,
                'amount' => $request->amount,
                'amount_debited' => $request->amount,
                'amount_credited' => $request->amount - $imali_commission,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'payment_type' => 'directo',
                'estado_color' => '#388E3C',
                'old_balance' => $accountPayerOld ? $accountPayerOld->balance : $accountPayerOld,
                'new_balance' => $accountPayer ? $accountPayer->balance : $accountPayer,
                'old_store_balance' => $store_account_old->balance,
                'new_store_balance' => $store_account->balance,
                'category_id' => $store_account->industry_activity,

                // 'push_id' => $generated_push_payment ? $generated_push_payment->push_id : null,
                // 'push_payment_requests_id' => $generated_push_payment ? $generated_push_payment->id : null,

                'payment_requests_id' => $generated_push_payment ? $generated_push_payment->id : null,

                'transaction_type' => 'debit',
                'transaction_name' => 'Pagamento'
            ]);


            if ($generated_push_payment) {
                $generated_push_payment->status = 'SUCCESS';
                $generated_push_payment->update();
            }
        } else {

            $new_payment = Payment::create([
                'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                'partner_transaction_id' => $request->partner_transaction_id,
                'terminalID' => $request->terminal_id,
                'sender_id' => $userPayer ? $userPayer->id : $userPayer,
                'sender_name' => $userPayer ? $userPayer->name : $userPayer,
                'sender_account_number' => $accountPayer ? $accountPayer->account_number : $accountPayer,
                'sender_card_number' => $accountPayer ? $accountPayer->card_number : $accountPayer,
                'store_id' => $store_account->id,
                'received_points' => $points,
                'amount' => $request->amount,
                'amount_debited' => $request->amount,
                'amount_credited' => $request->amount - $imali_commission,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'payment_type' => 'directo',
                'estado_color' => '#388E3C',
                'old_balance' => $accountPayerOld ? $accountPayerOld->balance : $accountPayerOld,
                'new_balance' => $accountPayer ? $accountPayer->balance : $accountPayer,
                'old_store_balance' => $store_account_old->balance,
                'new_store_balance' => $store_account->balance,
                'category_id' => $store_account->industry_activity,

                'transaction_type' => 'debit',
                'transaction_name' => 'Pagamento'
            ]);

            $created_payment = $new_payment;
        }






        // Dados para nova tabela de All Transactions

        // REGISTO DE DEBITO PARA O CLIENTE
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            1,
            1,
            $created_payment->sender_name,
            $created_payment->sender_account_number,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            $created_payment->amount,
            'Pagamento ' . $created_payment->source,
            $created_payment->old_balance,
            $created_payment->new_balance,
            $created_payment->old_store_balance,
            $created_payment->new_store_balance + $imali_commission,
            $created_payment->status,
            $created_payment->created_at,
            'DEBIT',
        );

        // REGISTO DE CREDITO PARA LOJA
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            1,
            1,
            $created_payment->sender_name,
            $created_payment->sender_account_number,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            $created_payment->amount,
            'Pagamento ' . $created_payment->source,
            $created_payment->old_balance,
            $created_payment->new_balance,
            $created_payment->old_store_balance,
            $created_payment->new_store_balance  + $imali_commission,
            $created_payment->status,
            $created_payment->created_at,
            'CREDIT',
        );

        // REGISTO DE DEBITO PARA A LOJA
        AllTransactionController::create_all_transaction(
            $created_payment->transaction_id,
            7,
            1,
            $store_account->name,
            $store_account->account_number,
            3,
            'iMali',
            '11900',
            9,
            $created_payment->comissao,
            'Pagamento ' . $created_payment->source,
            $created_payment->new_store_balance + $created_payment->comissao,
            $created_payment->new_store_balance,
            0,
            0,
            $created_payment->status,
            $created_payment->created_at,
            'DEBIT',
        );

        // REGISTO DE DEBITO DA TAXA PARA LOJA
        // $store_account->balance -= $imali_commission;
        // $store_account->update();

        return $created_payment;
    }

    // TODO -- 15-Setembro-2024
    private function create_payment_dependences($userPayer, $created_payment, $accountPayer, $request, $imali_commission, $points)
    {

        TransactionHistory::create([
            'user_id' => $userPayer->id,
            'payment_id' => $created_payment->id,
            'transaction_type' => 'payment',
        ]);


        HistoryPayment::create([
            'sender_account' => $accountPayer->account_number,
            'sender_name' => $userPayer->name,
            'amount_credited' => $request->amount,
            'status_user' => 'sender',
            'status' => 'done',
            'comissao' => $imali_commission,
            'amount' => $request->amount,
            'user_id' => $userPayer->id,
            'actual_points' => $points,
            'last_points' => $points,
            'win_points' => $points,
            'transaction_id' => $created_payment->transaction_id,
            'payment_id' => $created_payment->id
        ]);


        Profit::create([
            'payer_id' => $userPayer->id,
            'payer_account' => $userPayer->account_number,
            'amount' => $request->amount,
            'amount_credited' => $request->amount,
            'comissao' => $imali_commission,
            'profit_id' => $this->trasactionGeneration->generateTransaction(),
            'payment_id' => $created_payment->id,
            'profit_payer_id' => $created_payment->store_id
        ]);
    }

    public function makePaymentStoreAppNew(Request $request)
    {

        Log::info('Outgoing Response', [
            'content' => $request->all(),
        ]);

        $this->validate($request, [
            'account_number' => 'required',
            'amount' => 'required',
            //'description' => 'required|max:30'
        ]);

        $pay = Payment::query()->where('transaction_id', $request->transaction)->first();

        if (($pay && $pay->status === 'rejected') || ($pay && $pay->status === 'expired')) {

            return response()->json(['message' => trans('payment_invalid'), 'status' => 401], 406);
        }

        $kyc = new Kyc();
        $kycCheck = $kyc->checkSenderPayment($request);


        if ($kycCheck) {
            $log = new Record();
            $log->createLog([
                'description' => "Payment Fail",
                'details' => $kycCheck,
                'operation' => 'Payment',
                'properties' => json_encode($request->except(['pin'])),
                'status' => 'Error',
                'user_id' => $request->user()->id
            ]);

            //   $pay->update([
            //        'estado' => 'rejected',
            //      'status' => 'rejected',
            //    'description' => $kycCheck->getData()->message,
            //   'created_at' => now(),
            //   'updated_at' => now()
            //  ]);

            return $kycCheck;
        } else {

            $this->request = $request;


            DB::transaction(function () {

                $store = DB::table('stores')->where('account_number', $this->request->account_number)->first();

                $imaliAccount = DB::table('users')
                    ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
                    ->where('users.user_id', $this->request->user()->user_id)
                    ->select('users.*', 'imali_accounts.account_number', 'imali_accounts.points', 'imali_accounts.balance')
                    ->first();

                $valorAPagar = $this->request->amount;
                $points = round($valorAPagar);

                // Payer or Sender Section
                DB::table('imali_accounts')->where('user_id', $imaliAccount->id)->decrement('balance', $valorAPagar);
                DB::table('imali_accounts')->where('user_id', $imaliAccount->id)->increment('points', $points);

                //                            $contractoComerciante = MerchantContract::query()->where('store_id', '=', $store->id)->first();
                $contractoComerciante = DB::table('merchant_contracts')->where('store_id', '=', $store->id)->first();

                $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                $valorMin = $contractoComerciante->min_amount;
                $valorMax = $contractoComerciante->max_amount;

                if ($taxaDesconto < $valorMin) {
                    $taxaDesconto = $valorMin;
                }
                if ($taxaDesconto > $valorMax) {
                    $taxaDesconto = $valorMax;
                }

                //                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                $valorFinal = $valorAPagar - $taxaDesconto;

                // Recever User Merchante
                DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);

                // Add Money to Merchant
                //                        $storeT = Store::query()->where('account_number', $store->account_number)->first();
                //                        DB::table('merchant_accounts')->where('id', $storeT->merchant_account_id)->increment('balance', $valorFinal);


                //                $profit = $valorAPagar*($contractoComerciante->taxa)/100;
                $this->generatedTransaction = $this->trasactionGeneration->generateTransaction();


                $getPayment = DB::table('payments')->where('transaction_id', $this->request->transaction)->first();

                $imaliAccount2 = DB::table('users')
                    ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
                    ->where('users.user_id', $this->request->user()->user_id)
                    ->select('users.*', 'imali_accounts.account_number', 'imali_accounts.points', 'imali_accounts.balance')
                    ->first();


                if ($getPayment) {



                    DB::table('payments')
                        ->where('transaction_id', $this->request->transaction)
                        ->update([
                            'received_points' => $points,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'description' => $this->request->description,
                            'used_points' => $this->request->used_points,
                            'estado' => 'success',
                            'status' => 'success',
                            'payment_type' => 'directo',
                            'estado_color' => '#388E3C',
                            'sender_id' => $imaliAccount->id,
                            'updated_at' => now(),

                            'old_balance' => $imaliAccount->balance,
                            'new_balance' => $imaliAccount2->balance
                        ]);

                    $this->createTransaction = DB::table('payments')->where('transaction_id', $this->request->transaction)->first();
                } else {

                    DB::table('payments')->insert([
                        'transaction_id' => $this->generatedTransaction,
                        'sender_id' => $imaliAccount->id,
                        'store_id' => $store->id,
                        'client_id' => $this->request->user_client_id,
                        'received_points' => $points,
                        'amount' => $valorAPagar,
                        'amount_credited' => $valorFinal,
                        'comissao' => $taxaDesconto,
                        'description' => $this->request->description,
                        'used_points' => $this->request->used_points,
                        'estado' => 'success',
                        'status' => 'success',
                        'payment_type' => 'directo',
                        'estado_color' => '#388E3C',
                        'created_at' => now(),
                        'updated_at' => now(),
                        'category_id' => $store->industry_activity,

                        'old_balance' => $imaliAccount->balance,
                        'new_balance' => $imaliAccount2->balance
                    ]);

                    $this->createTransaction = DB::table('payments')->where('transaction_id', $this->generatedTransaction)->first();
                }


                DB::table('transaction_histories')->insert([
                    'user_id' => $this->request->user()->id,
                    'payment_id' => $this->createTransaction->id,
                    'category_id' => $this->createTransaction->category_id,
                    'transaction_type' => 'payment',
                    'created_at' => now(),
                    'updated_at' => now()
                ]);

                $actualPoints = $imaliAccount->points + $points;

                DB::table('history_payments')->insert([
                    'sender_account' => $imaliAccount->account_number,
                    'sender_name' => $imaliAccount->name,
                    'amount_credited' => $valorFinal,
                    'status_user' => 'sender',
                    'status' => 'done',
                    'comissao' => $taxaDesconto,
                    'amount' => $valorAPagar,
                    'user_id' => $imaliAccount->id,
                    'actual_points' => $actualPoints,
                    'last_points' => $imaliAccount->points,
                    'win_points' => $points,
                    'transaction_id' => $this->generatedTransaction,
                    'category_id' => $store->industry_activity,
                    'payment_id' => $this->createTransaction->id,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);


                DB::table('profits')->insert([
                    'payer_id' => $imaliAccount->id,
                    'payer_account' => $store->account_number,
                    'amount' => $valorAPagar,
                    'amount_credited' => $valorFinal,
                    'comissao' => $taxaDesconto,
                    'profit_id' => $this->trasactionGeneration->generateTransaction(),
                    'payment_id' => $this->createTransaction->id,
                    'profit_payer_id' => $this->createTransaction->store_id,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);


                DB::table('logs')->insert([
                    'description' => $imaliAccount->account_number . ' ' . $store->name,
                    'details' => trans('payment_done'),
                    'operation' => 'Payment',
                    'properties' => json_encode($this->request->except(['pin'])),
                    'status' => 'success',
                    'user_id' => $this->request->user()->id
                ]);

                $notification = array(
                    //                                'icon' => 'ic_imali_logo_verde_01',
                    'icon' => 'ic_i_mali_cover',
                    'title' => 'Pagamento ' . $this->request->amount . ' MT',
                    'body' => 'Parabéns, ' . ' fez o pagamento de ' . $this->request->amount . ' MT ' . ' na loja ' . $store->name,
                    'click_action' => 'com.imali.payapp.payment_PAGAR_NOTIFICATION',
                    'color' => '#ffffff'
                );

                $notificationStore = array(
                    'icon' => 'ic_imali_logo_verde_01',
                    'image' => 'https://imali.co.mz/wp-content/uploads/2022/04/iMali-Business-Logo.png',
                    //                            'icon' => 'ic_i_mali_cover',
                    'title' => 'Pagamento ' . $this->request->amount . ' MT',
                    'body' => 'Parabéns, ' . ' recebeu o pagamento de ' . $this->request->amount . ' MT ' . ' do cliente ' . $imaliAccount->name,
                    'click_action' => 'mz.co.imali.business.payment_TARGET_NOTIFICATION',
                    'color' => '#ffffff'
                );


                $store = DB::table('stores')->where('account_number', $this->request->account_number)->first();

                $category = RamoActivity::find($store->industry_activity);

                $data = array(
                    'transaction' => $this->createTransaction->transaction_id,
                    'loja' => $store->name,
                    'name' => $imaliAccount->name,
                    'loja_account' => $store->account_number,
                    'pontos' => $this->createTransaction->received_points,
                    'pontos_usados' => $this->createTransaction->used_points,
                    'amount' => $this->createTransaction->amount,
                    'amount_debited' => $this->createTransaction->amount_credited,
                    'amount_credited' => $this->createTransaction->amount_credited,
                    'account_number' => $imaliAccount->account_number,
                    'phone' => $this->request->user()->phone,
                    'descricao' => $this->createTransaction->description,
                    'data' => $this->createTransaction->created_at,
                    'created_at' => $this->createTransaction->created_at,
                    'estado' => $this->createTransaction->estado,
                    'comissao' => $this->createTransaction->comissao,
                    'message_store' => trans('payment_received'),
                    'message_customer' => trans('payment_done'),
                    'logo_category' => $category->logo,
                    'category' => $category->nome,
                    'route' => 'PAGAR_NOTIFICATION',
                    'terminal' => 'firebase'
                );


                // Notifify customer
                $this->pushNotifification($imaliAccount->firebase_token, $notification, $data);


                $storeConfig = StoreConfig::query()
                    ->where('store_id', '=', $store->id)
                    ->first();

                if ($storeConfig) {

                    if ($storeConfig->notify === 1) {

                        // NOTIFY STORE BY SMS
                        if ($storeConfig->notify_sms === 1) {
                            $sms = new SendSMSSislog();

                            $data = array(
                                "sender_id" => $this->createTransaction->sender_id,
                                "store_id" => $this->createTransaction->store_id,
                                "transaction_id" => $this->createTransaction->transaction_id,
                                "created_at" => $this->createTransaction->created_at,
                                "amount" => $this->createTransaction->amount,
                            );
                            $this->smsManager->sendSMSToComerciante($data);
                        }

                        if ($storeConfig->notify_email == 1) {
                        }

                        // NOTIFY STORE
                        if ($storeConfig->notify_push == 1) {

                            if ($getPayment) {
                                $this->pushNotifification($getPayment->firebase_token, $notificationStore, $data);
                            } else {
                                $device = StoreDevice::query()
                                    ->where('store_id', $store->id)
                                    ->where('status', '=', 1)
                                    ->get();

                                foreach ($device as $d) {
                                    $this->pushNotifification($d->firebase_token, $notificationStore, $data);
                                }
                            }
                        }
                    }
                }
            }, 2);
            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $this->generatedTransaction,
                'created_at' => $this->createTransaction->created_at,
                'duration' => 3000,
            ]);
        }
    }

    //? Payment With SubAccounts
    // todo --- FUNCIONA PRODUÇÃO -- 16-Setembro-2024 🧣👍🏽

    public function makePaymentStoreApp2024SubAccounts(Request $request)
    {

        // QR Static
        // QR Dynamic
        // QR Store Number
        //? Payment by Link
        // Reembolso
        // Payment Push

        // New Parameter - account_type = subaccount

        $this->validate(
            $request,
            [
                'amount' => 'required',
                'card_number' => 'required',
                //'terminal_id' => 'required',
                'account_number' => 'required',
                'partner_transaction_id' => 'required|unique:payments',
                'is_real_payment' => 'in:0,1',
            ],
            [
                'amount.required' => 'Campo amount é obrigatório',
                'card_number.required' => 'Campo card_number é obrigatório',
                //'terminal_id.required' => 'Campo terminal_id é obrigatório',
                'account_number.required' => 'Campo account_number é obrigatório',
                'partner_transaction_id.required' => 'Campo partner_transaction_id é obrigatório',
                'partner_transaction_id.unique' => 'Campo partner_transaction_id ja existe',
                'is_real_payment.in' => 'Campo is_real_payment aceita 0 ou 1 (0 - pagamento ficticio, 1 - pagamento real)',
            ]
        );

        $accountPayer = User::getAccount($request->card_number);
        if (!$accountPayer) return response()->json(['message' => 'O cartão informado para pagamento não existe.'], 404);

        $accountPayerOld = User::getAccount($request->card_number);
        $userPayer = User::getUserDetails($accountPayer->user_id, $accountPayer->account_number);

        // Validar KYC do userPayer
        $kyc = new UserKyc($userPayer);
        $kycResp = $kyc->checkSenderKYC($request->amount);
        if ($kycResp->getStatusCode() != 200) return $kycResp;


        // Validacao do saldo do User
        //$kycRespBalance = $kyc->checkUserBalance($request->amount);
        $kycRespBalance = $kyc->checkUserCardBalance($request->amount);
        if ($kycRespBalance->getStatusCode() != 200) return $kycRespBalance;


        // Buscar a loja onde se fara o pagamento
        $store_account_old = Store::getStoreAccount($request->account_number);
        $store_account = Store::getStoreAccount($request->account_number);
        // return $store_account;
        $store_contract = Store::getStoreContractsAndConfigs($request->account_number);
        if (!$store_contract)  return response()->json(['message' => 'Falha no pagamento, nao e possivel executar a operacao, tente novamente'], 400);
        // return $store_contract;

        //validar KYC da Loja
        $storeKyc = new StoreKyc($store_contract);

        $respStoreKyc = $storeKyc->checkStoreKYC($request->amount);
        if ($respStoreKyc->getStatusCode() != 200) return $respStoreKyc;

        // Calculos para efectuar pagamento
        if ($request->has('is_real_payment') && $request->is_real_payment)
            $imali_commission = $request->amount * ($store_contract->taxa) / 100;
        else
            $imali_commission = 0;

        $points = round($request->amount);

        // Efectuar o Pagamento..
        try {
            DB::beginTransaction();

            // retirar o valor a pagar do saldo do User que esta a pagar
            $accountPayer->balance -= $request->amount;
            $accountPayer->update();


            if ($request->has('is_real_payment') && $request->is_real_payment) {
                // adicionar o valor retirado na conta do accountPayer no balance da Loja
                $store_account->balance += $request->amount - $imali_commission;
                $store_account->update();
            }

            // Criar pagamento
            $created_payment = $this->create_payment_transaction(null, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points);

            // criar dependencias de pagamentos
            $this->create_payment_dependences($userPayer, $created_payment, $accountPayer, $request, $imali_commission, $points);

            // envio de notificacoes
            $this->send_payment_notifications($request, $store_contract, $userPayer, $accountPayer, $created_payment);

            DB::commit();

            Log::info('Outgoing Response Success', [
                'message' => 'Transaction Successfull'
            ]);

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        } catch (\Throwable $th) {

            DB::rollBack();

            Log::info('Outgoing Response Error', [
                'content' => $th->getMessage()
            ]);

            // Escrever no ficheiro de log as mensagens de erro.
            return response()->json(['message' => 'Falha no pagamento', $th->getMessage()], 500);
        }
    }
    //? Payment With SubAccounts

    public function makePaymentStoreApp2024(Request $request)
    {

        //return response()->json(['message' => "Chegou"], 404);

        //Log::info('Outgoing Response', [
        //    'content' => $request->all(),
        //]);

        // QR Static
        // QR Dynamic
        // QR Store Number
        //? Payment by Link
        // Reembolso
        // Payment Push

        $this->validate($request, [
            'account_number' => 'required',
            'amount' => 'required'
        ]);

        $request->request->add(['is_real_payment' => true]);

        // Indentificar se o pagamento ja existe e o seu estado e rejected ou expired
        $generated_payment = Payment::query()->where('transaction_id', $request->transaction)->first();
        if (($generated_payment && $generated_payment->status === 'rejected') || ($generated_payment && $generated_payment->status === 'expired') || ($generated_payment && $generated_payment->status === 'success')) return response()->json(['message' => trans('payment_invalid'), 'status' => 401], 406);

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;

        // return 'Validou tudo!';

        // Buscar dados do User que faz a transacao
        $userPayer = User::getUserDetails(auth()->user()->id);

        // Buscar dados da conta do User que faz a transacao
        $accountPayer = User::getAccountByUser($userPayer->id, $userPayer->account_id);
        // return $accountPayer;
        $accountPayerOld = User::getAccountByUser($userPayer->id, $userPayer->account_id);

        // Validar KYC do userPayer
        $kyc = new UserKyc($userPayer);
        $kycResp = $kyc->checkSenderKYC($request->amount);
        if ($kycResp->getStatusCode() != 200) return $kycResp;


        // Validacao do saldo do User
        $kycRespBalance = $kyc->checkUserBalance($request->amount);
        if ($kycRespBalance->getStatusCode() != 200) return $kycRespBalance;

        if (User::is_subAccount($request->account_number)) {
            $sub_a = User::getAccount($request->account_number);
            $st = Store::query()->where('id', $sub_a->store_id)->first();

            $store_account_old = Store::getStoreAccount($st->account_number);
            $store_account = Store::getStoreAccount($st->account_number);
            $store_contract = Store::getStoreContractsAndConfigs($st->account_number);

            $request->request->add(['sub_account_number' => $request->account_number]);
        } else {

            // Buscar a loja onde se fara o pagamento
            $store_account_old = Store::getStoreAccount($request->account_number);
            $store_account = Store::getStoreAccount($request->account_number);
            $store_contract = Store::getStoreContractsAndConfigs($request->account_number);
        }

        // Buscar a loja onde se fara o pagamento
        //$store_account_old = Store::getStoreAccount($request->account_number);
        //$store_account = Store::getStoreAccount($request->account_number);
        //$store_contract = Store::getStoreContractsAndConfigs($request->account_number);
        $sub_account = null;
        $sub_account_old = null;

        // VERIFICAR SE ESTA A SER ENVIDO O CARD NUMBER
        if ($request->has('sub_account_number')) {
            //if ($request->has('sub_account_number')) {
            $sub_account = User::getAccount($request->sub_account_number);
            $sub_account_old = User::getAccount($request->sub_account_number);
            if (!$sub_account) return response()->json(['message' => 'Subconta invalida'], 400);

            //if ($sub_account->sub_account_types_id != 7) return response()->json(['message' => 'A tua subconta deve ser do tipo Cartao'], 400);

            //if ($sub_account->store_id != $store_account->id) return response()->json(['message' => 'Numero de Comerciante/Loja invalido'], 400);

            $subC_type = SubAccountType::query()->where('id', $sub_account->sub_account_types_id)->where('type_id', 'NFC_CARD')->first();

            if (!$subC_type) return response()->json(['message' => 'A tua subconta deve ser do tipo Cartao'], 400);
        }

        //validar KYC da Loja
        $storeKyc = new StoreKyc($store_contract);

        $respStoreKyc = $storeKyc->checkStoreKYC($request->amount);
        if ($respStoreKyc->getStatusCode() != 200) return $respStoreKyc;

        // Calculos para efectuar pagamento
        $imali_commission = $request->amount * ($store_contract->taxa) / 100;
        $points = round($request->amount);

        // Efectuar o Pagamento..
        try {
            DB::beginTransaction();

            // retirar o valor a pagar do saldo do User que esta a pagar
            $accountPayer->balance -= $request->amount;
            $accountPayer->update();

            // adicionar o valor retirado na conta do accountPayer no balance da Loja
            $store_account->balance += ($request->amount - $imali_commission);
            $store_account->update();

            // VERIFICAR SE ESTA A SER ENVIDO O CARD NUMBER
            // se existir uma subconta entao sera feito o credito do valor na loja e credito "ficticio" na subconta
            // no acto de pagamento via cartao e feito debito na subonta e o credito a zero "0" na loja 
            //if ($request->has('sub_account_number')) {
            if ($request->has('sub_account_number')) {

                $sub_account->balance += $request->amount;
                $sub_account->update();
            }

            // Criar pagamento
            //$created_payment = $this->create_payment_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $imali_commission, $points);
            $created_payment = $this->create_payment_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points, $sub_account, $sub_account_old);

            // criar dependencias de pagamentos
            $this->create_payment_dependences($userPayer, $created_payment, $accountPayer, $request, $imali_commission, $points);

            // envio de notificacoes
            $this->send_payment_notifications($request, $store_contract, $userPayer, $accountPayer, $created_payment);

            DB::commit();

            return response()->json([
                'message' => trans('payment_done'),
                'transaction' => $created_payment->transaction_id,
                'created_at' => $created_payment->created_at
            ]);
        } catch (\Throwable $th) {

            DB::rollBack();

            // Escrever no ficheiro de log as mensagens de erro.
            return response()->json(['message' => 'Falha no pagamento', $th->getMessage()], 500);
        }
    }

    //private function create_payment_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $imali_commission, $points)
    private function create_payment_transaction($generated_payment, $request, $userPayer, $accountPayer, $accountPayerOld, $store_account, $store_account_old, $imali_commission, $points, $sub_account = null, $sub_account_old = null)
    {
        $created_payment = new Payment();

        // Registar o pagamento na tabela de Payment
        if ($generated_payment) {

            $generated_payment->update([
                'received_points' => $points,
                'amount_credited' => $request->amount,
                'comissao' => $imali_commission,
                'description' => $request->description,
                'used_points' => $request->used_points,
                'estado' => 'success',
                'status' => 'success',
                'estado_color' => '#388E3C',
                'sender_id' => $userPayer->id,
                'old_balance' => $accountPayerOld->balance,
                'new_balance' => $accountPayer->balance
            ]);

            $created_payment = $generated_payment;
        } else {

            if ($request->has('is_real_payment') && $request->is_real_payment) {

                $new_payment = Payment::create([
                    'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                    'partner_transaction_id' => $request->partner_transaction_id,
                    'terminalID' => $request->terminal_id,
                    'sender_id' => $userPayer->id,
                    'sender_name' => $userPayer->name,
                    'sender_account_number' => $accountPayer->account_number,
                    'sender_card_number' => $accountPayer->card_number,
                    //'sender_card_number' => $sub_account?$sub_account->card_number:null,
                    'store_id' => $store_account->id,
                    'received_points' => $points,
                    'amount' => $request->amount,
                    'amount_debited' => $request->amount,
                    'amount_credited' => $request->amount - $imali_commission,
                    'comissao' => $imali_commission,
                    'description' => $request->description,
                    'used_points' => $request->used_points,
                    'estado' => 'success',
                    'status' => 'success',
                    'payment_type' => 'directo',
                    'estado_color' => '#388E3C',
                    'old_balance' => $accountPayerOld->balance,
                    'new_balance' => $accountPayer->balance,
                    'old_store_balance' => $store_account_old->balance,
                    'new_store_balance' => $store_account->balance,
                    'category_id' => $store_account->industry_activity,

                    'transaction_type' => 'debit',
                    'transaction_name' => 'Pagamento'
                ]);

                if ($request->has('sub_account_number')) {
                    Payment::create([
                        'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                        'partner_transaction_id' => $request->partner_transaction_id,
                        'terminalID' => $request->terminal_id,
                        'sender_id' => $userPayer->id,
                        'sender_name' => $userPayer->name,
                        'sender_account_number' => $accountPayer->account_number,
                        'sender_card_number' => $sub_account ? $sub_account->card_number : null,
                        'store_id' => $store_account->id,
                        'received_points' => $points,
                        'amount' => $request->amount,
                        'amount_debited' => $request->amount,
                        'amount_credited' => $request->amount - $imali_commission,
                        'comissao' => $imali_commission,
                        'description' => $request->description,
                        'is_real_payment' => 0,
                        'used_points' => $request->used_points,
                        'estado' => 'success',
                        'status' => 'success',
                        'payment_type' => 'directo',
                        'estado_color' => '#388E3C',
                        'old_balance' => $accountPayerOld->balance,
                        'new_balance' => $accountPayer->balance,
                        'old_store_balance' => $store_account_old->balance,
                        'new_store_balance' => $store_account->balance,
                        'category_id' => $store_account->industry_activity,

                        'transaction_type' => 'credit',
                        'transaction_name' => 'Depósito',
                    ]);
                }
            } else {
                $new_payment = Payment::create([
                    'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                    'partner_transaction_id' => $request->partner_transaction_id,
                    'terminalID' => $request->terminal_id,
                    'sender_id' => $userPayer->id,
                    'sender_name' => $userPayer->name,
                    'sender_account_number' => $accountPayer->account_number,
                    'sender_card_number' => $accountPayer->card_number,
                    'store_id' => $store_account->id,
                    'received_points' => $points,
                    'amount' => $request->amount,
                    'amount_debited' => $request->amount,
                    'amount_credited' => $request->amount,
                    'comissao' => $imali_commission,
                    'description' => $request->description,
                    'is_real_payment' => 0,
                    'used_points' => $request->used_points,
                    'estado' => 'success',
                    'status' => 'success',
                    'payment_type' => 'directo',
                    'estado_color' => '#388E3C',
                    'old_balance' => $accountPayerOld->balance,
                    'new_balance' => $accountPayer->balance,
                    'old_store_balance' => $store_account_old->balance,
                    'new_store_balance' => $store_account->balance,
                    'category_id' => $store_account->industry_activity,

                    'transaction_type' => 'debit',
                    'transaction_name' => 'Pagamento',
                ]);
            }

            if ($request->has('sub_account_number') && $sub_account != null) {

                PrepaidCardDeposit::create([
                    'transaction_id' => $this->trasactionGeneration->generateTransaction(),
                    'payment_transaction_id' => $new_payment->transaction_id,
                    'imali_account_number' => $accountPayer->account_number,
                    'imali_sub_account_number' => $sub_account->account_number,
                    'store_account_number' => $store_account->account_number,
                    'imali_account_id' => $accountPayer->id,
                    'imali_sub_account_id' => $sub_account->id,
                    'store_id' => $store_account->id,
                    'last_unreal_balance' => $sub_account_old->balance,
                    'unreal_balance' => $sub_account->balance,
                    'unreal_amount_credited' => $request->amount,
                    'real_amount_debited' => $request->amount,
                    'real_amount_credited' => $request->amount - $imali_commission
                ]);
            }

            $created_payment = $new_payment;
        }

        return $created_payment;
    }


    // TODO -- 15-Setembro-2024
    private function send_payment_notifications($request, $store_contract, $userPayer, $accountPayer, $created_payment)
    {

        // notificar o utilizador que fez o pagamento
        $push_userPayer = new PushNotification(
            //'Depósito de ' . $request->amount . ' MT',
            $request->has('sub_account_number') && $request->sub_account_number ? ' Depósito de ' . $request->amount . ' MT' : 'Pagamento de ' . $request->amount . ' MT',
            // 'Parabéns, ' . $request->has('sub_account_number')?' Fez o depósito de ' . $request->amount . ' MT ' . ' na tua subconta ' . $request->sub_account_number: ' fez o pagamento de ' . $request->amount . ' MT ' . ' na loja ' . $store_contract->name,
            'Parabéns, ' . ($request->has('sub_account_number') && $request->sub_account_number ? 'fez o depósito de ' . $request->amount . ' MT na tua subconta ' . $request->sub_account_number : 'fez o pagamento de ' . $request->amount . ' MT na loja ' . $store_contract->name),
            //'Parabéns, ' . ' fez o pagamento de ' . $request->amount . ' MT ' . ' na loja ' . $store_contract->name,
            $userPayer->firebase_token,
            'com.imali.payapp.payment_PAGAR_NOTIFICATION'
        );

        $push_store = new PushNotification(
            'Pagamento ' . $request->amount . ' MT',
            'Parabéns, ' . ' recebeu o pagamento de ' . $request->amount . ' MT ' . ' do cliente ' . $userPayer->name,
            $store_contract->firebase_token,
            'mz.co.imali.business.payment_TARGET_NOTIFICATION',
            'https://imali.co.mz/wp-content/uploads/2022/04/iMali-Business-Logo.png'
        );

        $data = $this->get_notification_data($request, $userPayer, $store_contract, $created_payment, $accountPayer);

        // Notificar o user que fez pagamento
        $push_userPayer->sendPush($data);

        // Notificar a loja que recebeu o pagamento
        $this->send_notification_store($store_contract, $push_store, $data, $created_payment);
    }

    // TODO -- 15-Setembro-2024
    private function get_notification_data($request, $userPayer, $store_contract, $created_payment, $accountPayer)
    {
        $category = RamoActivity::find($store_contract->industry_activity);

        $data = array(
            'transaction' => $created_payment->transaction_id,
            'loja' => $store_contract->name,
            'name' => $userPayer->name,
            'loja_account' => $store_contract->account_number,
            'pontos' => $created_payment->received_points,
            'pontos_usados' => $created_payment->used_points,
            'amount' => $created_payment->amount,
            'amount_debited' => $created_payment->amount_credited,
            'amount_credited' => $created_payment->amount_credited,
            'account_number' => $accountPayer->account_number,
            'phone' => $userPayer->phone,
            'descricao' => $created_payment->description,
            'data' => $created_payment->created_at,
            'created_at' => $created_payment->created_at,
            'estado' => $created_payment->estado,
            'comissao' => $created_payment->comissao,
            'message_store' => trans('payment_received'),
            'message_customer' => trans('payment_done'),
            'logo_category' => $category->logo,
            'category' => $category->nome,
            'route' => 'PAGAR_NOTIFICATION',
            'terminal' => 'firebase'
        );

        return $data;
    }

    // TODO -- 15-Setembro-2024
    private function send_notification_store($store_contract, $push_store, $push_data, $created_payment)
    {

        if ($store_contract->notify) {

            // envia push se estiver activo
            if ($store_contract->notify_push) {
                $push_store->sendPush($push_data);
            }

            // envia sms se estiver activo
            if ($store_contract->notify_sms) {

                $sms = new SendSMSSislog();

                $data = array(
                    "sender_id" => $created_payment->sender_id,
                    "store_id" => $created_payment->store_id,
                    "transaction_id" => $created_payment->transaction_id,
                    "created_at" => $created_payment->created_at,
                    "amount" => $created_payment->amount,
                );
                $sms->sendSMSToComerciante($data);
            }
        }
    }


    public function makePaymentStore(Request $request)
    {

        $user = User::find($request->user()->id);

        if (Hash::check($request->pin, $user->pin)) {
            $trasactionGeneration = new TransactionGeneration();

            $payerUser = User::query()->where('user_id', '=', $request->user()->user_id)->first();
            $store = Store::query()->where('account_number', '=', $request->account_number)->first();
            $payer_id = $payerUser->id;

            $imali = ImaliAccount::query()->where('user_id', '=', $payer_id)->first();
            $kyc = new Kyc();
            $kycCheck = $kyc->checkSenderPayment($request);

            if ($kycCheck) {
                $log = new Record();
                $log->createLog([
                    'description' => $imali->account_number . ' ' . $store->name,
                    'details' => $kycCheck,
                    'operation' => 'Payment',
                    //                    'properties' => $request->all(),
                    'properties' => json_encode($request->except(['pin'])),
                    'status' => 'Error',
                    'user_id' => $request->user()->id
                ]);

                return $kycCheck;
            } else {
                if ($payerUser) {
                    if ($imali->balance < $request->amount) {

                        $log = new Record();
                        $log->createLog([
                            'description' => $imali->account_number . ' ' . $store->name,
                            'details' => 'Saldo Insuficiente',
                            'operation' => 'Payment',
                            //                            'properties' => $request->all(),
                            'properties' => json_encode($request->except(['pin'])),
                            'status' => 'Error',
                            'user_id' => $request->user()->id
                        ]);

                        return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402, [], JSON_NUMERIC_CHECK);
                    } else {
                        $valorAPagar = $request->amount;
                        $points = round($valorAPagar);

                        // Payer or Sender Section
                        DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
                        DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

                        $contractoComerciante = MerchantContract::query()->where('store_id', '=', $store->id)->first();

                        $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                        $valorMin = $contractoComerciante->min_amount;
                        $valorMax = $contractoComerciante->max_amount;

                        if ($taxaDesconto < $valorMin) {
                            $taxaDesconto = $valorMin;
                        }
                        if ($taxaDesconto > $valorMax) {
                            $taxaDesconto = $valorMax;
                        }

                        //                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                        $valorFinal = $valorAPagar - $taxaDesconto;

                        // Recever User Merchante
                        DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);

                        // Add Money to Merchant
                        //                        $storeT = Store::query()->where('account_number', $store->account_number)->first();
                        //                        DB::table('merchant_accounts')->where('id', $storeT->merchant_account_id)->increment('balance', $valorFinal);


                        //                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

                        $transaction = $trasactionGeneration->generateTransaction();

                        $createTransaction = Payment::create([
                            'transaction_id' => $transaction,
                            'sender_id' => $payer_id,
                            'store_id' => $store->id,
                            'client_id' => $request->user_client_id,
                            'received_points' => $points,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'description' => $request->description,
                            'used_points' => $request->used_points,
                            'estado' => 'pago',
                            'payment_type' => 'directo',
                            'estado_color' => '#388E3C',
                            'created_at' => now(),
                            'updated_at' => now(),
                            'category_id' => $store->industry_activity
                        ]);

                        TransactionHistory::create([
                            'user_id' => $request->user()->id,
                            'payment_id' => $createTransaction->id,
                            'category_id' => $createTransaction->category_id,
                            'transaction_type' => 'payment'
                        ]);


                        $actualPoints = $imali->points + $points;
                        $re = $createTransaction->paymentHistoric()->create([
                            'sender_account' => $imali->account_number,
                            'sender_name' => $payerUser->name,
                            'amount_credited' => $valorFinal,
                            'status_user' => 'sender',
                            'status' => 'done',
                            'comissao' => $taxaDesconto,
                            'amount' => $valorAPagar,
                            'user_id' => $payerUser->id,
                            'actual_points' => $actualPoints,
                            'last_points' => $imali->points,
                            'win_points' => $points,
                            'transaction_id' => $transaction,
                            'category_id' => $store->industry_activity
                        ]);

                        //                        TransactionHistory::create([
                        //                            'user_id' => $re->user_id,
                        //                            'payment_id' => $re->id,
                        //                            'category_id' => $re->category_id,
                        //                            'transaction_type' => 'payment'
                        //                        ]);


                        $saveProfit = $createTransaction->profit()->create([
                            'payer_id' => $payer_id,
                            'payer_account' => $store->account_number,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'profit_id' => $trasactionGeneration->generateTransaction(),
                            'payment_id' => $createTransaction->id,
                            'profit_payer_id' => $createTransaction->store_id
                        ]);
                        if ($saveProfit) {


                            $generate = StoreAmountGeneration::query()
                                ->where('id', '=', $request->store_amount_generation_id)
                                ->first();

                            if ($generate) {

                                $generate->update([
                                    'status' => 'sucesso',
                                    'payment_id' => $createTransaction->id
                                ]);

                                $createTransaction->update([
                                    'store_amount_generation_id' => $generate->id
                                ]);
                            }


                            $log = new Record();
                            $log->createLog([
                                'description' => $imali->account_number . ' ' . $store->name,
                                'details' => 'Pagamento Feito com Sucesso',
                                'operation' => 'Payment',
                                //                                'properties' => $request->all(),
                                'properties' => json_encode($request->except(['pin'])),
                                'status' => 'Success',
                                'user_id' => $request->user()->id
                            ]);

                            $notification = array(
                                //                                'icon' => 'ic_imali_logo_verde_01',
                                'icon' => 'ic_i_mali_cover',
                                'title' => 'Pagamento ' . $request->amount . ' MT',
                                'body' => 'Parabéns, ' . ' fez o pagamento de ' . $request->amount . ' MT ' . ' na loja ' . $store->name,
                                'click_action' => 'com.imali.payapp.payment_PAGAR_NOTIFICATION',
                                //                            'color' => '#008577'
                                'color' => '#ffffff'
                            );

                            $notificationStore = array(
                                'icon' => 'ic_imali_logo_verde_01',
                                //                                'image' => 'https://paytek-africa.com/image/logo.png',
                                'image' => 'https://imali.co.mz/wp-content/uploads/2022/04/iMali-Business-Logo.png',
                                //                            'icon' => 'ic_i_mali_cover',
                                'title' => 'Pagamento ' . $request->amount . ' MT',
                                'body' => 'Parabéns, ' . ' recebeu o pagamento de ' . $request->amount . ' MT ' . ' do cliente ' . $user->name,
                                'click_action' => 'mz.co.imali.business.payment_TARGET_NOTIFICATION',
                                //                            'color' => '#008577'
                                'color' => '#ffffff'
                            );


                            $store = Store::query()->where('account_number', $request->account_number)->first();

                            $category = RamoActivity::find($store->industry_activity);
                            $data = array(
                                'transaction' => $createTransaction->transaction_id,
                                'loja' => $store->name,
                                'name' => $user->name,
                                'loja_account' => $store->account_number,
                                'pontos' => $createTransaction->received_points,
                                'pontos_usados' => $createTransaction->used_points,
                                'amount' => $createTransaction->amount,
                                'amount_debited' => $createTransaction->amount_credited,
                                'amount_credited' => $createTransaction->amount_credited,
                                'account_number' => $imali->account_number,
                                'phone' => $request->user()->phone,
                                'descricao' => $createTransaction->description,
                                'data' => $createTransaction->created_at,
                                'created_at' => $createTransaction->created_at,
                                'estado' => $createTransaction->estado,
                                'comissao' => $createTransaction->comissao,
                                'message_store' => 'Pagamento Recebido Com Sucesso',
                                'message_customer' => 'Pagamento Efectuado Com Sucesso',
                                'logo_category' => $category->logo,
                                'category' => $category->nome,
                                'route' => 'TARGET_NOTIFICATION',
                                'terminal' => 'firebase'
                            );


                            // Notifify customer
                            $this->pushNotifification($user->firebase_token, $notification, $data);


                            $storeConfig = StoreConfig::query()
                                ->where('store_id', '=', $store->id)
                                //                                ->where('store_id', '=', $createTransaction->store_id)
                                ->first();

                            if ($storeConfig) {

                                if ($storeConfig->notify === 1) {

                                    // NOTIFICAR POR SMS
                                    if ($storeConfig->notify_sms === 1) {

                                        //                                        $sms = new SendSMS();
                                        //                                        $sms->sendMessageToClientePayment($createTransaction);
                                        //                                        $sms->sendMessageToComerciante($createTransaction);
                                        //                                        $sms->sendMessageToClientePayment($payerUser);

                                        $this->smsManager->sendSMSToComerciante($createTransaction);
                                    }

                                    if ($storeConfig->notify_email == 1) {
                                        //                                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
                                        //                                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));
                                    }

                                    // NOTIFY STORE
                                    if ($storeConfig->notify_push == 1) {

                                        if ($generate) {
                                            $this->pushNotifification($generate->firebase_token, $notificationStore, $data);
                                        } else {
                                            $device = StoreDevice::query()
                                                ->where('store_id', $store->id)
                                                ->where('status', '=', 1)
                                                ->get();

                                            foreach ($device as $d) {
                                                $this->pushNotifification($d->firebase_token, $notificationStore, $data);
                                            }
                                        }
                                    }
                                }
                            }

                            return response()->json([
                                'message' => 'Pagamento Efectuado com Sucesso!',
                                'transaction' => $transaction,
                                'created_at' => $createTransaction->created_at,
                                'duration' => 3000
                            ], 200);
                        }
                    }
                }
            }
        } else {
            return response()->json(['message' => 'Pin Incorrecto'], 400);
        }
    }

    public function makePaymentStore2NEW(Request $request)
    {

        DB::transaction(function ($request) {

            $trasactionGeneration = new TransactionGeneration();

            $payerUser = User::query()->where('user_id', $request->user()->user_id)->first();
            $store = Store::query()->where('account_number', $request->account_number)->first();
            $payer_id = $payerUser->id;

            $imali = ImaliAccount::query()->where('user_id', $payer_id)->first();
            $kyc = new Kyc();
            $kycCheck = $kyc->checkSenderPayment($request);

            if ($kycCheck) {

                $log = new Record();
                $log->createLog([
                    'description' => $imali->account_number . ' ' . $store->name,
                    'details' => $kycCheck,
                    'operation' => 'Payment',
                    'status' => 'Error',
                    //                    'properties' => $request->all(),
                    'properties' => json_encode($request->except(['pin'])),
                    'user_id' => $request->user()->id
                ]);

                return $kycCheck;
            } else {
                if ($payerUser) {
                    if ($imali->balance < $request->amount) {

                        $log = new Record();
                        $log->createLog([
                            'description' => $imali->account_number . ' ' . $store->name,
                            'details' => 'Saldo Insuficiente',
                            'operation' => 'Payment',
                            'status' => 'Error',
                            //                            'properties' => $request->all(),
                            'properties' => json_encode($request->except(['pin'])),
                            'user_id' => $request->user()->id
                        ]);

                        return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402, [], JSON_NUMERIC_CHECK);
                    } else {
                        $valorAPagar = $request->amount;
                        $points = round($valorAPagar);

                        // Payer or Sender Section
                        DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
                        DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

                        $contractoComerciante = MerchantContract::query()->where('store_id', $store->id)->first();

                        $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                        $valorMin = $contractoComerciante->min_amount;
                        $valorMax = $contractoComerciante->max_amount;

                        if ($taxaDesconto < $valorMin) {
                            $taxaDesconto = $valorMin;
                        }
                        if ($taxaDesconto > $valorMax) {
                            $taxaDesconto = $valorMax;
                        }

                        //                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                        $valorFinal = $valorAPagar - $taxaDesconto;

                        // Recever User Merchante
                        DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);

                        //                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

                        $transaction = $trasactionGeneration->generateTransaction();

                        $createTransaction = Payment::create([
                            'transaction_id' => $transaction,
                            'sender_id' => $payer_id,
                            'store_id' => $store->id,
                            'client_id' => $request->user_client_id,
                            'received_points' => $points,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'description' => $request->description,
                            'used_points' => $request->used_points,
                            'estado' => 'pago',
                            'estado_color' => '#388E3C',
                            'created_at' => now(),
                            'updated_at' => now(),
                            'category_id' => $store->industry_activity
                        ]);
                        //                    TransactionHistory::create([
                        //                        'user_id' => $request->user()->id,
                        //                        'payment_id' => $createTransaction->id,
                        //                        'category_id' => $createTransaction->category_id,
                        //                        'transaction_type' => 'payment'
                        //                    ]);

                        $actualPoints = $imali->points + $points;
                        $res = $createTransaction->paymentHistoric()->create([
                            'sender_account' => $imali->account_number,
                            'sender_name' => $payerUser->name,
                            'amount_credited' => $valorFinal,
                            'status_user' => 'sender',
                            'status' => 'done',
                            'comissao' => $taxaDesconto,
                            'amount' => $valorAPagar,
                            'user_id' => $payerUser->id,
                            'actual_points' => $actualPoints,
                            'last_points' => $imali->points,
                            'win_points' => $points,
                            'transaction_id' => $transaction,
                            'category_id' => $createTransaction->category_id
                        ]);
                        //                    TransactionHistory::create([
                        //                        'user_id' => $res->user_id,
                        //                        'payment_id' => $res->id,
                        //                        'category_id' => $res->category_id,
                        //                        'transaction_type' => 'payment'
                        //                    ]);

                        $saveProfit = $createTransaction->profit()->create([
                            'payer_id' => $payer_id,
                            'payer_account' => $store->account_number,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'profit_id' => $trasactionGeneration->generateTransaction(),
                            'payment_id' => $createTransaction->id,
                        ]);
                        if ($saveProfit) {

                            $this->smsManager->sendSMSToComerciante($createTransaction);
                            //                        $sms = new SendSMS();
                            //                        $sms->sendMessageToClientePayment($createTransaction);
                            //                        $sms->sendMessageToComerciante($createTransaction);
                            //                    $sms->sendMessageToClientePayment($payerUser);
                            //                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
                            //                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));


                            $generate = StoreAmountGeneration::query()
                                ->where('id', $request->store_amount_generation_id)
                                ->first();

                            if ($generate) {

                                $generate->update([
                                    'status' => 'sucesso'
                                ]);
                            }


                            $log = new Record();
                            $log->createLog([
                                'description' => $imali->account_number . ' ' . $store->name,
                                'details' => 'Pagamento Feito com Sucesso',
                                'operation' => 'Payment',
                                'status' => 'Success',
                                //                                'properties' => $request->all(),
                                'properties' => json_encode($request->except(['pin'])),
                                'user_id' => $request->user()->id
                            ]);

                            return response()->json([
                                'message' => 'Pagamento Feito com Sucesso!',
                                'transaction' => $transaction,
                                'created_at' => $createTransaction->created_at,
                                'duration' => 3000
                            ], 200);
                        }
                    }
                }
            }
        });
    }

    public function makePaymentStore2(Request $request)
    {
        $trasactionGeneration = new TransactionGeneration();
        //        $payerUser = User::query()->where('user_id', $request->user_id)->first();
        $payerUser = User::query()->where('user_id', '=', $request->user()->user_id)->first();
        $user = User::find($request->user()->id);
        //        $comerciante = MerchantAccount::query()->where('account_number', $request->account_number)->first();
        $store = Store::query()->where('account_number', '=', $request->account_number)->first();
        $payer_id = $payerUser->id;

        $imali = ImaliAccount::query()->where('user_id', $payer_id)->first();
        $kyc = new Kyc();
        $kycCheck = $kyc->checkSenderPayment($request);

        if ($kycCheck) {

            $log = new Record();
            $log->createLog([
                'description' => $imali->account_number . ' ' . $store->name,
                'details' => $kycCheck,
                'operation' => 'Payment',
                'status' => 'Error',
                //                'properties' => $request->all(),
                'properties' => json_encode($request->except(['pin'])),
                'user_id' => $request->user()->id
            ]);

            return $kycCheck;
        } else {
            if ($payerUser) {
                if ($imali->balance < $request->amount) {

                    $log = new Record();
                    $log->createLog([
                        'description' => $imali->account_number . ' ' . $store->name,
                        'details' => 'Saldo Insuficiente',
                        'operation' => 'Payment',
                        'status' => 'Error',
                        //                        'properties' => $request->all(),
                        'properties' => json_encode($request->except(['pin'])),
                        'user_id' => $request->user()->id
                    ]);

                    return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402, [], JSON_NUMERIC_CHECK);
                } else {
                    $valorAPagar = $request->amount;
                    $points = round($valorAPagar);

                    // Payer or Sender Section
                    DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
                    DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

                    $contractoComerciante = MerchantContract::query()->where('store_id', $store->id)->first();

                    $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                    $valorMin = $contractoComerciante->min_amount;
                    $valorMax = $contractoComerciante->max_amount;

                    if ($taxaDesconto < $valorMin) {
                        $taxaDesconto = $valorMin;
                    }
                    if ($taxaDesconto > $valorMax) {
                        $taxaDesconto = $valorMax;
                    }

                    //                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                    $valorFinal = $valorAPagar - $taxaDesconto;

                    // Recever User Merchante
                    DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);

                    // Add Money to Merchant
                    //                    $storeT = Store::query()->where('account_number', $store->account_number)->first();
                    //                    DB::table('merchant_accounts')->where('id', $storeT->merchant_account_id)->increment('balance', $valorFinal);

                    //                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

                    $transaction = $trasactionGeneration->generateTransaction();

                    $createTransaction = Payment::create([
                        'transaction_id' => $transaction,
                        'sender_id' => $payer_id,
                        'store_id' => $store->id,
                        'client_id' => $request->user_client_id,
                        'received_points' => $points,
                        'amount' => $valorAPagar,
                        'amount_credited' => $valorFinal,
                        'comissao' => $taxaDesconto,
                        'description' => $request->description,
                        'used_points' => $request->used_points,
                        'estado' => 'pago',
                        'estado_color' => '#388E3C',
                        'payment_type' => 'directo',
                        'created_at' => now(),
                        'updated_at' => now(),
                        'category_id' => $store->industry_activity
                    ]);
                    TransactionHistory::create([
                        'user_id' => $request->user()->id,
                        'payment_id' => $createTransaction->id,
                        'category_id' => $createTransaction->category_id,
                        'transaction_type' => 'payment'
                    ]);

                    $actualPoints = $imali->points + $points;
                    $res = $createTransaction->paymentHistoric()->create([
                        'sender_account' => $imali->account_number,
                        'sender_name' => $payerUser->name,
                        'amount_credited' => $valorFinal,
                        'status_user' => 'sender',
                        'status' => 'done',
                        'comissao' => $taxaDesconto,
                        'amount' => $valorAPagar,
                        'user_id' => $payerUser->id,
                        'actual_points' => $actualPoints,
                        'last_points' => $imali->points,
                        'win_points' => $points,
                        'transaction_id' => $transaction,
                        'category_id' => $createTransaction->category_id
                    ]);
                    TransactionHistory::create([
                        'user_id' => $res->user_id,
                        'payment_id' => $res->id,
                        'category_id' => $res->category_id,
                        'transaction_type' => 'payment'
                    ]);

                    $saveProfit = $createTransaction->profit()->create([
                        'payer_id' => $payer_id,
                        'payer_account' => $store->account_number,
                        'amount' => $valorAPagar,
                        'amount_credited' => $valorFinal,
                        'comissao' => $taxaDesconto,
                        'profit_id' => $trasactionGeneration->generateTransaction(),
                        'payment_id' => $createTransaction->id,
                    ]);
                    if ($saveProfit) {

                        //                        $sms = new SendSMSSislog();
                        //                        $sms->sendSMSToComerciante($createTransaction);


                        //                        $sms = new SendSMS();
                        //                        $sms->sendMessageToClientePayment($createTransaction);
                        //                        $sms->sendMessageToComerciante($createTransaction);
                        //                    $sms->sendMessageToClientePayment($payerUser);
                        //                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
                        //                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));


                        $generate = StoreAmountGeneration::query()
                            ->where('id', $request->store_amount_generation_id)
                            ->first();

                        if ($generate) {
                            $generate->update([
                                'status' => 'sucesso',
                                'payment_id' => $createTransaction->id
                            ]);

                            $createTransaction->update([
                                'store_amount_generation_id' => $generate->id
                            ]);
                        }


                        $log = new Record();
                        $log->createLog([
                            'description' => $imali->account_number . ' ' . $store->name,
                            'details' => 'Pagamento Feito com Sucesso',
                            'operation' => 'Payment',
                            'status' => 'Success',
                            //                            'properties' => $request->all(),
                            'properties' => json_encode($request->except(['pin'])),
                            'user_id' => $request->user()->id
                        ]);

                        $notification = array(
                            //                            'icon' => 'ic_imali_logo_verde_01',
                            'icon' => 'ic_i_mali_cover',
                            //                            'icon' => 'ic_i_mali_cover',
                            'title' => 'Pagamento ' . $request->amount . ' MT',
                            'body' => 'Parabéns, ' . ' fez o pagamento de ' . $request->amount . ' MT ' . ' na loja ' . $store->name,
                            'click_action' => 'com.imali.payapp.payment_PAGAR_NOTIFICATION',
                            //                            'color' => '#008577'
                            'color' => '#ffffff'
                        );

                        $notificationStore = array(
                            'icon' => 'ic_imali_logo_verde_01',
                            //                            'icon' => 'ic_i_mali_cover',
                            'title' => 'Pagamento ' . $request->amount . ' MT',
                            //                            'image' => 'https://paytek-africa.com/image/logo.png',
                            'image' => 'https://imali.co.mz/wp-content/uploads/2022/04/iMali-Business-Logo.png',
                            'body' => 'Parabéns, ' . ' recebeu o pagamento de ' . $request->amount . ' MT ' . ' do cliente ' . $user->name,
                            'click_action' => 'mz.co.imali.business.payment_TARGET_NOTIFICATION',
                            //                            'color' => '#008577'
                            'color' => '#ffffff'
                        );

                        $store = Store::query()->where('account_number', $request->account_number)->first();
                        $category = RamoActivity::find($store->industry_activity);
                        $data = array(
                            'transaction' => $createTransaction->transaction_id,
                            'loja' => $store->name,
                            'name' => $user->name,
                            'loja_account' => $store->account_number,
                            'pontos' => $createTransaction->received_points,
                            'pontos_usados' => $createTransaction->used_points,
                            'amount' => $createTransaction->amount,
                            'amount_debited' => $createTransaction->amount_credited,
                            'amount_credited' => $createTransaction->amount_credited,
                            'account_number' => $imali->account_number,
                            'phone' => $request->user()->phone,
                            'descricao' => $createTransaction->description,
                            'data' => $createTransaction->created_at,
                            'created_at' => $createTransaction->created_at,
                            'estado' => $createTransaction->estado,
                            'comissao' => $createTransaction->comissao,
                            'message_store' => 'Pagamento Recebido Com Sucesso',
                            'message_customer' => 'Pagamento Efectuado Com Sucesso',
                            'logo_category' => $category->logo,
                            'category' => $category->nome,
                            'route' => 'TRANSFER_DETAILS',
                            'terminal' => 'firebase'
                        );

                        //                        $this->pushNotifification($user->firebase_token, $notification, $data);
                        //
                        //                        if ($generate) {
                        //                            $this->pushNotifification($generate->firebase_token, $notificationStore, $data);
                        //                        }
                        //
                        //                        $device = StoreDevice::query()
                        //                            ->where('store_id', $store->id)
                        //                            ->where('status', '=', 1)
                        //                            ->get();
                        //
                        //                        foreach ($device as $d) {
                        //                            $this->pushNotifification($d->firebase_token, $notificationStore, $data);
                        //                        }

                        // NOTIFY CUSTOMER
                        $this->pushNotifification($user->firebase_token, $notification, $data);


                        $storeConfig = StoreConfig::query()
                            ->where('store_id', '=', $store->id)
                            ->first();

                        if ($storeConfig) {

                            if ($storeConfig->notify == 1) {

                                // NOTIFICAR POR SMS
                                if ($storeConfig->notify_sms == 1) {

                                    //                                        $sms = new SendSMS();
                                    //                                        $sms->sendMessageToClientePayment($createTransaction);
                                    //                                        $sms->sendMessageToComerciante($createTransaction);
                                    //                                        $sms->sendMessageToClientePayment($payerUser);

                                    $this->smsManager->sendSMSToComerciante($createTransaction);
                                }

                                if ($storeConfig->notify_email == 1) {
                                    //                                    Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
                                    //                                    Mail::to($payerUser->email)->send(new Pagamento($createTransaction));
                                }

                                if ($storeConfig->notify_push == 1) {

                                    if ($generate) {
                                        $this->pushNotifification($generate->firebase_token, $notificationStore, $data);
                                    } else {

                                        $device = StoreDevice::query()
                                            ->where('store_id', $store->id)
                                            ->where('status', '=', 1)
                                            ->get();

                                        foreach ($device as $d) {
                                            $this->pushNotifification($d->firebase_token, $notificationStore, $data);
                                        }
                                    }
                                }
                            }
                        }

                        return response()->json([
                            'message' => 'Pagamento Feito com Sucesso!',
                            'transaction' => $transaction,
                            'created_at' => $createTransaction->created_at,
                            'duration' => 3000
                        ], 200);
                    }
                }
            }
        }
    }

    public function transferMoney(Request $request)
    {

        $usr = User::query()->join('imali_accounts', 'imali_accounts.user_id', 'users.id')->where('imali_accounts.account_number', $request->account_number)->first();

        //? teste
        $kyc = new Kyc();
        $request->request->add(['id' => $request->user()->id, 'receiver_id' => $usr->id]);
        $resultKYC = $kyc->checkSender($request);
        //? teste

        if (Hash::check($request->pin, auth()->user()->pin)) {
            $random = new TransactionGeneration();

            $senderUser = User::query()->where('user_id', $request->user()->user_id)->first();
            $sender_id = $senderUser->id;

            $imaliAccountSender = ImaliAccount::query()->where('user_id', $senderUser->id)->first();
            $imaliAccountReceiver = ImaliAccount::query()->where('account_number', $request->account_number)->first();
            $imaliAccountReceiverCount = ImaliAccount::query()->where('account_number', $request->account_number)->count();


            $kyc = ImaliAccount::query()
                ->join('imali_account_configs', 'imali_account_configs.id', '=', 'imali_accounts.imali_account_config')
                ->where('user_id', $senderUser->id)
                ->select('imali_account_configs.*')
                ->first();

            $payments = Payment::query()
                ->where(['sender_id' => $senderUser->id])
                ->whereDate('created_at', date('Y-m-d'))
                ->get();


            //        $recevier = User::query()->where('id', $imaliAccountReceiver->user_id)->count();

            if ($imaliAccountReceiverCount > 0) {
                $recevier = User::query()->where('id', $imaliAccountReceiver->user_id)->first();

                // $kyc = new Kyc();

                $request->request->add(['id' => $senderUser->id, 'receiver_id' => $recevier->id]);
                // return response()->json(['message' => 'Não pode Transferir para si mesmo!', 'class' => 'error'], 400);
                // $result = $kyc->checkSender($request);

                // $result = $kyc->checkSender($request);
                $result = $resultKYC;

                if ($result) {

                    $log = new Record();
                    $log->createLog([
                        'description' => 'Transfer Money',
                        'details' => $result,
                        'operation' => 'Transfer Money',
                        'status' => 'Error',
                        'origin_ip' => $request->ip(),
                        'properties' => json_encode($request->except(['pin'])),
                        //                        'properties' => json_encode($request->all()),
                        'origin_request' => $request->url(),
                        'user_id' => $request->user()->id
                    ]);


                    return $result;
                } else {
                    if ($imaliAccountSender) {
                        if ($imaliAccountReceiver->user_id === $imaliAccountSender->user_id) {

                            //                            $log = new Record();
                            //                            $log->createLog([
                            //                                'description' => $imaliAccountSender->account_number,
                            //                                'details' => 'Não pode Transferir para Si mesmo' . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                            //                                'operation' => 'Transfer Money',
                            //                                'status' => 'Error',
                            //                                'user_id' => $request->user()->id
                            //                            ]);

                            $log = new Record();
                            $log->createLog([
                                'description' => 'Não pode Transferir para Si mesmo',
                                'details' => 'Não pode Transferir para Si mesmo',
                                'operation' => 'Transfer Money',
                                'properties' => json_encode($request->except(['pin'])),
                                'status' => 'Error',
                                'origin_ip' => $request->ip(),
                                'origin_request' => $request->url(),
                                'user_id' => $request->user()->id
                            ]);


                            return response()->json(['message' => 'Não pode Transferir para si mesmo!', 'class' => 'error'], 400);
                        } elseif ($imaliAccountSender->balance < $request->amount) {


                            $log = new Record();
                            $log->createLog([
                                'description' => 'Saldo insuficiente',
                                'details' => 'Saldo Insuficiente',
                                'operation' => 'Transfer Money',
                                //                                'properties' => $request->all(),
                                'properties' => json_encode($request->except(['pin'])),
                                'status' => 'Error',
                                'origin_ip' => $request->ip(),
                                'origin_request' => $request->url(),
                                'user_id' => $request->user()->id
                            ]);

                            return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402);
                        } else {

                            $valorAPagar = $request->amount;
                            $points = round($valorAPagar);
                            $imaliAccountConfig = ImaliAccountConfig::find(1);


                            //                $valorTaxadoTotal = $valorAPagar + $valorAPagar*($imaliAccountConfig->taxa)/100;
                            $valorTaxadoTotal = $valorAPagar + $imaliAccountConfig->taxa;
                            // Payer or Sender Section
                            DB::table('imali_accounts')->where('user_id', $sender_id)->decrement('balance', $valorTaxadoTotal);


                            // Recever User
                            DB::table('imali_accounts')->where('account_number', $imaliAccountReceiver->account_number)->increment('balance', $valorAPagar);

                            //                $profit = $valorAPagar*$valorAPagar*($imaliAccountConfig->taxa)/100;
                            $profit = $imaliAccountConfig->taxa;

                            $transactionReference = $random->generateTransaction();

                            $imaliAccountSender2 = ImaliAccount::query()->where('user_id', $senderUser->id)->first();

                            $transferencia = Transfer::create([
                                'transaction_id' => $transactionReference,
                                'sender_id' => $sender_id,
                                'reciever_id' => $recevier->id,
                                'reciever_name' => $recevier->name,
                                'reciever_account' => $imaliAccountReceiver->account_number,
                                'amount' => $valorAPagar,
                                'description' => $request->description,
                                'comissao' => $profit,
                                'estado_color' => '#388E3C',
                                'estado' => 'Pago',
                                'amount_debited' => $valorTaxadoTotal,
                                'created_at' => now(),
                                'updated_at' => now(),
                                'category_id' => 22,

                                'old_balance' => $imaliAccountSender->balance,
                                'new_balance' => $imaliAccountSender2->balance
                            ]);

                            TransactionHistory::create([
                                'user_id' => $transferencia->sender_id,
                                'transfer_id' => $transferencia->id,
                                'category_id' => $transferencia->category_id,
                                'transaction_type' => 'transfer'
                            ]);

                            $senderHistory = TransferHistory::create([
                                'transaction_id' => $transactionReference,
                                'user_id' => $senderUser->id,
                                //                            'account_number' =>$imaliAccountReceiver->account_number,
                                'client_id' => $recevier->id,
                                'amount' => $valorAPagar,
                                'description' => $request->description,
                                'comissao' => $profit,
                                'estado_color' => '#388E3C',
                                'estado' => 'Pago',
                                'user_status' => 'payer',
                                'amount_debited' => $valorTaxadoTotal,
                                'created_at' => now(),
                                'updated_at' => now(),
                                'category_id' => $transferencia->category_id
                            ]);

                            TransactionHistory::create([
                                'user_id' => $senderHistory->user_id,
                                'transfer_history_id' => $senderHistory->id,
                                'category_id' => $senderHistory->category_id,
                                'transaction_type' => 'transfer_history'
                            ]);

                            $receiverHistory = TransferHistory::create([
                                'transaction_id' => $transactionReference,
                                'user_id' => $recevier->id,
                                //                            'account_number' =>$imaliAccountSender->account_number,
                                'client_id' => $senderUser->id,
                                'amount' => $valorAPagar,
                                'description' => $request->description,
                                'comissao' => 0,
                                'estado_color' => '#388E3C',
                                'estado' => 'Recebido',
                                'user_status' => 'receiver',
                                'amount_debited' => 0,
                                'created_at' => now(),
                                'updated_at' => now(),
                                'category_id' => $transferencia->category_id
                            ]);
                            TransactionHistory::create([
                                'user_id' => $receiverHistory->user_id,
                                'transfer_history_id' => $receiverHistory->id,
                                'category_id' => $receiverHistory->category_id,
                                'transaction_type' => 'transfer_history'
                            ]);

                            //                $transferencia->paymentHistoric()->create([
                            //                    'sender_account' =>$imaliAccountSender->account_number,
                            //                    'sender_name' => $senderUser->name,
                            //                    'amount_credited' => $valorTaxadoTotal,
                            //                    'status_user' => 'reciever',
                            //                    'status' => 'done',
                            //                    'comissao' => $profit,
                            //                    'amount' =>$valorAPagar,
                            //                    'sender_id' => $senderUser->id,
                            //                    'user_id' => $recevier->id,
                            //                    'actual_points' =>$recevier->points,
                            //                    'last_points' =>$recevier->points,
                            //                    'win_points' => 0,
                            //                    'transaction_id' =>$transferencia->transaction_id
                            //                ]);


                            $saveProfit = $transferencia->profit()->create([
                                'payer_id' => $senderUser->id,
                                'payer_account' => $imaliAccountSender->account_number,
                                'amount' => $valorAPagar,
                                'amount_credited' => $valorTaxadoTotal,
                                'comissao' => $profit,
                                'profit_id' => $transactionReference,
                                'payment_id' => $transferencia->id,
                                'transfer_id' => $request->user()->id
                            ]);
                            //                            $sms = new SendSMS();
                            //                            $sms->sendSMSTransferSender($transferencia);
                            //                            $sms->sendSMSTranferReceiver($transferencia);
                            $recevier2 = User::query()->where('id', $imaliAccountReceiver->user_id)->first();


                            $notification = array(
                                //                                'icon' => 'ic_i_mali_cover',
                                'icon' => 'ic_imali_logo_verde_01',
                                'title' => 'Recebeste ' . $request->amount . ' MT',
                                'body' => 'Parabéns, ' . 'recebeste ' . $request->amount . 'MT ' . 'do ' . $request->user()->name,
                                'click_action' => 'com.imali.payapp.payment_TRANSFER_DETAILS',
                                //                                'color' => '#008577'
                                'color' => '#ffffff'
                            );

                            $data = array(
                                'transaction' => $receiverHistory->transaction_id,
                                'name' => $request->user()->name,
                                'amount' => (float)$senderHistory->amount,
                                'amount_debited' => (float)$receiverHistory->amount_debited,
                                //                                'amount_credited' => (double)$receiverHistory->amount_credited,
                                'account_number' => (int)$imaliAccountSender->account_number,
                                'phone' => $request->user()->phone,
                                'description' => $request->description,
                                'data' => $receiverHistory->created_at,
                                'estado' => $receiverHistory->estado,
                                'route' => 'TRANSFER_DETAILS',
                                'comissao' => (float)$receiverHistory->comissao,
                                'terminal' => 'firebase'
                            );

                            $this->pushNotifification($recevier2->firebase_token, $notification, $data);

                            if ($request->id_request != 0) {

                                $moneyR = MoneyRequest::query()->where('id', $request->id_request)->first();
                                if ($moneyR) {
                                    $moneyR->update([
                                        'status' => 'sucesso'
                                    ]);
                                }
                            }


                            if ($saveProfit) {
                                $log = new Record();
                                $log->createLog([
                                    'description' => 'SenderAccount: ' . $imaliAccountSender->account_number . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                                    'details' => 'Transferência feita com Sucesso',
                                    'operation' => 'Transfer Money',
                                    //                                    'properties' => $request->all(),
                                    'properties' => json_encode($request->except(['pin'])),
                                    'status' => 'Success',
                                    'origin_ip' => $request->ip(),
                                    'origin_request' => $request->url(),
                                    'user_id' => $request->user()->id
                                ]);


                                return response()->json([
                                    'message' => 'Transferência Feita com Sucesso!',
                                    'transaction' => $transactionReference,
                                    'created_at' => $transferencia->created_at
                                ], 200);
                            }
                        }
                    }
                }
            } else {


                $log = new Record();
                $log->createLog([
                    'description' => 'SenderAccount: ' . $imaliAccountSender->account_number . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                    'details' => 'Conta i.Mali inválida',
                    'operation' => 'Transfer Money',
                    //                    'properties' => $request->all(),
                    'properties' => json_encode($request->except(['pin'])),
                    'status' => 'Error',
                    'origin_ip' => $request->ip(),
                    'origin_request' => $request->url(),
                    'user_id' => $request->user()->id
                ]);

                return response()->json(['message' => 'Conta i.Mali inválida', 'class' => 'error'], 404);
            }
        } else {
            return response()->json(['message' => 'Pin Incorrecto'], 400);
        }
    }

    // todo new Method transfer 17-April-2024 *

    public function transferMoneyNew2024ORIGINALISSIMO(Request $request)
    {
        // return $request->all();

        // $app = new GenerateImaliAccount();
        // return $app->generateSubImaliAccount();
        Log::info('Incoming Transfer with PIN', [
            'content' => $request->all(),
        ]);

        // $val_resp = $this->makeValidations($request);

        $this->validate($request, [
            'account_number' => 'required',
            'amount' => 'required',
            //'imali_transac_type' => 'required'
        ]);

        // todo MIGUEL deve implementar esse campo ao fazer-se a transferencia na proxima versao

        $request->request->add(['imali_transac_type' => 'TRANSAC_C2C_TRANSFERENCIA']);

        // $userReceiver = User::getUserDetails(User::getAccount($request->account_number)->user_id);
        $accountReceiver = User::getAccount($request->account_number);
        $accountReceiverOld = User::getAccount($request->account_number);
        $userReceiver = User::getUserDetails($accountReceiver->user_id); //! novo metodo substituido 
        // todo -- Identificar se a conta que vai receber é conta BUSINESS... 🍩

        if ($request->has('id_request') && $request->id_request && ($request->id_request !== 'request_id')) {
            $pedido = MoneyRequest::query()->where('id', $request->id_request)->first();

            $userReceiver = User::getUserDetails($pedido->user_id); //! novo metodo substituido

            if (!$pedido) return response()->json(['message' => 'Pedido invalido!'], 400);
            // if ($pedido->user_id == auth()->user()->id) return response()->json(['message' => 'Nao pode aceitar um pedido feito por ti mesmo!'], 400);
            if ($pedido->status === 'sucesso') return response()->json(['message' => 'Esse pedido ja foi aceite.'], 400);
        }

        $tariff = ImaliTariff::query()->where('abbreviation', $request->imali_transac_type)->first();
        if (!$tariff) return response()->json(['message' => 'Codigo de transacao invalida.'], 400);

        //! --------
        // Buscar dados do User que faz a transacao
        // return $request->user();
        // return $totalKeys = count($request->user()->getAttributes());

        if ($request->has('complete_debit') && $request->complete_debit == 'COMPLETE_DEBIT') {

            $userSender = User::getUserDetails($request->user()->user_id);
        } else {
            $userSender = User::getUserAccount(); // todo -- Identificar se a conta que vai enviar é conta CLIENTE... 🍩
        }

        // Buscar dados da conta do User que faz a transacao
        $accountSender = User::getAccountByUser($userSender->id, $userSender->account_id);
        $accountSenderOld = User::getAccountByUser($userSender->id, $userSender->account_id);

        //? Se o user que esta a transferir for CLIENTE para BUSINESS ❌
        if ($userSender->profile == 'client' && $userReceiver->profile == 'business') return SendResponse::errorResp404notfound('Transação não autorizada', 'Unauthorized transaction');
        //? Se o user que esta a transferir for CLIENTE para BUSINESS ❌


        $kyc = new UserKyc($userSender);
        $kycSenderResp = $kyc->checkSenderKYC($request->amount);
        if ($kycSenderResp->getStatusCode() != 200) return $kycSenderResp;

        // verificacao do KYC e Saldo de Origem
        $kycSenderResp = $kyc->checkUserBalance($request->amount);
        if ($kycSenderResp->getStatusCode() != 200) return $kycSenderResp;

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;


        if ($request->has('wallets_id')) {
            return $this->createWithDrawalls2024($request, $userSender, $accountSender, $accountSenderOld);
        }


        // return $accountReceiver;

        // verificacao do KYC e Saldo de Destino
        $kyc = new UserKyc($userReceiver);
        $kycReceiverResp = $kyc->checkReceiverKYC($request->amount);
        if ($kycReceiverResp->getStatusCode() != 200) return $kycReceiverResp;

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;

        //! --------

        // validar se esta a ser envido o valor para si mesmo
        if ($accountSender->id == $accountReceiver->id) return response()->json(['message' => 'Não podes enviar dinheiro para ti mesmo.'], 400);

        // realizacao de debito na conta de origem e credito na conta de destino
        try {
            DB::beginTransaction();

            $total_amount = ImaliTariff::getImaliTotalAmount($request->amount, $userReceiver->profile, $tariff->fee_type, $tariff->fee);
            $incoming_value = ImaliTariff::getImalIncoming($request->amount, $userReceiver->profile, $tariff->fee_type, $tariff->fee);

            // retirada do valor da conta de quem envia
            $accountSender->balance -= $total_amount;
            $accountSender->update();

            // creditar valor da conta de quem recebe
            $accountReceiver->balance += $request->amount;
            $accountReceiver->update();

            // Registar a transacao de transferencia | Envio de Dinheiro
            $random = new TransactionGeneration();
            $transactionReference = $random->generateTransaction();

            $transferencia = Transfer::create([
                'transaction_id' => $transactionReference,
                'sender_id' => $userSender->id,
                'sender_account' => $accountSender->account_number,
                'sender_name' => $userSender->name,
                'sender_account_type' => $userSender->profile,
                'reciever_id' => $userReceiver->id,
                'reciever_account' => $accountReceiver->account_number,
                'reciever_name' => $userReceiver->name,
                'amount' => $request->amount,
                'imali_fee' => 0,
                'imali_cost' => 0,
                // 'description' => 'TRF. iMali',
                'description' => 'TRF. iMali de ' . $userSender->name . ' para ' . $userReceiver->name,
                'estado' => 'Pago',
                'status' => 'success',
                'old_balance' => $accountSenderOld->balance,
                'new_balance' => $accountSender->balance,
                'total_amount' => $total_amount,
                'commission' => $incoming_value,
                'comissao' => $incoming_value,
                'stamp_tax' => 0,
                'amount_debited' => $total_amount,
                'imali_transac_type' => $tariff->abbreviation
            ]);


            $senderHistory = TransferHistory::create([
                'transaction_id' => $transactionReference,

                'sender_account' => $userSender->account_number,
                'reciever_account' => $userReceiver->account_number,

                'user_id' => $userSender->id,
                'client_id' => $userReceiver->id,

                'amount' => $request->amount,
                'comissao' => $incoming_value,
                'estado_color' => '#388E3C',
                'estado' => 'Pago',
                'user_status' => 'payer',
                'amount_debited' => $total_amount,
                'transaction_type' => 'debit',
                'transaction_name' => 'Transferência'
            ]);


            $receiverHistory = TransferHistory::create([
                'transaction_id' => $transactionReference,

                'sender_account' => $userReceiver->account_number,
                'reciever_account' => $userSender->account_number,

                'user_id' => $userReceiver->id,
                'client_id' => $userSender->id,

                'amount' => $request->amount,
                'description' => $request->description,
                'comissao' => $incoming_value,
                'estado_color' => '#388E3C',
                'estado' => 'Recebido',
                'user_status' => 'receiver',
                'amount_debited' => $total_amount,
                'transaction_type' => 'credit',
                'transaction_name' => 'Transferência'
            ]);


            TransactionHistory::create([
                'user_id' => $senderHistory->user_id,
                'transfer_history_id' => $senderHistory->id,
                'transaction_type' => 'transfer_history'
            ]);

            TransactionHistory::create([
                'user_id' => $receiverHistory->user_id,
                'transfer_history_id' => $receiverHistory->id,
                'transaction_type' => 'transfer'
            ]);
            // $bug=2/0;

            // DADOS DA TABELA ALLTRANSACTIONS

            // REGISTO DE DEBITO PARA O SENDER
            AllTransactionController::create_all_transaction(
                $transferencia->transaction_id,
                2,
                1,
                $userSender->name,
                $userSender->account_number,
                1,
                $userReceiver->name,
                $userReceiver->account_number,
                1,
                $transferencia->amount,
                'Transferencia iMali',
                $accountSenderOld->balance,
                $accountSender->balance,

                $accountReceiverOld->balance,
                $accountReceiver->balance,

                $transferencia->status,
                $transferencia->created_at,
                'DEBIT',
            );

            // REGISTO DE DEBITO PARA O RECEIVER
            AllTransactionController::create_all_transaction(
                $transferencia->transaction_id,
                2,
                1,
                $userSender->name,
                $userSender->account_number,
                1,
                $userReceiver->name,
                $userReceiver->account_number,
                1,
                $transferencia->amount,
                'Transferencia iMali',
                $accountSenderOld->balance,
                $accountSender->balance,

                $accountReceiverOld->balance,
                $accountReceiver->balance,

                $transferencia->status,
                $transferencia->created_at,
                'CREDIT',
            );
            // DADOS DA TABELA ALLTRANSACTIONS

            $notification = array(
                'icon' => 'ic_imali_logo_verde_01',
                'title' => 'Recebeste ' . $request->amount . ' MT',
                'body' => 'Parabéns, ' . 'recebeste ' . $request->amount . 'MT ' . 'do ' . $request->user()->name,
                'click_action' => 'com.imali.payapp.payment_TRANSFER_DETAILS',
                'color' => '#ffffff'
            );

            $data = array(
                'transaction' => $receiverHistory->transaction_id,
                'name' => $request->user()->name,
                'amount' => (float)$senderHistory->amount,
                'amount_debited' => (float)$receiverHistory->amount_debited,
                'account_number' => (int)$accountSender->account_number,
                'phone' => $request->user()->phone,
                'description' => $request->description,
                'data' => $receiverHistory->created_at,
                'estado' => $receiverHistory->estado,
                'route' => 'TRANSFER_DETAILS',
                'comissao' => (float)$receiverHistory->comissao,
                'terminal' => 'firebase'
            );

            if ($request->id_request != 0) {

                $moneyR = MoneyRequest::query()->where('id', $request->id_request)->first();
                if ($moneyR) {
                    $moneyR->update([
                        'status' => 'sucesso',
                        'new_balance' => $accountReceiver->balance
                    ]);
                }
            }

            $this->pushNotifification($userReceiver->firebase_token, $notification, $data);
            // $push_userPayer->sendPush($data);


            DB::commit();

            return response()->json([
                'message' => 'Transferência Feita com Sucesso!',
                'transaction' => $transactionReference,
                'created_at' => $transferencia->created_at
            ], 200);
        } catch (\Throwable $th) {
            DB::rollBack();
            // return response()->json(['message' => 'Erro do Servidor!', $th->getMessage()], 500);

            Log::info('Error TransferMoneyNEW2024', [
                'content' => $request->url(),
                'params' => $request->all(),
                'error' => $th,
            ]);

            return response()->json(['message' => 'Erro do Servidor!'], 500);
        }
    }

    public function accept_loans(Request $request)
    {
        $accept = BusinessAccount::query()
            ->where('accept_loans', 1)
            ->select(
                'id',
                'company_name as name',
                'account_number',
                'owner_name',
                'owner_phone',
                'owner_email',
                'business_type',
                'accept_loans'
            )
            ->orderBy('id', 'desc')
            // ->get();
            ->first();

        return response()->json([
            'data' => [$accept]
        ], 200);
    }

    public function pay_loans_payments(Request $request)
    {
        $transfers = Transfer::query()
            ->where('credit_request_ref', $request->credit_request)
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'data' => $transfers
        ], 200);
    }

    // todo NEW 07-11-2025
    public function pay_loans(Request $request)
    {
        try {
            $this->validate($request, [
                'credit_request' => 'required',
                'payment_type' => 'required|in:TOTAL,PARTIAL',
                'amount' => 'required_if:payment_type,PARTIAL',
            ]);

            $credit = \App\BusinessCreditRequest::query()
                ->join('begin_solicitations', 'begin_solicitations.id', 'business_credit_requests.dados_begin_solicitation')
                ->where('business_credit_requests.transaction_id', $request->credit_request)
                ->where('business_credit_requests.status', 'IN_PROGRESS')
                ->select('business_credit_requests.*', 'begin_solicitations.*')
                ->first();

            // return $credit;

            if (!$credit) {
                return response()->json([
                    'message' => 'Esta conta não tem empréstimo em andamento.'
                ], 404);
            }

            if ($request->payment_type === 'PARTIAL') {
                $request->request->add(['account_number' => $credit->provider_account]);
            } elseif ($request->payment_type === 'TOTAL') {

                $begin_solicitation_data = BeginSolicitation::find($credit->dados_begin_solicitation);

                // $request_account = User::getAccount($credit->request_account);
                $request->request->add(['account_number' => $credit->provider_account, 'amount' => $begin_solicitation_data->remaing_amount]);
            }

            $resp_transfer = $this->transferMoneyNew2024($request);

            if ($resp_transfer->getStatusCode() == 200) {

                $begin_solicitation = BeginSolicitation::find($credit->dados_begin_solicitation);
                $begin_solicitation->remaing_amount -= $request->amount;
                $begin_solicitation->paid_amount += $request->amount;
                $begin_solicitation->update();

                $begin_solicitation2 = BeginSolicitation::find($credit->dados_begin_solicitation);
                if ($begin_solicitation2 && $begin_solicitation2->remaing_amount == 0) {

                    $credit2 = \App\BusinessCreditRequest::query()
                        ->where('transaction_id', $request->credit_request)
                        ->where('status', 'IN_PROGRESS')
                        ->first();

                    $credit2->status = 'PAID';
                    $credit2->update();
                }
            }

            return $resp_transfer;
        } catch (\Throwable $th) {
            return response()->json([
                'message' => 'Erro interno ao processar pagamento de empréstimo.',
                'error_hint' => $th->getMessage()
            ], 500);
        }
    }

    public function transferMoneyNew2024(Request $request)
    {
        // return $request->all();
        // $app = new GenerateImaliAccount();
        // return $app->generateSubImaliAccount();
        Log::info('Incoming Transfer with PIN', [
            'content' => $request->all(),
        ]);

        // $val_resp = $this->makeValidations($request);

        $this->validate($request, [
            'account_number' => 'required',
            'amount' => 'required',
            //'imali_transac_type' => 'required'
        ]);

        // return "Passou";

        // todo MIGUEL deve implementar esse campo ao fazer-se a transferencia na proxima versao

        $request->request->add(['imali_transac_type' => 'TRANSAC_C2C_TRANSFERENCIA']);

        // $userReceiver = User::getUserDetails(User::getAccount($request->account_number)->user_id);
        $accountReceiver = User::getAccount($request->account_number);
        $accountReceiverOld = User::getAccount($request->account_number);
        $userReceiver = User::getUserDetails($accountReceiver->user_id); //! novo metodo substituido 
        // todo -- Identificar se a conta que vai receber é conta BUSINESS... 🍩

        if ($request->has('id_request') && $request->id_request && ($request->id_request !== 'request_id')) {
            $pedido = MoneyRequest::query()->where('id', $request->id_request)->first();

            $userReceiver = User::getUserDetails($pedido->user_id); //! novo metodo substituido

            if (!$pedido) return response()->json(['message' => 'Pedido invalido!'], 400);
            // if ($pedido->user_id == auth()->user()->id) return response()->json(['message' => 'Nao pode aceitar um pedido feito por ti mesmo!'], 400);
            if ($pedido->status === 'sucesso') return response()->json(['message' => 'Esse pedido ja foi aceite.'], 400);
        }

        $tariff = ImaliTariff::query()->where('abbreviation', $request->imali_transac_type)->first();
        if (!$tariff) return response()->json(['message' => 'Codigo de transacao invalida.'], 400);

        //! --------
        // Buscar dados do User que faz a transacao
        // return $request->user();
        // return $totalKeys = count($request->user()->getAttributes());

        if ($request->has('complete_debit') && $request->complete_debit == 'COMPLETE_DEBIT') {

            $userSender = User::getUserDetails($request->user()->user_id);
        } else {
            $userSender = User::getUserAccount(); // todo -- Identificar se a conta que vai enviar é conta CLIENTE... 🍩
        }

        // Buscar dados da conta do User que faz a transacao
        $accountSender = User::getAccountByUser($userSender->id, $userSender->account_id);
        $accountSenderOld = User::getAccountByUser($userSender->id, $userSender->account_id);

        //? Se o user que esta a transferir for CLIENTE para BUSINESS ❌
        if ($userSender->profile == 'client' && $userReceiver->profile == 'business') return SendResponse::errorResp404notfound('Transação não autorizada', 'Unauthorized transaction');
        //? Se o user que esta a transferir for CLIENTE para BUSINESS ❌


        $kyc = new UserKyc($userSender);
        $kycSenderResp = $kyc->checkSenderKYC($request->amount);
        if ($kycSenderResp->getStatusCode() != 200) return $kycSenderResp;

        // verificacao do KYC e Saldo de Origem
        $kycSenderResp = $kyc->checkUserBalance($request->amount);
        if ($kycSenderResp->getStatusCode() != 200) return $kycSenderResp;

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;


        if ($request->has('wallets_id')) {
            return $this->createWithDrawalls2024($request, $userSender, $accountSender, $accountSenderOld);
        }

        // return $accountReceiver;

        // verificacao do KYC e Saldo de Destino
        $kyc = new UserKyc($userReceiver);
        $kycReceiverResp = $kyc->checkReceiverKYC($request->amount);
        if ($kycReceiverResp->getStatusCode() != 200) return $kycReceiverResp;

        // Validar o PIN e Fingerprint do userPayer
        $auth = new ClassesAuth();
        $authResp = $auth->checkUserPinAndFingerprint($request);
        if ($authResp->getStatusCode() != 200) return $authResp;

        //! --------

        // validar se esta a ser envido o valor para si mesmo
        if ($accountSender->id == $accountReceiver->id) return response()->json(['message' => 'Não podes enviar dinheiro para ti mesmo.'], 400);

        // realizacao de debito na conta de origem e credito na conta de destino
        try {

            DB::beginTransaction();

            // return $total_amount;
            // return $request->all();
            $total_amount = ImaliTariff::getImaliTotalAmount($request->amount, $userReceiver->profile, $tariff->fee_type, $tariff->fee);

            $incoming_value = ImaliTariff::getImalIncoming($request->amount, $userReceiver->profile, $tariff->fee_type, $tariff->fee);

            // retirada do valor da conta de quem envia
            $accountSender->balance -= $total_amount;
            $accountSender->update();

            // creditar valor da conta de quem recebe
            $accountReceiver->balance += $request->amount;
            $accountReceiver->update();

            // Registar a transacao de transferencia | Envio de Dinheiro
            $random = new TransactionGeneration();
            $transactionReference = $random->generateTransaction();

            $transferencia = Transfer::create([
                'transaction_id' => $transactionReference,
                'sender_id' => $userSender->id,
                'sender_account' => $accountSender->account_number,
                'sender_name' => $userSender->name,
                'sender_account_type' => $userSender->profile,
                'reciever_id' => $userReceiver->id,
                'reciever_account' => $accountReceiver->account_number,
                'reciever_name' => $userReceiver->name,
                'amount' => $request->amount,
                'imali_fee' => 0,
                'imali_cost' => 0,
                // 'description' => 'TRF. iMali',
                'description' => 'TRF. iMali de ' . $userSender->name . ' para ' . $userReceiver->name,
                'estado' => 'Pago',
                'status' => 'success',
                'old_balance' => $accountSenderOld->balance,
                'new_balance' => $accountSender->balance,
                'total_amount' => $total_amount,
                'commission' => $incoming_value,
                'comissao' => $incoming_value,
                'stamp_tax' => 0,
                'amount_debited' => $total_amount,
                'imali_transac_type' => $tariff->abbreviation
            ]);


            $senderHistory = TransferHistory::create([
                'transaction_id' => $transactionReference,

                'sender_account' => $userSender->account_number,
                'reciever_account' => $userReceiver->account_number,

                'user_id' => $userSender->id,
                'client_id' => $userReceiver->id,

                'amount' => $request->amount,
                'comissao' => $incoming_value,
                'estado_color' => '#388E3C',
                'estado' => 'Pago',
                'user_status' => 'payer',
                'amount_debited' => $total_amount,
                'transaction_type' => 'debit',
                'transaction_name' => 'Transferência'
            ]);


            $receiverHistory = TransferHistory::create([
                'transaction_id' => $transactionReference,

                'sender_account' => $userReceiver->account_number,
                'reciever_account' => $userSender->account_number,

                'user_id' => $userReceiver->id,
                'client_id' => $userSender->id,

                'amount' => $request->amount,
                'description' => $request->description,
                'comissao' => $incoming_value,
                'estado_color' => '#388E3C',
                'estado' => 'Recebido',
                'user_status' => 'receiver',
                'amount_debited' => $total_amount,
                'transaction_type' => 'credit',
                'transaction_name' => 'Transferência'
            ]);


            TransactionHistory::create([
                'user_id' => $senderHistory->user_id,
                'transfer_history_id' => $senderHistory->id,
                'transaction_type' => 'transfer_history'
            ]);

            TransactionHistory::create([
                'user_id' => $receiverHistory->user_id,
                'transfer_history_id' => $receiverHistory->id,
                'transaction_type' => 'transfer'
            ]);
            // $bug=2/0;

            // DADOS DA TABELA ALLTRANSACTIONS

            // REGISTO DE DEBITO PARA O SENDER
            AllTransactionController::create_all_transaction(
                $transferencia->transaction_id,
                2,
                1,
                $userSender->name,
                $userSender->account_number,
                1,
                $userReceiver->name,
                $userReceiver->account_number,
                1,
                $transferencia->amount,
                'Transferencia iMali',
                $accountSenderOld->balance,
                $accountSender->balance,

                $accountReceiverOld->balance,
                $accountReceiver->balance,

                $transferencia->status,
                $transferencia->created_at,
                'DEBIT',
            );

            // REGISTO DE DEBITO PARA O RECEIVER
            AllTransactionController::create_all_transaction(
                $transferencia->transaction_id,
                2,
                1,
                $userSender->name,
                $userSender->account_number,
                1,
                $userReceiver->name,
                $userReceiver->account_number,
                1,
                $transferencia->amount,
                'Transferencia iMali',
                $accountSenderOld->balance,
                $accountSender->balance,

                $accountReceiverOld->balance,
                $accountReceiver->balance,

                $transferencia->status,
                $transferencia->created_at,
                'CREDIT',
            );
            // DADOS DA TABELA ALLTRANSACTIONS

            $notification = array(
                'icon' => 'ic_imali_logo_verde_01',
                'title' => 'Recebeste ' . $request->amount . ' MT',
                'body' => 'Parabéns, ' . 'recebeste ' . $request->amount . 'MT ' . 'do ' . $request->user()->name,
                'click_action' => 'com.imali.payapp.payment_TRANSFER_DETAILS',
                'color' => '#ffffff'
            );

            $data = array(
                'transaction' => $receiverHistory->transaction_id,
                'name' => $request->user()->name,
                'amount' => (float)$senderHistory->amount,
                'amount_debited' => (float)$receiverHistory->amount_debited,
                'account_number' => (int)$accountSender->account_number,
                'phone' => $request->user()->phone,
                'description' => $request->description,
                'data' => $receiverHistory->created_at,
                'estado' => $receiverHistory->estado,
                'route' => 'TRANSFER_DETAILS',
                'comissao' => (float)$receiverHistory->comissao,
                'terminal' => 'firebase'
            );

            if ($request->id_request != 0) {

                $moneyR = MoneyRequest::query()->where('id', $request->id_request)->first();
                if ($moneyR) {
                    $moneyR->update([
                        'status' => 'sucesso',
                        'new_balance' => $accountReceiver->balance
                    ]);
                }
            }

            // todo ----- CREDIT_REQUEST

            if ($request->has('credit_request') && !empty($request->credit_request)) {

                $accountSender->credit_balance -= $request->amount;
                $accountSender->update();

                // todo ----- new 12/11/2025
                $transferencia->credit_request_ref = $request->credit_request;
                $transferencia->update();
            }

            // todo ----- CREDIT_REQUEST

            $this->pushNotifification($userReceiver->firebase_token, $notification, $data);
            // $push_userPayer->sendPush($data);


            DB::commit();

            return response()->json([
                'message' => 'Transferência Feita com Sucesso!',
                'transaction' => $transactionReference,
                'created_at' => $transferencia->created_at
            ], 200);
        } catch (\Throwable $th) {
            DB::rollBack();
            // return response()->json(['message' => 'Erro do Servidor!', $th->getMessage()], 500);

            Log::info('Error TransferMoneyNEW2024', [
                'content' => $request->url(),
                'params' => $request->all(),
                'error' => $th,
            ]);

            return response()->json(['message' => 'Erro do Servidor!'], 500);
        }
    }

    public function transferMoney2(Request $request)
    {
        //        return $request->fullUrl();
        //        return $test;
        //        return $request->header();
        //        return $request->fullUrl();

        //        return $request->url();
        //        return Request::ip();
        //        return $request->ip();
        //return response()->json(['message' => 'Pagamento Feito com Sucesso!',
        //                     ], 200);     
        $random = new TransactionGeneration();

        $senderUser = User::query()->where('user_id', $request->user()->user_id)->first();
        $sender_id = $senderUser->id;

        $imaliAccountSender = ImaliAccount::query()->where('user_id', $senderUser->id)->first();
        $imaliAccountReceiver = ImaliAccount::query()->where('account_number', $request->account_number)->first();
        $imaliAccountReceiverCount = ImaliAccount::query()->where('account_number', $request->account_number)->count();


        $kyc = ImaliAccount::query()
            ->join('imali_account_configs', 'imali_account_configs.id', '=', 'imali_accounts.imali_account_config')
            ->where('user_id', $senderUser->id)
            ->select('imali_account_configs.*')
            ->first();

        $payments = Payment::query()
            ->where(['sender_id' => $senderUser->id])
            ->whereDate('created_at', date('Y-m-d'))
            ->get();

        //        $recevier = User::query()->where('id', $imaliAccountReceiver->user_id)->count();

        if ($imaliAccountReceiverCount > 0) {
            $recevier = User::query()->where('id', $imaliAccountReceiver->user_id)->first();

            $kyc = new Kyc();

            $request->request->add(['id' => $senderUser->id, 'receiver_id' => $recevier->id]);
            $result = $kyc->checkSender($request);

            if ($result) {

                $log = new Record();
                $log->createLog([
                    'description' => 'SenderAccount: ' . $imaliAccountSender->account_number . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                    'details' => $result,
                    'operation' => 'Transfer Money',
                    //                    'properties' => $request->all(),
                    'properties' => json_encode($request->except(['pin'])),
                    'status' => 'Error',
                    'origin_ip' => $request->ip(),
                    'origin_request' => $request->url(),
                    'user_id' => $request->user()->id
                ]);

                return $result;
            } else {
                if ($imaliAccountSender) {
                    if ($imaliAccountReceiver->user_id === $imaliAccountSender->user_id) {

                        $log = new Record();
                        $log->createLog([
                            'description' => $imaliAccountSender->account_number . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                            'details' => 'Não pode Transferir para Si mesmo',
                            'operation' => 'Transfer Money',
                            //                            'properties' => $request->all(),
                            'properties' => json_encode($request->except(['pin'])),
                            'status' => 'Error',
                            'origin_ip' => $request->ip(),
                            'origin_request' => $request->url(),
                            'user_id' => $request->user()->id
                        ]);

                        return response()->json(['message' => 'Não pode Transferir para si mesmo!', 'class' => 'error'], 400);
                    } elseif ($imaliAccountSender->balance < $request->amount) {
                        $log = new Record();
                        $log->createLog([
                            'description' => $imaliAccountSender->account_number . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                            'details' => 'Saldo insuficiente',
                            'operation' => 'Transfer Money',
                            //                            'properties' => $request->all(),
                            'properties' => json_encode($request->except(['pin'])),
                            'status' => 'Error',
                            'origin_ip' => $request->ip(),
                            'origin_request' => $request->url(),
                            'user_id' => $request->user()->id
                        ]);

                        return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402);
                    } else {

                        $valorAPagar = $request->amount;
                        $points = round($valorAPagar);
                        $imaliAccountConfig = ImaliAccountConfig::find(1);


                        //                $valorTaxadoTotal = $valorAPagar + $valorAPagar*($imaliAccountConfig->taxa)/100;
                        $valorTaxadoTotal = $valorAPagar + $imaliAccountConfig->taxa;
                        // Payer or Sender Section
                        DB::table('imali_accounts')->where('user_id', $sender_id)->decrement('balance', $valorTaxadoTotal);


                        // Recever User
                        DB::table('imali_accounts')->where('account_number', $imaliAccountReceiver->account_number)->increment('balance', $valorAPagar);

                        //                $profit = $valorAPagar*$valorAPagar*($imaliAccountConfig->taxa)/100;
                        $profit = $imaliAccountConfig->taxa;

                        $transactionReference = $random->generateTransaction();

                        $imaliAccountSender2 = ImaliAccount::query()->where('user_id', $senderUser->id)->first();

                        $transferencia = Transfer::create([
                            'transaction_id' => $transactionReference,
                            'sender_id' => $sender_id,
                            'reciever_id' => $recevier->id,
                            'reciever_name' => $recevier->name,
                            'reciever_account' => $imaliAccountReceiver->account_number,
                            'amount' => $valorAPagar,
                            'description' => $request->description,
                            'comissao' => $profit,
                            'estado_color' => '#388E3C',
                            'estado' => 'Pago',
                            'amount_debited' => $valorTaxadoTotal,
                            'created_at' => now(),
                            'updated_at' => now(),
                            'category_id' => 22,

                            'old_balance' => $imaliAccountSender->balance,
                            'new_balance' => $imaliAccountSender2->balance
                        ]);

                        TransactionHistory::create([
                            'user_id' => $transferencia->sender_id,
                            'transfer_id' => $transferencia->id,
                            'category_id' => $transferencia->category_id,
                            'transaction_type' => 'transfer'
                        ]);

                        $senderHistory = TransferHistory::create([
                            'transaction_id' => $transactionReference,
                            'user_id' => $senderUser->id,
                            //                            'account_number' =>$imaliAccountReceiver->account_number,
                            'client_id' => $recevier->id,
                            'amount' => $valorAPagar,
                            'description' => $request->description,
                            'comissao' => $profit,
                            'estado_color' => '#388E3C',
                            'estado' => 'Pago',
                            'user_status' => 'payer',
                            'amount_debited' => $valorTaxadoTotal,
                            'created_at' => now(),
                            'updated_at' => now(),
                            'category_id' => $transferencia->category_id
                        ]);
                        TransactionHistory::create([
                            'user_id' => $senderHistory->user_id,
                            'transfer_history_id' => $senderHistory->id,
                            'category_id' => $senderHistory->category_id,
                            'transaction_type' => 'transfer'
                        ]);


                        $receiverHistory = TransferHistory::create([
                            'transaction_id' => $transactionReference,
                            'user_id' => $recevier->id,
                            //                            'account_number' =>$imaliAccountSender->account_number,
                            'client_id' => $senderUser->id,
                            'amount' => $valorAPagar,
                            'description' => $request->description,
                            'comissao' => 0,
                            'estado_color' => '#388E3C',
                            'estado' => 'Recebido',
                            'user_status' => 'receiver',
                            'amount_debited' => 0,
                            'created_at' => now(),
                            'updated_at' => now(),
                            'category_id' => $transferencia->category_id
                        ]);
                        TransactionHistory::create([
                            'user_id' => $receiverHistory->user_id,
                            'transfer_history_id' => $receiverHistory->id,
                            'category_id' => $receiverHistory->category_id,
                            'transaction_type' => 'transfer'
                        ]);


                        //                $transferencia->paymentHistoric()->create([
                        //                    'sender_account' =>$imaliAccountSender->account_number,
                        //                    'sender_name' => $senderUser->name,
                        //                    'amount_credited' => $valorTaxadoTotal,
                        //                    'status_user' => 'reciever',
                        //                    'status' => 'done',
                        //                    'comissao' => $profit,
                        //                    'amount' =>$valorAPagar,
                        //                    'sender_id' => $senderUser->id,
                        //                    'user_id' => $recevier->id,
                        //                    'actual_points' =>$recevier->points,
                        //                    'last_points' =>$recevier->points,
                        //                    'win_points' => 0,
                        //                    'transaction_id' =>$transferencia->transaction_id
                        //                ]);


                        $saveProfit = $transferencia->profit()->create([
                            'payer_id' => $senderUser->id,
                            'payer_account' => $imaliAccountSender->account_number,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorTaxadoTotal,
                            'comissao' => $profit,
                            'profit_id' => $transactionReference,
                            'payment_id' => $transferencia->id,
                        ]);
                        //                            $sms = new SendSMS();
                        //                            $sms->sendSMSTransferSender($transferencia);
                        //                            $sms->sendSMSTranferReceiver($transferencia);

                        $recevier2 = User::query()->where('id', $imaliAccountReceiver->user_id)->first();
                        $notification = array(
                            'icon' => 'ic_imali_logo_verde_01',
                            //                            'icon' => 'ic_i_mali_cover',
                            'title' => 'Recebeste ' . $request->amount . ' MT',
                            'body' => 'Parabéns, ' . ' recebeste ' . $request->amount . ' MT ' . ' do ' . $request->user()->name,
                            'click_action' => 'com.imali.payapp.payment_TRANSFER_DETAILS',
                            //                            'color' => '#008577'
                            'color' => '#ffffff'
                        );

                        //                        $data = array(
                        //                            'transaction' => $receiverHistory->transaction_id,
                        //                            'name' => $request->user()->name,
                        //                            'amount' => $receiverHistory->amount,
                        //                            'amount_debited' => $receiverHistory->amount_debited,
                        //                            'account_number' => $request->account_number,
                        //                            'phone' => $request->user()->phone,
                        //                            'description' => $request->description,
                        //                            'data' => $receiverHistory->created_at,
                        //                            'estado' => $receiverHistory->estado,
                        //                            'comissao' => $receiverHistory->comissao,
                        //                        );

                        $data = array(
                            'transaction' => $receiverHistory->transaction_id,
                            'name' => $request->user()->name,
                            'amount' => (float)$senderHistory->amount,
                            'amount_debited' => (float)$receiverHistory->amount_debited,
                            'account_number' => (int)$imaliAccountSender->account_number,
                            'phone' => $request->user()->phone,
                            'description' => $request->description,
                            'data' => $receiverHistory->created_at,
                            'estado' => $receiverHistory->estado,
                            'route' => 'TRANSFER_DETAILS',
                            'comissao' => (float)$receiverHistory->comissao,
                            'terminal' => 'firebase'
                        );

                        $this->pushNotifification($recevier2->firebase_token, $notification, $data);

                        if ($request->id_request != 0) {

                            $moneyR = MoneyRequest::query()->where('id', $request->id_request)->first();
                            if ($moneyR) {
                                $moneyR->update([
                                    'status' => 'sucesso'
                                ]);
                            }
                        }


                        if ($saveProfit) {

                            $log = new Record();
                            $log->createLog([
                                'description' => $imaliAccountSender->account_number,
                                'details' => 'Transferência feita com Sucesso' . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                                'operation' => 'Transfer Money',
                                'status' => 'Success',
                                'properties' => json_encode($request->except(['pin'])),
                                'user_id' => $request->user()->id
                            ]);


                            $log->createLog([
                                'description' => $imaliAccountSender->account_number . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                                'details' => 'Transferência Feita com Sucesso!',
                                'operation' => 'Transfer Money',
                                //                                'properties' => $request->all(),
                                'properties' => json_encode($request->except(['pin'])),
                                'status' => 'Sucess',
                                'origin_ip' => $request->ip(),
                                'origin_request' => $request->url(),
                                'user_id' => $request->user()->id
                            ]);


                            return response()->json([
                                'message' => 'Transferência Feita com Sucesso!',
                                'transaction' => $transactionReference,
                                'created_at' => $transferencia->created_at
                            ], 200);
                        }
                    }
                }
            }
        } else {

            $log = new Record();
            $log->createLog([
                'description' => $imaliAccountSender->account_number,
                'details' => 'Conta i.Mali inválida' . ' ReceiverAccount: ' . $imaliAccountReceiver->account_number,
                'operation' => 'Transfer Money',
                //                'properties' => $request->all(),
                'properties' => json_encode($request->except(['pin'])),
                'status' => 'Error',
                'user_id' => $request->user()->id
            ]);

            return response()->json(['message' => 'Conta i.Mali inválida', 'class' => 'error'], 404);
        }
    }

    public function getPayments()
    {
        $payments = Payment::query()->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('stores', 'stores.id', 'payments.store_id')
            ->join('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
            ->orderBy('payments.created_at', 'desc')
            ->select('payments.*', 'users.name as client_name', 'stores.name as merchant_name', 'stores.account_number as merchant_account', 'imali_accounts.account_number as client_account')
            ->get();

        return response()->json(['data' => $payments], 200);
    }

    public function getMyPayments($id)
    {

        $payments = Payment::query()->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->join('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
            ->where('payments.sender_id', $id)
            ->orderBy('payments.created_at', 'desc')
            ->select('payments.*', 'users.name as client_name', 'stores.name as merchant_name', 'stores.account_number as merchant_account', 'imali_accounts.account_number as client_account')
            ->get();

        return response()->json(['data' => $payments], 200);
    }

    public function getMyPayments2(Request $request)
    {
        $size = (!request()->per_page) ? 4 : request()->per_page;

        $new_start_date  = null;
        $new_end_date  = null;

        if ($request->filled('start_date')) {
            $start_date = explode('-', $request->start_date);
            if (strlen($start_date[2]) >= 4)
                $new_start_date = $start_date[2] . '-' . $start_date[1] . '-' . $start_date[0];
        }

        if ($request->filled('end_date')) {
            $end_date = explode('-', $request->end_date);
            if (strlen($end_date[2]) >= 4)
                $new_end_date = $end_date[2] . '-' . $end_date[1] . '-' . $end_date[0];
        }

        // return $new_start_date;

        $payments = Payment::query()
            ->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->leftJoin('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
            ->leftJoin('business_accounts', 'business_accounts.user_id', 'payments.sender_id')
            //            ->join('ramo_activities', 'ramo_activities.id', 'payments.store_id')
            ->leftJoin('ramo_activities', 'ramo_activities.id', '=', 'payments.category_id')
            ->where('payments.sender_id', $request->user()->id)
            ->where('payments.is_real_payment', 1)
            // new ------------------------
            ->when($request->filled('start_date'), function ($query) use ($request, $new_start_date) {
                $query->whereDate('payments.created_at', '>=', $new_start_date ?? $request->start_date);
            })
            ->when($request->filled('end_date'), function ($query) use ($request, $new_end_date) {
                $query->whereDate('payments.created_at', '<=', $new_end_date ?? $request->end_date);
            })
            // new ------------------------
            ->orderBy('payments.created_at', 'desc')
            ->select(
                'payments.*',
                'users.name as client_name',
                'users.last_name',
                'stores.name as merchant_name',
                'stores.account_number as merchant_account',
                // 'imali_accounts.account_number as client_account',
                // 'business_accounts.account_number as client_account',
                DB::raw('COALESCE(imali_accounts.account_number, business_accounts.account_number) as client_account'),
                'ramo_activities.nome as category',
                'ramo_activities.logo as logo_category'
            )
            //->get();
            ->paginate($size);

        return response()->json($payments, 200);

        //return response()->json(['data' => $payments], 200);
    }

    public function getMyPayments3(Request $request)
    {

        $payments = Payment::query()
            ->join('users', 'users.id', '=', 'payments.sender_id')
            ->join('stores', 'stores.id', '=', 'payments.store_id')
            ->join('imali_accounts', 'imali_accounts.user_id', 'payments.sender_id')
            //            ->leftJoin('ramo_activities', 'ramo_activities.id','=', 'payments.store_id')
            ->leftJoin('ramo_activities', 'ramo_activities.id', '=', 'payments.category_id')
            //            ->where('payments.sender_id', $request->user()->id)
            ->where('payments.sender_id', '=', 1)
            ->orderBy('payments.created_at', 'desc')
            ->select(
                'payments.*',
                'users.name as client_name',
                'users.last_name',
                'stores.name as merchant_name',
                'stores.account_number as merchant_account',
                'imali_accounts.account_number as client_account',
                'ramo_activities.nome as category',
                'ramo_activities.logo as logo_category'
            )
            ->get();

        return response()->json(['data' => $payments], 200);
    }

    public function getTransferencias()
    {
        $transfers = Transfer::query()->join('users', 'users.id', '=', 'transfers.sender_id')
            ->join('imali_accounts', 'imali_accounts.user_id', 'transfers.sender_id')
            ->orderBy('transfers.created_at', 'desc')
            ->select('transfers.*', 'users.name as sender_name', 'imali_accounts.account_number as sender_account')
            ->get();
        return response()->json(['data' => $transfers], 200);
    }

    public function getMyTransferencias($id)
    {
        // $transfers = Transfer::query()->join('users', 'users.id', '=', 'transfers.sender_id')
        //     ->join('imali_accounts', 'imali_accounts.user_id', 'transfers.sender_id')
        //     ->where('transfers.sender_id', $id)
        //     ->orderBy('transfers.created_at', 'desc')
        //     ->select('transfers.*', 'users.name as sender_name', 'imali_accounts.account_number as sender_account')
        //     ->get();
        // return response()->json(['data' => $transfers], 200);

        $size = (!request()->per_page) ? 4 : request()->per_page;

        $withdrawals = WithdrawalsRequest::query()
            // ->where('user_id', $request->user()->id)
            ->where('user_id', $id)
            ->select(
                'withdrawals_requests.id as id',
                'withdrawals_requests.transaction_id as transaction_id',
                'withdrawals_requests.imali_account as imali_account',
                'withdrawals_requests.account_number as account_number',
                'withdrawals_requests.account_type as account_type',
                'withdrawals_requests.description as description',
                'withdrawals_requests.status as status',
                'withdrawals_requests.amount as amount',
                'withdrawals_requests.commission as commission',
                'withdrawals_requests.bank_fee as bank_fee',
                'withdrawals_requests.stamp_tax as stamp_tax',
                'withdrawals_requests.imali_fee as imali_fee',
                'withdrawals_requests.total as total',
                'withdrawals_requests.old_balance as old_balance',
                'withdrawals_requests.new_balance as new_balance',
                'withdrawals_requests.user_id as user_id',
                'withdrawals_requests.wallets_id as wallets_id',
                'withdrawals_requests.operators_id as operators_id',
                'withdrawals_requests.moza_message as moza_message',
                'withdrawals_requests.imali_account_id as imali_account_id',
                DB::raw("'NULL' as reciever_id"),
                DB::raw("'NULL' as reciever_account"),
                // DB::raw("'NULL' as reciever_name"),
                'withdrawals_requests.reciever_name as reciever_name',
                DB::raw("'NULL' as amount_debited"),
                DB::raw("'NULL' as estado_color"),
                DB::raw("'NULL' as category_id"),
                // DB::raw("'NULL' as sender_name"),
                'withdrawals_requests.sender_name as sender_name',
                'withdrawals_requests.created_at as created_at',
                'withdrawals_requests.updated_at as updated_at',
            )
            ->orderBy('withdrawals_requests.created_at', 'desc');

        $transfers = Transfer::query()
            ->join('users', 'users.id', '=', 'transfers.sender_id')
            ->join('imali_accounts', 'imali_accounts.user_id', 'transfers.sender_id')
            // ->where('transfers.sender_id', $request->user()->id)
            ->where('transfers.sender_id', $id)
            ->select(
                'transfers.id as id',
                'transfers.transaction_id as transaction_id',
                DB::raw("'NULL' as imali_account"),
                'imali_accounts.account_number as account_number',
                'users.profile as account_type',
                DB::raw("'TRF. iMali' as description"),
                'transfers.estado as status',
                'transfers.amount as amount',
                'transfers.comissao as commission',
                DB::raw("'0' as bank_fee"),
                DB::raw("'0' as stamp_tax"),
                DB::raw("'0' as imali_fee"),
                DB::raw("'0' as total"),
                'transfers.old_balance as old_balance',
                'transfers.new_balance as new_balance',
                'transfers.sender_id as user_id',
                DB::raw("'NULL' as wallets_id"),
                DB::raw("'NULL' as operators_id"),
                DB::raw("'No message' as moza_message"),
                DB::raw("'NULL' as imali_account_id"),
                'transfers.reciever_id as reciever_id',
                'transfers.reciever_account as reciever_account',
                'transfers.reciever_name as reciever_name',
                'transfers.amount_debited as amount_debited',
                'transfers.estado_color as estado_color',
                'transfers.category_id as category_id',
                'users.name as sender_name',
                'transfers.created_at as created_at',
                'transfers.updated_at as updated_at',

            )
            ->orderBy('transfers.created_at', 'desc');

        $results = $withdrawals->union($transfers)->paginate($size);


        return response()->json($results, 200);
    }

    public function getCarregamentos()
    {
        $carregamento = ImaliAccount::query()
            ->join('users', 'users.id', 'imali_accounts.user_id')
            ->join('recharge_imali_accounts', 'recharge_imali_accounts.imali_account_id', 'imali_accounts.id')
            ->orderBy('recharge_imali_accounts.created_at', 'desc')
            ->select('users.name as user_name', 'imali_accounts.account_number as user_account', 'recharge_imali_accounts.*')->get();
        return response()->json(['data' => $carregamento], 200);
    }

    public function getMyCarregamentos2($id)
    {
        $carregamento = ImaliAccount::query()
            ->join('users', 'users.id', 'imali_accounts.user_id')
            ->join('recharge_imali_accounts', 'recharge_imali_accounts.imali_account_id', 'imali_accounts.id')
            ->where('users.id', $id)
            ->orderBy('recharge_imali_accounts.created_at', 'desc')
            ->select('users.name as user_name', 'imali_accounts.reference', 'imali_accounts.account_number', 'recharge_imali_accounts.*')->get();
        return response()->json(['data' => $carregamento], 200);
    }

    public function getMyCarregamentos(Request $request)
    {
        //        $carregamento = ImaliAccount::query()
        //            ->join('users', 'users.id', 'imali_accounts.user_id')
        //            ->join('recharge_imali_accounts', 'recharge_imali_accounts.imali_account_id', 'imali_accounts.id')
        //            ->where('users.id', auth()->user()->id)
        //            ->orderBy('recharge_imali_accounts.created_at', 'desc')
        //            ->select('users.name as user_name', 'imali_accounts.account_number as user_account', 'recharge_imali_accounts.*')->get();
        //        return response()->json(['data' => $carregamento], 200);
        $size = (!request()->per_page) ? 4 : request()->per_page;

        $new_start_date  = null;
        $new_end_date  = null;

        if ($request->filled('start_date')) {
            $start_date = explode('-', $request->start_date);
            if (strlen($start_date[2]) >= 4)
                $new_start_date = $start_date[2] . '-' . $start_date[1] . '-' . $start_date[0];
        }

        if ($request->filled('end_date')) {
            $end_date = explode('-', $request->end_date);
            if (strlen($end_date[2]) >= 4)
                $new_end_date = $end_date[2] . '-' . $end_date[1] . '-' . $end_date[0];
        }

        $carregamento = ImaliAccount::query()
            ->join('users', 'users.id', 'imali_accounts.user_id')
            ->join('recharge_imali_accounts', 'recharge_imali_accounts.imali_account_id', 'imali_accounts.id')
            ->where('users.id', $request->user()->id)
            // new ------------------------
            ->when($request->filled('start_date'), function ($query) use ($request, $new_start_date) {
                $query->whereDate('recharge_imali_accounts.created_at', '>=', $new_start_date ?? $request->start_date);
            })
            ->when($request->filled('end_date'), function ($query) use ($request, $new_end_date) {
                $query->whereDate('recharge_imali_accounts.created_at', '<=', $new_end_date ?? $request->end_date);
            })
            // new ------------------------
            ->orderBy('recharge_imali_accounts.created_at', 'desc')
            ->select('users.name as user_name', 'users.last_name', 'imali_accounts.reference', 'imali_accounts.account_number', 'recharge_imali_accounts.*')
            //->get();
            ->paginate($size);

        return response()->json($carregamento, 200);

        // return response()->json(['data' => $carregamento], 200);

    }

    //? NEW WITHDRAWALLS

    public function getMyWithDrawalls(Request $request)
    {
        $size = (!request()->per_page) ? 4 : request()->per_page;

        $withdrawalls = WithdrawalsRequest::query()
            ->where('user_id', $request->user()->id)
            ->orderBy('created_at', 'desc')
            ->paginate($size);

        return response()->json($withdrawalls, 200);
    }

    //? NEW WITHDRAWALLS

    public function getTransferenciasHistory($id)
    {
        //        $transfers = TransferHistory::query()
        //            ->join('users', 'users.id', '=', 'transfer_histories.client_id')
        //            ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
        //            ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts as imaliSender', 'imaliSender.user_id','=', 'transfer_histories.user_id')
        //            ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id','=', 'transfer_histories.user_id')
        //            ->join('imali_accounts', 'imali_accounts.user_id','=', 'transfer_histories.client_id')
        //            ->where('transfer_histories.user_id', $id)
        ////            ->where('transfer_histories.receiver_id', $id)
        //            ->orderBy('transfer_histories.created_at', 'desc')
        //            ->select(
        //                'transfer_histories.*',
        //                'sender.name as name_sender',
        //                'receiver.name as name_receiver',
        //                'imaliSender.account_number as account_sender',
        //                'imaliReceiver.account_number as account_receiver',
        //                'users.name',
        //                'imali_accounts.account_number'
        //                )
        //            ->get();

        $transfers = TransferHistory::query()
            ->join('users', 'users.id', '=', 'transfer_histories.client_id')
            ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
            ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
            ->where('transfer_histories.user_id', $id)
            //            ->where('transfer_histories.receiver_id', $id)
            ->orderBy('transfer_histories.created_at', 'desc')
            ->select(
                'transfer_histories.*',
                'users.name',
                'imali_accounts.account_number'
            )
            ->get();
        return response()->json(['data' => $transfers], 200);
    }

    public function getTransferenciasHistoryData(Request $request)
    {
        //        $transfers = TransferHistory::query()
        //            ->join('users', 'users.id', '=', 'transfer_histories.client_id')
        //            ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
        //            ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
        //            ->where('transfer_histories.user_id', auth()->user()->id)
        ////            ->where('transfer_histories.receiver_id', $id)
        //            ->orderBy('transfer_histories.created_at', 'desc')
        //            ->select(
        //                'transfer_histories.*',
        //                'users.name',
        //                'imali_accounts.account_number'
        //            )
        //            ->get();
        //        return response()->json(['data' => $transfers], 200);

        $size = (!request()->per_page) ? 4 : request()->per_page;

        $transfers = TransferHistory::query()
            ->join('users', 'users.id', '=', 'transfer_histories.client_id')
            ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
            ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
            ->where('transfer_histories.user_id', $request->user()->id)
            //            ->where('transfer_histories.receiver_id', $id)
            ->orderBy('transfer_histories.created_at', 'desc')
            ->select(
                'transfer_histories.*',
                'users.name',
                'imali_accounts.account_number',
                'imaliSender.account_number as account_number_sender',
                'sender.name as name_sender',
                'sender.last_name as last_name_sender',
                'users.name as name_receiver',
                'users.last_name as last_name_receiver',
            )
            // ->get();
            ->paginate($size);

        return response()->json($transfers, 200);
    }


    public function getTransferenciasHistoryData2024(Request $request)
    {

        //        $transfers = TransferHistory::query()
        //            ->join('users', 'users.id', '=', 'transfer_histories.client_id')
        //            ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
        //            ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
        //            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
        //            ->where('transfer_histories.user_id', auth()->user()->id)
        ////            ->where('transfer_histories.receiver_id', $id)
        //            ->orderBy('transfer_histories.created_at', 'desc')
        //            ->select(
        //                'transfer_histories.*',
        //                'users.name',
        //                'imali_accounts.account_number'
        //            )
        //            ->get();
        //        return response()->json(['data' => $transfers], 200);

        //PEGAR DADOS DAS TRANSACOES FEITAS PELAS SUBCONTAS

        $data_transfer = TransferHistory::query()
            ->join('transfers', 'transfers.transaction_id', 'transfer_histories.transaction_id')
            ->where('transfer_histories.user_id', $request->user()->id)->orderBy('transfers.created_at', 'desc')
            ->select('transfer_histories.*', 'transfers.sender_account', 'transfers.reciever_account')
            //->latest();
            ->first();

        // Verificar se o terceiro dígito do sender_account ou receiver_account é diferente de 0
        if ($this->checkAccount($data_transfer->sender_account) || $this->checkAccount($data_transfer->reciever_account)) {
            // return "subconta";

            $size = (!request()->per_page) ? 4 : request()->per_page;

            $transfers = TransferHistory::query()
                ->join('transfers', 'transfers.transaction_id', '=', 'transfer_histories.transaction_id')
                ->join('users', 'users.id', '=', 'transfer_histories.client_id')
                ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
                ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
                ->where('transfer_histories.user_id', $request->user()->id)
                ->orderBy('transfer_histories.created_at', 'desc')
                ->select(
                    'transfer_histories.*',
                    'transfers.reciever_name as name',
                    'transfers.reciever_account as account_number',
                    'imaliSender.account_number as account_number_sender',
                    'sender.name as name_sender',
                    'sender.last_name as last_name_sender',
                    'transfers.reciever_name as name_receiver',
                    'users.last_name as last_name_receiver',
                )
                ->paginate($size);

            // $transfers = TransferHistory::query()
            //     ->join('users', 'users.id', '=', 'transfer_histories.client_id')
            //     ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
            //     ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
            //     ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
            //     ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
            //     ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
            //     ->where('transfer_histories.user_id', $request->user()->id)
            //     ->orderBy('transfer_histories.created_at', 'desc')
            //     ->select(
            //         'transfer_histories.*',
            //         'users.name',
            //         'imali_accounts.account_number',
            //         'imaliSender.account_number as account_number_sender',
            //         'sender.name as name_sender',
            //         'sender.last_name as last_name_sender',
            //         'users.name as name_receiver',
            //         'users.last_name as last_name_receiver',
            //     )
            //     ->paginate($size);

            return response()->json($transfers, 200);
        } else {
            // return "não subconta";

            $size = (!request()->per_page) ? 4 : request()->per_page;

            $transfers = TransferHistory::query()
                ->join('users', 'users.id', '=', 'transfer_histories.client_id')
                ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
                ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
                ->where('transfer_histories.user_id', $request->user()->id)
                //            ->where('transfer_histories.receiver_id', $id)
                ->orderBy('transfer_histories.created_at', 'desc')
                ->select(
                    'transfer_histories.*',
                    'users.name',
                    'imali_accounts.account_number',
                    'imaliSender.account_number as account_number_sender',
                    'sender.name as name_sender',
                    'sender.last_name as last_name_sender',
                    'users.name as name_receiver',
                    'users.last_name as last_name_receiver',
                )
                // ->get();
                ->paginate($size);

            return response()->json($transfers, 200);
        }

        //PEGAR DADOS DAS TRANSACOES FEITAS PELAS SUBCONTAS



        // $size = (!request()->per_page) ? 4 : request()->per_page;

        // $transfers = TransferHistory::query()
        //     ->join('users', 'users.id', '=', 'transfer_histories.client_id')
        //     ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
        //     ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
        //     ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
        //     ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
        //     ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')
        //     ->where('transfer_histories.user_id', $request->user()->id)
        //     //            ->where('transfer_histories.receiver_id', $id)
        //     ->orderBy('transfer_histories.created_at', 'desc')
        //     ->select(
        //         'transfer_histories.*',
        //         'users.name',
        //         'imali_accounts.account_number',
        //         'imaliSender.account_number as account_number_sender',
        //         'sender.name as name_sender',
        //         'sender.last_name as last_name_sender',
        //         'users.name as name_receiver',
        //         'users.last_name as last_name_receiver',
        //     )
        //     // ->get();
        //     ->paginate($size);

        // return response()->json($transfers, 200);
        // return response()->json(['data' => $transfers], 200);



        // // todo -------------------------------------------------------------------
        // $size = (!request()->per_page) ? 4 : request()->per_page;

        // $withdrawals = WithdrawalsRequest::query()
        //     // ->where('user_id', $request->user()->id)
        //     ->where('user_id', $request->user()->id)
        //     ->select(
        //         'withdrawals_requests.id as id',
        //         'withdrawals_requests.transaction_id as transaction_id',
        //         'withdrawals_requests.imali_account as imali_account',
        //         'withdrawals_requests.account_number as account_number',
        //         'withdrawals_requests.account_type as account_type',
        //         'withdrawals_requests.description as description',
        //         'withdrawals_requests.status as status',
        //         'withdrawals_requests.amount as amount',
        //         'withdrawals_requests.commission as commission',
        //         'withdrawals_requests.bank_fee as bank_fee',
        //         'withdrawals_requests.stamp_tax as stamp_tax',
        //         'withdrawals_requests.imali_fee as imali_fee',
        //         'withdrawals_requests.total as total',
        //         'withdrawals_requests.old_balance as old_balance',
        //         'withdrawals_requests.new_balance as new_balance',
        //         'withdrawals_requests.user_id as user_id',
        //         'withdrawals_requests.wallets_id as wallets_id',
        //         'withdrawals_requests.operators_id as operators_id',
        //         'withdrawals_requests.moza_message as moza_message',
        //         'withdrawals_requests.imali_account_id as imali_account_id',
        //         DB::raw("'NULL' as reciever_id"),
        //         DB::raw("'NULL' as reciever_account"),
        //         // DB::raw("'NULL' as reciever_name"),
        //         'withdrawals_requests.reciever_name as reciever_name',
        //         DB::raw("'NULL' as amount_debited"),
        //         DB::raw("'#388E3C' as estado_color"),
        //         DB::raw("'NULL' as category_id"),
        //         // DB::raw("'NULL' as sender_name"),
        //         'withdrawals_requests.sender_name as sender_name',
        //         'withdrawals_requests.created_at as created_at',
        //         'withdrawals_requests.updated_at as updated_at',

        //         DB::raw("withdrawals_requests.commission as comissao"),
        //         DB::raw("withdrawals_requests.status as estado"),
        //         DB::raw("'NULL' as user_status"),
        //         // DB::raw("'NULL' as name"),
        //         // DB::raw("'NULL' as account_number"),
        //         DB::raw("withdrawals_requests.account_number as account_number_sender"),
        //         DB::raw("withdrawals_requests.sender_name as name_sender"),
        //         DB::raw("'NULL' as last_name_sender"),
        //         DB::raw("'NULL' as name_receiver"),
        //         DB::raw("'NULL' as last_name_receiver"),
        //     )
        //     ->orderBy('withdrawals_requests.created_at', 'desc');

        // $transfers = Transfer::query()
        //     ->join('users', 'users.id', '=', 'transfers.sender_id')
        //     ->join('imali_accounts', 'imali_accounts.user_id', 'transfers.sender_id')
        //     // todo acrescentado....
        //     ->join('transfer_histories', 'transfer_histories.user_id', 'transfers.sender_id')
        //     ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfers.sender_id')
        //     ->join('users as receiver', 'receiver.id', '=', 'transfers.reciever_id')
        //     // todo acrescentado....
        //     // ->where('transfers.sender_id', $request->user()->id)
        //     ->where('transfers.sender_id', $request->user()->id)
        //     ->select(
        //         'transfers.id as id',
        //         'transfers.transaction_id as transaction_id',
        //         DB::raw("'NULL' as imali_account"),
        //         'imali_accounts.account_number as account_number',
        //         'users.profile as account_type',
        //         DB::raw("'TRF. iMali' as description"),
        //         'transfers.estado as status',
        //         'transfers.amount as amount',
        //         'transfers.comissao as commission',
        //         DB::raw("'0' as bank_fee"),
        //         DB::raw("'0' as stamp_tax"),
        //         DB::raw("'0' as imali_fee"),
        //         DB::raw("'0' as total"),
        //         'transfers.old_balance as old_balance',
        //         'transfers.new_balance as new_balance',
        //         'transfers.sender_id as user_id',
        //         DB::raw("'NULL' as wallets_id"),
        //         DB::raw("'NULL' as operators_id"),
        //         DB::raw("'No message' as moza_message"),
        //         DB::raw("'NULL' as imali_account_id"),
        //         'transfers.reciever_id as reciever_id',
        //         'transfers.reciever_account as reciever_account',
        //         'transfers.reciever_name as reciever_name',
        //         'transfers.amount_debited as amount_debited',
        //         'transfers.estado_color as estado_color',
        //         'transfers.category_id as category_id',
        //         'users.name as sender_name',
        //         'transfers.created_at as created_at',
        //         'transfers.updated_at as updated_at',

        //         'transfer_histories.comissao as comissao',
        //         'transfer_histories.estado as estado',
        //         'transfer_histories.user_status as user_status',
        //         // 'transfer_histories.name as name',
        //         // 'transfer_histories.account_number as account_number',
        //         'imaliSender.account_number as account_number_sender',
        //         'users.name as name_sender',
        //         'users.last_name as last_name_sender',
        //         'transfers.reciever_name as name_receiver',
        //         'receiver.last_name as last_name_receiver',
        //     )
        //     ->orderBy('transfers.created_at', 'desc');

        // $results = $withdrawals->union($transfers)->paginate($size);


        // return response()->json($results, 200);
        // // todo -------------------------------------------------------------------
    }


    // Função para verificar se o terceiro dígito de um número é diferente de 0
    private function checkAccount($numero)
    {
        return substr($numero, 2, 1) !== '0';
    }

    public function getTransferInEx2024(Request $request)
    {
        $size = (!request()->per_page) ? 4 : request()->per_page;

        $withdrawals = WithdrawalsRequest::query()
            ->where('user_id', $request->user()->id)
            ->select(
                'withdrawals_requests.id as id',
                'withdrawals_requests.transaction_id as transaction_id',
                'withdrawals_requests.account_number as account_number',
                DB::raw("'NULL' as account_number_sender"),
                'withdrawals_requests.description as description',
                'withdrawals_requests.reciever_name as name_receiver',
                DB::raw("withdrawals_requests.sender_name as name_sender"),
                'withdrawals_requests.amount as amount',
                'withdrawals_requests.imali_fee as imali_fee',
                'withdrawals_requests.total as total',
                //DB::raw("'NULL' as client_id"),
                DB::raw("'NULL' as user_status"),
                //'withdrawals_requests.status as status',
                DB::raw(
                    "CASE WHEN withdrawals_requests.status = 'success' THEN 'Sucesso'
                        WHEN withdrawals_requests.status = 'pending' THEN 'Pendente'
                        WHEN withdrawals_requests.status = 'completed' THEN 'Concluído'
                        WHEN withdrawals_requests.status = 'failed' THEN 'Falhou'
                        ELSE withdrawals_requests.status END as status"
                ),
                'withdrawals_requests.created_at as created_at',
                'withdrawals_requests.updated_at as updated_at',
                DB::raw("'external' as transfer_type"),
                'withdrawals_requests.user_id as sender_id',
            )
            ->orderBy('withdrawals_requests.created_at', 'desc');
        //->orderBy('withdrawals_requests.id', 'desc');

        //  $transfers = Transfer::query()
        //      ->join('users', 'users.id', '=', 'transfers.sender_id')
        //      ->join('imali_accounts', 'imali_accounts.user_id', 'transfers.sender_id')
        //      ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfers.sender_id')
        //      ->join('users as receiver', 'receiver.id', '=', 'transfers.reciever_id')
        //      ->where('transfers.sender_id', $request->user()->id)
        //      ->select(
        //          'transfers.id as id',
        //          'transfers.transaction_id as transaction_id',
        //	'transfers.reciever_account as account_number',
        //         DB::raw("'TRF. iMali' as description"),
        //         'transfers.reciever_name as name_receiver',
        //         'users.name as name_sender',
        //         'transfers.amount as amount',
        //         DB::raw("'0' as imali_fee"),
        //         'transfers.amount as total',
        //		DB::raw("CASE WHEN transfers.estado = 'Pago' THEN 'Sucesso' ELSE transfers.estado END as status"),
        //        'transfers.created_at as created_at',
        //        'transfers.updated_at as updated_at',
        //        DB::raw("'internal' as transfer_type"),
        //        'transfers.sender_id as sender_id',
        //    )
        //    ->orderBy('transfers.created_at', 'desc');

        // todo ----
        $transfers = TransferHistory::query()
            ->join('users', 'users.id', '=', 'transfer_histories.client_id')
            ->join('users as sender', 'sender.id', '=', 'transfer_histories.user_id')
            ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')

            ->join('transfers', 'transfers.transaction_id', '=', 'transfer_histories.transaction_id')
            ->where('transfer_histories.user_id', $request->user()->id)
            ->orderBy('transfer_histories.created_at', 'desc')
            ->select(
                'transfer_histories.id as id',
                'transfer_histories.transaction_id as transaction_id',
                'imali_accounts.account_number as account_number',
                'imaliSender.account_number as account_number_sender',
                DB::raw("'TRF. iMali' as description"),
                'users.name as name_receiver',
                'sender.name as name_sender',
                'transfers.amount as amount',
                DB::raw("'0' as imali_fee"),
                'transfers.amount as total',
                'transfer_histories.user_status',
                DB::raw("CASE WHEN transfers.estado = 'Pago' THEN 'Sucesso' WHEN transfers.estado = 'Recebido' THEN 'Recebido' ELSE transfers.estado END as status"),
                'transfers.created_at as created_at',
                'transfers.updated_at as updated_at',
                DB::raw("'internal' as transfer_type"),
                'transfers.sender_id as sender_id',
            )
            ->orderBy('transfer_histories.created_at', 'desc');
        // ->orderBy('transfer_histories.id', 'desc');
        // ->get();
        // todo ----

        //$results = $withdrawals->union($transfers)->paginate($size);
        $results = $withdrawals->union($transfers)->orderBy('created_at', 'desc')->paginate($size);


        return response()->json($results, 200);
    }

    // public function getTransfersEx2(){}
    public function getTransferInEx(Request $request)
    {

        $size = (!request()->per_page) ? 4 : request()->per_page;

        $new_start_date  = null;
        $new_end_date  = null;

        if ($request->filled('start_date')) {
            $start_date = explode('-', $request->start_date);
            if (strlen($start_date[2]) >= 4)
                $new_start_date = $start_date[2] . '-' . $start_date[1] . '-' . $start_date[0];
        }

        if ($request->filled('end_date')) {
            $end_date = explode('-', $request->end_date);
            if (strlen($end_date[2]) >= 4)
                $new_end_date = $end_date[2] . '-' . $end_date[1] . '-' . $end_date[0];
        }

        $transfers = $this->getMyTransfers($request, $request->user()->id, $new_start_date, $new_end_date);
        $withdrawals = $this->getMyWithdralls($request, $request->user()->id, $new_start_date, $new_end_date);

        $results = $withdrawals->union($transfers)
            ->orderBy('created_at', 'desc')
            ->paginate($size);

        return response()->json($results, 200);
    }

    private function getMyTransfers(Request $request, $user_id, $new_start_date, $new_end_date)
    {
        return TransferHistory::query()
            ->join('transfers', 'transfers.transaction_id', '=', 'transfer_histories.transaction_id')
            ->where('user_id', $user_id)
            // new ------------------------
            ->when($request->filled('start_date'), function ($query) use ($request, $new_start_date) {
                $query->whereDate('transfer_histories.created_at', '>=', $new_start_date ?? $request->start_date);
            })
            ->when($request->filled('end_date'), function ($query) use ($request, $new_end_date) {
                $query->whereDate('transfer_histories.created_at', '<=', $new_end_date ?? $request->end_date);
            })
            // new ------------------------
            ->orderBy('transfer_histories.created_at', 'desc')
            ->select(
                'transfer_histories.id as id',
                'transfer_histories.transaction_id as transaction_id',
                //'transfers.reciever_account as account_number',
                DB::raw("CASE WHEN transfer_histories.user_status = 'payer' THEN transfers.reciever_account WHEN transfer_histories.user_status = 'receiver' THEN transfers.sender_account ELSE transfers.reciever_account END as reciever_account"),
                'transfers.sender_account as account_number_sender',
                DB::raw("'TRF. iMali' as description"),
                DB::raw("CASE WHEN transfer_histories.user_status = 'payer' THEN transfers.reciever_name WHEN transfer_histories.user_status = 'receiver' THEN transfers.sender_name ELSE transfers.reciever_name END as reciever_name"),
                //'transfers.reciever_name as name_receiver',
                'transfers.sender_name as name_sender',
                'transfers.amount as amount',
                DB::raw("'0' as imali_fee"),
                'transfers.amount as total',
                'transfer_histories.user_status',
                DB::raw("CASE WHEN transfers.estado = 'Pago' THEN 'Sucesso' WHEN transfers.estado = 'Recebido' THEN 'Recebido' ELSE transfers.estado END as status"),
                'transfers.created_at as created_at',
                'transfers.updated_at as updated_at',
                DB::raw("'internal' as transfer_type"),
                'transfers.sender_id as sender_id',
            );
    }

    private function getMyWithdralls(Request $request, $user_id, $new_start_date, $new_end_date)
    {
        return WithdrawalsRequest::query()
            ->where('user_id', $user_id)
            // new ------------------------
            ->when($request->filled('start_date'), function ($query) use ($request, $new_start_date) {
                $query->whereDate('withdrawals_requests.created_at', '>=', $new_start_date ?? $request->start_date);
            })
            ->when($request->filled('end_date'), function ($query) use ($request, $new_end_date) {
                $query->whereDate('withdrawals_requests.created_at', '<=', $new_end_date ?? $request->end_date);
            })
            // new ------------------------
            ->select(
                'withdrawals_requests.id as id',
                'withdrawals_requests.transaction_id as transaction_id',
                'withdrawals_requests.account_number as account_number',
                DB::raw("'NULL' as account_number_sender"),
                'withdrawals_requests.description as description',
                'withdrawals_requests.reciever_name as name_receiver',
                DB::raw("withdrawals_requests.sender_name as name_sender"),
                'withdrawals_requests.amount as amount',
                'withdrawals_requests.imali_fee as imali_fee',
                'withdrawals_requests.total as total',
                DB::raw("'NULL' as user_status"),
                DB::raw(
                    "CASE WHEN withdrawals_requests.status = 'success' THEN 'Sucesso'
                    WHEN withdrawals_requests.status = 'pending' THEN 'Pendente'
                    WHEN withdrawals_requests.status = 'completed' THEN 'Concluído'
                    WHEN withdrawals_requests.status = 'failed' THEN 'Falhou'
                    ELSE withdrawals_requests.status END as status"
                ),
                'withdrawals_requests.created_at as created_at',
                'withdrawals_requests.updated_at as updated_at',
                DB::raw("'external' as transfer_type"),
                'withdrawals_requests.user_id as sender_id',
            )
            ->orderBy('withdrawals_requests.created_at', 'desc');
    }

    // todo -- adicionado 15-04-24
    public function getTransferInExOLD(Request $request)
    {

        $data_transfer = TransferHistory::query()
            ->join('transfers', 'transfers.transaction_id', 'transfer_histories.transaction_id')
            ->where('transfer_histories.user_id', $request->user()->id)
            //->orWhere('transfer_histories.client_id', $request->user()->id)
            ->orderBy('transfers.created_at', 'desc')
            ->select('transfer_histories.*', 'transfers.sender_account', 'transfers.reciever_account')
            //->latest();
            ->first();

        $size = (!request()->per_page) ? 4 : request()->per_page;

        $withdrawals = WithdrawalsRequest::query()
            ->where('user_id', $request->user()->id)
            ->select(
                'withdrawals_requests.id as id',
                'withdrawals_requests.transaction_id as transaction_id',
                'withdrawals_requests.account_number as account_number',
                DB::raw("'NULL' as account_number_sender"),
                'withdrawals_requests.description as description',
                'withdrawals_requests.reciever_name as name_receiver',
                DB::raw("withdrawals_requests.sender_name as name_sender"),
                'withdrawals_requests.amount as amount',
                'withdrawals_requests.imali_fee as imali_fee',
                'withdrawals_requests.total as total',
                // DB::raw("'NULL' as client_id"),
                DB::raw("'NULL' as user_status"),
                // 'withdrawals_requests.status as status',
                DB::raw(
                    "CASE WHEN withdrawals_requests.status = 'success' THEN 'Sucesso'
                        WHEN withdrawals_requests.status = 'pending' THEN 'Pendente'
                        WHEN withdrawals_requests.status = 'completed' THEN 'Concluído'
                        WHEN withdrawals_requests.status = 'failed' THEN 'Falhou'
                        ELSE withdrawals_requests.status END as status"
                ),
                'withdrawals_requests.created_at as created_at',
                'withdrawals_requests.updated_at as updated_at',
                DB::raw("'external' as transfer_type"),
                'withdrawals_requests.user_id as sender_id',
            )
            ->orderBy('withdrawals_requests.created_at', 'desc');



        //if ($this->checkAccount($data_transfer->sender_account) || $this->checkAccount($data_transfer->reciever_account)) {
        if (($data_transfer->sender_account && $this->checkAccount($data_transfer->sender_account)) || ($data_transfer->reciever_account && $this->checkAccount($data_transfer->reciever_account))) {
            //return "estou nas subcontas";

            $transfers = TransferHistory::query()
                ->join('transfers', 'transfers.transaction_id', '=', 'transfer_histories.transaction_id')
                ->join('users', 'users.id', 'transfer_histories.client_id') // ID = 2
                ->join('users as sender', 'sender.id', 'transfer_histories.user_id') // ID = 4

                ->where('transfer_histories.user_id', $request->user()->id)
                ->orderBy('transfer_histories.created_at', 'desc')
                ->select(
                    'transfer_histories.id as id',
                    'transfer_histories.transaction_id as transaction_id',
                    DB::raw("CASE WHEN transfer_histories.user_status = 'payer' THEN transfers.reciever_account WHEN transfer_histories.user_status = 'receiver' THEN transfers.sender_account ELSE transfers.reciever_account END as reciever_account"),
                    'transfers.sender_account as account_number_sender',
                    DB::raw("'TRF. iMali' as description"),
                    DB::raw("CASE WHEN transfer_histories.user_status = 'payer' THEN transfers.reciever_name WHEN transfer_histories.user_status = 'receiver' THEN transfers.sender_name ELSE transfers.reciever_name END as name_receiver"),
                    'transfers.sender_name as name_sender',
                    'transfers.amount as amount',
                    DB::raw("'0' as imali_fee"),
                    'transfers.amount as total',
                    'transfer_histories.user_status',
                    DB::raw("CASE WHEN transfers.estado = 'Pago' THEN 'Sucesso' WHEN transfers.estado = 'Recebido' THEN 'Recebido' ELSE transfers.estado END as status"),
                    'transfers.created_at as created_at',
                    'transfers.updated_at as updated_at',
                    DB::raw("'internal' as transfer_type"),
                    'transfers.sender_id as sender_id',
                )
                ->orderBy('transfer_histories.created_at', 'desc');

            $results = $withdrawals->union($transfers)->orderBy('created_at', 'desc')->paginate($size);
        } else {

            //return "entrou";
            $transfers = TransferHistory::query()
                ->join('users', 'users.id', 'transfer_histories.client_id') // ID = 2
                ->join('users as sender', 'sender.id', 'transfer_histories.user_id') // ID = 4

                ->join('users as receiver', 'receiver.id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts as imaliSender', 'imaliSender.user_id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts as imaliReceiver', 'imaliReceiver.user_id', '=', 'transfer_histories.user_id')
                ->join('imali_accounts', 'imali_accounts.user_id', '=', 'transfer_histories.client_id')

                ->join('transfers', 'transfers.transaction_id', '=', 'transfer_histories.transaction_id')
                ->where('transfer_histories.user_id', $request->user()->id)
                ->orderBy('transfer_histories.created_at', 'desc')
                ->select(
                    'transfer_histories.id as id',
                    'transfer_histories.transaction_id as transaction_id',
                    'imali_accounts.account_number as account_number',
                    'imaliSender.account_number as account_number_sender',
                    DB::raw("'TRF. iMali' as description"),
                    'users.name as name_receiver',
                    'sender.name as name_sender',
                    'transfers.amount as amount',
                    DB::raw("'0' as imali_fee"),
                    'transfers.amount as total',
                    'transfer_histories.user_status',
                    DB::raw("CASE WHEN transfers.estado = 'Pago' THEN 'Sucesso' WHEN transfers.estado = 'Recebido' THEN 'Recebido' ELSE transfers.estado END as status"),
                    'transfers.created_at as created_at',
                    'transfers.updated_at as updated_at',
                    DB::raw("'internal' as transfer_type"),
                    'transfers.sender_id as sender_id',
                )
                ->orderBy('transfer_histories.created_at', 'desc');

            $results = $withdrawals->union($transfers)->orderBy('created_at', 'desc')->paginate($size);
        }

        return response()->json($results, 200);
    }

    // todo -- adicionado 15-04-24



    // EXTRACT SUBACCOUNT PAYMENTS
    // public function subAccountExtract($subAccounNumber, $startDate = null, $endDate = null)
    public function subAccountExtract(Request $request)
    {
        $extract = Payment::query()
            ->select(
                'transaction_id as TransactionID',
                'created_at as Date',
                'sender_card_number as Card Number',
                'sender_account_number as Sender Account Number',
                'transaction_name as Transaction Type',
                'amount as Amount',
                'old_balance as OldBalance',
                'new_balance as NewBalance',
                'status as Status'
            )
            ->where('sender_account_number', $request->card_number);
        // ->where('created_at', '>=', $request->startDate)
        // ->where('created_at', '<=', $request->endDate)
        // ->orderByDesc('payments.created_at')
        // ->get();

        // Adicionar filtro de datas apenas se os parâmetros estiverem presentes
        if ($request->startDate) {
            $extract->where('created_at', '>=', $request->startDate);
        }

        if ($request->endDate) {
            $extract->where('created_at', '<=', $request->endDate);
        }

        $extract = $extract->orderByDesc('payments.created_at')->get();

        return response()->json(['data' => $extract], 200);
    }




    public function getMyVouchers(Request $request)
    {

        $size = (!request()->per_page) ? 4 : request()->per_page;

        $new_start_date  = null;
        $new_end_date  = null;

        if ($request->filled('start_date')) {
            $start_date = explode('-', $request->start_date);
            if (strlen($start_date[2]) >= 4)
                $new_start_date = $start_date[2] . '-' . $start_date[1] . '-' . $start_date[0];
        }

        if ($request->filled('end_date')) {
            $end_date = explode('-', $request->end_date);
            if (strlen($end_date[2]) >= 4)
                $new_end_date = $end_date[2] . '-' . $end_date[1] . '-' . $end_date[0];
        }

        $voucher = PurchaseVoucher::query()
            ->join('users', 'users.id', '=', 'purchase_vouchers.user_id')
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'purchase_vouchers.user_id')
            ->leftJoin('transaction_locations', 'transaction_locations.voucher_id', '=', 'purchase_vouchers.id')
            ->leftJoin('ramo_activities', 'ramo_activities.id', '=', 'purchase_vouchers.category_id')
            ->orderByDesc('purchase_vouchers.created_at')
            // new ------------------------
            ->when($request->filled('start_date'), function ($query) use ($request, $new_start_date) {
                $query->whereDate('purchase_vouchers.created_at', '>=', $new_start_date ?? $request->start_date);
            })
            ->when($request->filled('end_date'), function ($query) use ($request, $new_end_date) {
                $query->whereDate('purchase_vouchers.created_at', '<=', $new_end_date ?? $request->end_date);
            })
            // new ------------------------
            ->where('purchase_vouchers.user_id', $request->user()->id)
            ->select(
                'purchase_vouchers.*',
                'imali_accounts.account_number',
                'users.name',
                'users.last_name',
                'transaction_locations.longitude',
                'transaction_locations.latitude',
                'transaction_locations.country_name',
                'transaction_locations.country_code',
                'transaction_locations.admin_area',
                'transaction_locations.sub_admin_area',
                'ramo_activities.nome as category'
            )
            // ->get();
            ->paginate($size);

        return response()->json($voucher, 200);

        //return response()->json(['data' => $voucher], 200);
    }

    public function checkReceiver(Request $request)
    {
        $imaliAccountReceiver = ImaliAccount::query()->where('account_number', $request->account_number)->first();

        if ($imaliAccountReceiver) {

            $log = new Record();
            $log->createLog([
                'description' => $request->account_number,
                'details' => 'Conta Verificada com sucesso',
                'operation' => 'Check Receiver or Client',
                'properties' => json_encode($request->all()),
                'status' => 'Success',
                'user_id' => $request->user()->id
            ]);

            return response()->json(['message' => 'Conta existente'], 200);
        } else {

            $log = new Record();
            $log->createLog([
                'description' => $request->account_number,
                'details' => 'Conta i.Mali inválida',
                'operation' => 'Check Receiver or Client',
                //                'properties' => $request->all(),
                'properties' => json_encode($request->all()),
                'status' => 'Error',
                'user_id' => $request->user()->id
            ]);

            return response()->json(['message' => 'Conta i.Mali inválida'], 404);
        }
    }

    // public function pushNotifification($token, $notification = array(), $data = array())
    // {
    //     $apiKey = 'AAAA8zVzEPQ:APA91bHl_DXB6UGb_6gZlmFnaLTQoANtX_OBjvl3nOy2bSlnFhxedvk6EhGj7cZoIvmlbKeCnqGxXbuyMH_rEPuhRXvuitXzo6Pfl2TMXLar1PlifXqEhYq6tS55UMrY2Kffzj-P_UH-';
    //     $fields = array('to' => $token, 'notification' => $notification, 'data' => $data);
    //     $headers = array('Authorization: key=' . $apiKey, 'Content-Type: application/json');
    //     $url = 'https://fcm.googleapis.com/fcm/send';

    //     $curl = curl_init();
    //     curl_setopt($curl, CURLOPT_URL, $url);
    //     curl_setopt($curl, CURLOPT_POST, true);
    //     curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    //     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    //     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    //     curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields));
    //     $result = curl_exec($curl);
    //     curl_close($curl);

    //     return json_decode($result, true);
    // }

    private function getAccessToken()
    {
        $client = new GoogleClient();
        // $client->setAuthConfig(storage_path('app/imaliapp-5155e-firebase-adminsdk-gv3wp-2713d42c5b.json')); // Caminho do arquivo JSON da conta de serviço
        $client->setAuthConfig($this->getFirebaseAuthConf()); // Caminho do arquivo JSON da conta de serviço
        $client->addScope($_ENV['FIREBASE_MESSAGE_SCOPE']);
        $client->setAccessType('offline');

        $token = $client->fetchAccessTokenWithAssertion();
        return $token['access_token'];
    }

    private function getFirebaseAuthConf()
    {
        return [
            "type" => $_ENV['TYPE'],
            "project_id" => $_ENV['PROJECT_ID'],
            "private_key_id" => $_ENV['PRIVATE_KEY_ID'],
            "private_key" => $_ENV['PRIVATE_KEY'],
            "client_email" => $_ENV['CLIENT_EMAIL'],
            "client_id" => $_ENV['CLIENT_ID'],
            "auth_uri" => $_ENV['AUTH_URI'],
            "token_uri" => $_ENV['TOKEN_URI'],
            "auth_provider_x509_cert_url" => $_ENV['AUTH_PROVIDER_X509_CERT_URL'],
            "client_x509_cert_url" => $_ENV['CLIENT_X509_CERT_URL'],
            "universe_domain" => $_ENV['UNIVERSE_DOMAIN']
        ];
    }


    public function pushNotifification($token, $notification = array(), $data = array())
    {
        $fields = [
            'message' => [
                'token' => $token,
                'android' => [
                    'notification' => $notification
                ],
                "apns" => [
                    "payload" => [
                        "aps" => [
                            "category" => "NEW_MESSAGE_CATEGORY"
                        ]
                    ]
                ],
                'data' => $this->convert_array_values_to_string($data) ?? [],
            ]
        ];

        $headers = array('Authorization: Bearer ' . $this->getAccessToken(), 'Content-Type: application/json');
        $url = $_ENV['FIREBASE_NEW_URL'];

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields));
        $result = curl_exec($curl);
        curl_close($curl);

        return json_decode($result, true);
    }

    private function convert_array_values_to_string($array)
    {
        return array_map(function ($value) {
            return (string) $value; // Convert each value to a string
        }, array_combine(array_map('strval', array_keys($array)), $array));
    }

    // get All transactions TRANSFER | PAYMENT | VOUCHERS (recargas) tv, withdrawall, agua, credelec, 
    // TODO -- 15-Setembro-2024
    public function getAllTransactionData(Request $request)
    {
        $allTransac = AllTransaction::query()->orderBy('id', 'desc')->get();

        if ($allTransac->isEmpty()) {
            return response()->json(['data' => []], 200);
        }

        return response()->json(['data' => $allTransac], 200);
    }


    // Create Payment Link
    public function paymentLink(Request $request)
    {

        $this->validate(
            $request,
            [
                'title' => 'required',
                'store_id' => 'required|numeric',
                'amount' => 'required|numeric',
                'short_description' => 'required',
                // 'send_to_phone' => 'required',
                'customer_link_id' => 'nullable|unique:links,customer_link_id',
                'type' => 'required|in:RECURRING,DIRECT,DONATION',
                // 'expiration_datetime' => 'nullable|date_format:Y-m-d H:i:s',
                'expiration_datetime' => 'required_if:type,DONATION|nullable|date_format:Y-m-d H:i:s',

                'thumbnail_image' => 'mimes:jpeg,jpg,png|max:4096',

                'payment_frequence' => 'required_if:type,RECURRING|in:DAILY,WEEKLY,MONTHLY,YEARLY',

            ],
            [
                'title.required' => 'Campo title é obrigatório',
                'store_id.required' => 'Campo store_id é obrigatório',
                'store_id.numeric' => 'Campo store_id é numerico',
                'amount.required' => 'Campo amount é obrigatório',
                'amount.numeric' => 'Campo amount é numerico',
                'short_description.required' => 'Campo short_description é obrigatório',
                // 'send_to_phone.required' => 'Campo send_to_phone é obrigatório',
                'customer_link_id.unique' => 'O campo customer_link_id já está em uso.',
                'type.required' => 'Campo type é obrigatório',
                'type.in' => 'Campo type somente permite RECURRING, DIRECT ou DONATION',
                'expiration_datetime.date_format' => 'O expiration_datetime deve estar no formato Y-m-d H:i:s',
                'expiration_datetime.required_if' => 'Campo expiration_datetime é obrigatório quando o tipo for DONATION',
                'thumbnail_image.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                'thumbnail_image.max' => 'O tamanho de imagem permitido somente abaixo de 4 MB',

                'payment_frequence.required_if' => 'Campo payment_frequence é obrigatório',
            ]
        );

        if ($request->has('send_to_phone') && $request->send_to_phone) {
            $this->validate(
                $request,
                [
                    'send_to_phone' => 'required',
                ],
                [
                    'send_to_phone.required' => 'Campo send_to_phone é obrigatório',
                ]
            );
        }



        if ($request->has('expiration_datetime') && $request->expiration_datetime) {
            $expiration_date = (int)strtotime($request->expiration_datetime);
            $current_date = (int)strtotime(date('Y-m-d H:i:s'));

            if ($current_date > $expiration_date) return SendResponse::errorResp400('Data invalida', 'Invalid Date');
        }

        // Se o comerciante nao enviar o expiration_datetime a API por default adiciona + um dia de duracao do link
        if (!$request->has('expiration_datetime')) {

            $duration = new DateTime(); // Data atual
            $duration->modify('+24 hours');
            $request->request->add(['expiration_datetime' => $duration->format('Y-m-d H:i:s')]);
        }

        // adicionar o 
        if ($request->has('payment_frequence')) {

            $payment_frequence = $request->payment_frequence;
            $current_date = now(); // Data atual


            switch ($payment_frequence) {
                case 'DAILY':
                    # code...
                    $current_date->modify('+24 hours')->format('Y-m-d H:i:s');
                    break;

                case 'WEEKLY':
                    // Adiciona 7 dias à data atual
                    $current_date->modify('+7 days')->format('Y-m-d H:i:s');
                    break;
                case 'MONTHLY':
                    // Adiciona 1 mês à data atual
                    $current_date->modify('+1 month')->format('Y-m-d H:i:s');
                    break;
                case 'YEARLY':
                    // Adiciona 1 ano à data atual
                    $current_date->modify('+1 year')->format('Y-m-d H:i:s');
                    break;

                default:
                    return null;
                    break;
            }

            $request->request->add(['next_payment_date' => $current_date->format('Y-m-d H:i:s')]);
            // return $current_date->format('Y-m-d H:i:s');
        }

        $img_exists = $request->has('thumbnail_image') && $request->thumbnail_image;

        $store = Store::getStoreContractsAndConfigs($request->store_id);
        if (!$store) return response()->json(['message' => 'Loja inválida'], 404);

        // Verificar o thumbnail_image se esta preenchido
        if ($img_exists) {

            $image = new ImageUploader('links');
            $image_thumbnail = $image->generateImageUrlName($request, 'thumbnail_image');
            // $image_thumbnail = substr($image_thumbnail_url, 50, strlen($image_thumbnail_url));
        } else {
            $image_thumbnail = substr($store->logo, strrpos($store->logo, '/') + 1, strlen($store->logo));
        }

        $trasactionGeneration = new TransactionGeneration();
        $transaction = $trasactionGeneration->generateTransaction();

        // return $request->store_id;

        $imali_fee = $request->amount * ($store->taxa / 100);
        $amount_to_credit = $request->amount - $imali_fee;

        // 27 - Jan -25
        $is_recurring = $request->type == 'RECURRING' ? true : false;

        if ($request->type == 'DONATION' && !$request->filled('expiration_datetime')) {
            return SendResponse::errorResp400('Campo expiration_datetime é obrigatório para o tipo DONATION', 'Missing expiration_datetime');
        }

        $createLink = Link::create([
            'link_id' => $transaction,
            'customer_link_id' => $request->customer_link_id,

            'return_success_link' => $request->return_success_link,
            'return_error_link' => $request->return_error_link,

            'partner_transaction_id' => $request->partner_transaction_id,
            'send_to_phone' => $request->send_to_phone ?? NULL,
            'title' => $request->title,
            'amount' => $request->amount,
            'imali_fee' => $imali_fee,
            'amount_to_credit' => $amount_to_credit,
            'short_description' => $request->short_description,
            'type' => $request->type,
            'status' => $request->type == 'DIRECT' ? 'PENDING' : 'ACTIVE',
            'store_id' => $request->store_id,
            'business_account_id' => $store->business_account_id,
            // 'thumbnail_image' => $img_exists ? substr($image_thumbnail, 39, strlen($image_thumbnail))  : substr($store->logo, 56, strlen($store->logo)),
            // 'thumbnail_image' => $img_exists ? $image_thumbnail : substr($store->logo, 56, strlen($store->logo)),
            // 'thumbnail_image' => $img_exists ? $image_thumbnail : substr($store->logo, strpos($store->logo, 'logo/') + 5, strlen($store->logo)),
            'thumbnail_image' => $image_thumbnail,
            'thumbnail_location' => $img_exists ? 'LINKS' : 'COMERCIANTE_LOGO',
            // 'expiration_datetime' => $request->expiration_datetime,
            'expiration_datetime' => $is_recurring ? null : $request->expiration_datetime,

            'payment_frequence' => $is_recurring ? $request->payment_frequence : null,
            'next_payment_date' => $is_recurring ? $request->next_payment_date : null
        ]);

        // todo -- send SMS

        if ($request->has('send_to_phone') && $request->send_to_phone) {
            $login = new LoginController;
            $login->resendCode(new Request(['phone' => $request->send_to_phone, 'codigo' => $_ENV['PAYMENT_LINK_URL'] . $transaction]));
        }

        // return $createLink;
        return response()->json(['data' => $createLink], 200);
    }

    // update link
    public function updateLinkIIIII(Request $request)
    {
        // Validar imagem
        $this->validate(
            $request,
            [
                'link_id' => 'required',
                'amount' => 'required',
                'type' => 'in:RECURRING,DIRECT,DONATION',
                'thumbnail_image' => 'mimes:jpeg,jpg,png|max:4096',
                'payment_frequence' => 'required_if:type,RECURRING|in:DAILY,WEEKLY,MONTHLY,YEARLY',
            ],
            [
                'link_id.required' => 'O campo link_id é obrigatório',
                'amount.required' => 'O campo amount é obrigatório',
                'type.in' => 'Campo type somente permite RECURRING, DIRECT ou DONATION',
                'thumbnail_image.mimes' => 'Formato de imagem invalido, formatos permitidos jpeg,jpg,png',
                'thumbnail_image.max' => 'O tamanho de imagem permitido somente abaixo de 4 MB',
                'payment_frequence.required_if' => 'Campo payment_frequence é obrigatório',
            ]
        );

        $user = Link::query()->where('link_id', $request->link_id)->first();
        if (!$user) return response()->json(['message' => 'Link fornecido nao existe.'], 409);
        return $user;

        $store = Store::getStoreContractsAndConfigs($user->store_id);
        if (!$store) return response()->json(['message' => 'Loja inválida'], 404);

        if ($request->has('payment_frequence')) {

            $payment_frequence = $request->payment_frequence;
            $current_date = now(); // Data atual


            switch ($payment_frequence) {
                case 'DAILY':
                    # code...
                    $current_date->modify('+24 hours')->format('Y-m-d H:i:s');
                    break;

                case 'WEEKLY':
                    // Adiciona 7 dias à data atual
                    $current_date->modify('+7 days')->format('Y-m-d H:i:s');
                    break;
                case 'MONTHLY':
                    // Adiciona 1 mês à data atual
                    $current_date->modify('+1 month')->format('Y-m-d H:i:s');
                    break;
                case 'YEARLY':
                    // Adiciona 1 ano à data atual
                    $current_date->modify('+1 year')->format('Y-m-d H:i:s');
                    break;

                default:
                    return null;
                    break;
            }

            $request->request->add(['next_payment_date' => $current_date->format('Y-m-d H:i:s')]);
            // return $current_date->format('Y-m-d H:i:s');
        }

        $img_exists = $request->has('thumbnail_image') && $request->thumbnail_image;

        if ($img_exists) {

            $image = new ImageUploader('links');
            $image_thumbnail = $image->generateImageUrlName($request, 'thumbnail_image');
        } else {
            $image_thumbnail = substr($store->logo, strrpos($store->logo, '/') + 1, strlen($store->logo));
        }

        $is_recurring = $request->type == 'RECURRING' ? true : false;

        if ($user) {

            $imali_fee = $request->amount * ($store->taxa / 100);
            $amount_to_credit = $request->amount - $imali_fee;

            $update = Link::query()
                ->update([
                    'amount' => $request->amount,
                    'imali_fee' => $imali_fee,
                    'amount_to_credit' => $amount_to_credit,
                    'type' => $request->type,
                    'thumbnail_image' => $image_thumbnail,
                    'payment_frequence' => $is_recurring ? $request->payment_frequence : null,
                    'next_payment_date' => $is_recurring ? $request->next_payment_date : null
                ]);
            if ($update) {
                return response()->json(['message' => 'Dados actualizados com sucesso.'], 200);
            }
        }
        return $user;
    }

    public function updateLink(Request $request)
    {
        $this->validate(
            $request,
            [
                'link_id' => 'required',
                'amount' => 'required|numeric',
                'type' => 'required|in:RECURRING,DIRECT,DONATION',
                'thumbnail_image' => 'nullable|mimes:jpeg,jpg,png|max:4096',
                'payment_frequence' => 'required_if:type,RECURRING|in:DAILY,WEEKLY,MONTHLY,YEARLY',
            ],
            [
                'link_id.required' => 'O campo link_id é obrigatório',
                'amount.required' => 'O campo amount é obrigatório',
                'type.in' => 'Campo type somente permite RECURRING, DIRECT ou DONATION',
                'thumbnail_image.mimes' => 'Formato de imagem inválido. Permitido: jpeg, jpg, png.',
                'thumbnail_image.max' => 'O tamanho da imagem deve ser menor que 4 MB.',
                'payment_frequence.required_if' => 'Campo payment_frequence é obrigatório para tipo RECURRING.',
            ]
        );

        $link = Link::where('link_id', $request->link_id)->first();
        return $link;
        if (!$link) {
            return response()->json(['message' => 'Link fornecido não existe.'], 409);
        }

        $store = Store::getStoreContractsAndConfigs($link->store_id);
        if (!$store) {
            return response()->json(['message' => 'Loja inválida.'], 404);
        }

        // Calcular next_payment_date se for recorrente
        $next_payment_date = null;
        if ($request->type === 'RECURRING' && $request->filled('payment_frequence')) {
            $now = now();
            switch ($request->payment_frequence) {
                case 'DAILY':
                    $next_payment_date = $now->addDay();
                    break;
                case 'WEEKLY':
                    $next_payment_date = $now->addWeek();
                    break;
                case 'MONTHLY':
                    $next_payment_date = $now->addMonth();
                    break;
                case 'YEARLY':
                    $next_payment_date = $now->addYear();
                    break;
            }
        }

        // Processar imagem
        if ($request->hasFile('thumbnail_image')) {
            $image = new ImageUploader('links');
            $image_thumbnail = $image->generateImageUrlName($request, 'thumbnail_image');
        } else {
            $image_thumbnail = basename($store->logo);
        }

        // Calcular taxas
        $imali_fee = $request->amount * ($store->taxa / 100);
        $amount_to_credit = $request->amount - $imali_fee;

        // Actualizar os dados
        $link->update([
            'amount' => $request->amount,
            'imali_fee' => $imali_fee,
            'amount_to_credit' => $amount_to_credit,
            'type' => $request->type,
            'thumbnail_image' => $image_thumbnail,
            'payment_frequence' => $request->type === 'RECURRING' ? $request->payment_frequence : null,
            'next_payment_date' => $request->type === 'RECURRING' ? $next_payment_date : null,
        ]);

        return response()->json(['message' => 'Dados actualizados com sucesso.'], 200);
    }



    public function getStorePaymentLink($store_account)
    {

        $store = Store::getStoreContractsAndConfigs($store_account);
        if (!$store) return response()->json(['message' => 'Loja inválida'], 400);

        // $store_links = Link::query()
        //     ->join('stores', 'stores.id', 'links.store_id')
        //     ->where('links.store_id', $store->id)
        //     ->get();

        $store_links = Link::query()
            ->join('stores', 'stores.id', 'links.store_id')
            ->select(
                'links.id',
                'links.link_id',
                'links.customer_link_id',
                'links.send_to_phone',
                'links.title',
                'links.amount',
                'links.short_description',
                'links.amount_to_credit',
                'links.expiration_datetime',
                'links.status',
                'links.thumbnail_image',
                'stores.name',
                'links.created_at',
            )
            ->where('links.store_id', $store->id)
            ->get();

        return response()->json(['data' => $store_links], 200);
    }

    // Get Link by link_id or customer_link_id
    public function getStoreLink($link)
    {
        $store_links = Link::query()
            // ->join('business_accounts', 'business_accounts.id', 'links.business_account_id')
            ->join('stores', 'stores.id', 'links.store_id')
            // ->select('links.*', 'business_accounts.name as merchant_name', 'business_accounts.account_number as business_account_number')
            ->select('links.*', 'stores.name as store_name', 'stores.account_number as store_account_number', 'stores.logo')
            ->where('link_id', $link)
            ->orWhere('customer_link_id', $link)
            ->first();

        if ($store_links) $this->checkExpiredLink($store_links);

        // return response()->json($store_links, 200);
        return response()->json(['data' => array($store_links)], 200);
    }
}