<?php

use App\Constants\Status;
use App\Lib\Captcha;
use App\Lib\ClientInfo;
use App\Lib\CurlRequest;
use App\Lib\FileManager;
use App\Lib\GoogleAuthenticator;
use App\Lib\PDFManager;
use App\Models\AccountLevel;
use App\Models\Deposit;
use App\Models\Extension;
use App\Models\Frontend;
use App\Models\GeneralSetting;
use App\Models\Language;
use App\Models\RewardPoint;
use App\Models\RewardPointEarning;
use App\Models\Role;
use App\Models\TableConfiguration;
use App\Models\Transaction;
use App\Notify\Notify;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Laramin\Utility\VugiChugi;

function systemDetails() {
    $system['name']          = 'viserbank';
    $system['version']       = '3.3';
    $system['build_version'] = '5.1.19';
    return $system;
}

function slug($string) {
    return Str::slug($string);
}

function verificationCode($length) {
    if ($length == 0) {
        return 0;
    }

    $min = pow(10, $length - 1);
    $max = (int) ($min - 1) . '9';
    return random_int($min, $max);
}

function getNumber($length = 8) {
    $characters       = '1234567890';
    $charactersLength = strlen($characters);
    $randomString     = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

function activeTemplate($asset = false) {
    $template = session('template') ?? gs('active_template');
    if ($asset) {
        return 'assets/templates/' . $template . '/';
    }

    return 'templates.' . $template . '.';
}

function activeTemplateName() {
    $template = session('template') ?? gs('active_template');
    return $template;
}

function siteLogo($type = null) {
    $name = $type ? "/logo_$type.png" : '/logo.png';
    return getImage(getFilePath('logoIcon') . $name);
}

function siteFavicon() {
    return getImage(getFilePath('logoIcon') . '/favicon.png');
}

function loadReCaptcha() {
    return Captcha::reCaptcha();
}

function loadCustomCaptcha($width = '100%', $height = 46, $bgColor = '#003') {
    return Captcha::customCaptcha($width, $height, $bgColor);
}

function verifyCaptcha() {
    return Captcha::verify();
}

function loadExtension($key) {
    $extension = Extension::where('act', $key)->where('status', Status::ENABLE)->first();
    return $extension ? $extension->generateScript() : '';
}

function getTrx($length = 12) {
    $characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
    $charactersLength = strlen($characters);
    $randomString     = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

function getAmount($amount, $length = 2) {
    $amount = round($amount ?? 0, $length);
    return $amount + 0;
}

function showAmount($amount, $decimal = 2, $separate = true, $exceptZeros = false, $currencyFormat = true, $walletCurrency = null) {
    $separator = '';
    if ($separate) {
        $separator = ',';
    }
    $printAmount = number_format($amount, $decimal, '.', $separator);
    if ($exceptZeros) {
        $exp = explode('.', $printAmount);
        if ($exp[1] * 1 == 0) {
            $printAmount = $exp[0];
        } else {
            $printAmount = rtrim($printAmount, '0');
        }
    }
    if ($currencyFormat) {
        if (gs('currency_format') == Status::CUR_BOTH) {
            if ($walletCurrency) {
                return $walletCurrency->symbol . $printAmount . ' ' . __($walletCurrency->currency);
            }
            return gs('cur_sym') . $printAmount . ' ' . __(gs('cur_text'));
        } else if (gs('currency_format') == Status::CUR_TEXT) {
            if ($walletCurrency) {
                return $printAmount . ' ' . __($walletCurrency->currency);
            }
            return $printAmount . ' ' . __(gs('cur_text'));
        } else {
            if ($walletCurrency) {
                return $walletCurrency->symbol . $printAmount;
            }
            return gs('cur_sym') . $printAmount;
        }
    }
    return $printAmount;
}

function removeElement($array, $value) {
    return array_diff($array, (is_array($value) ? $value : array($value)));
}

function cryptoQR($wallet) {
    return "https://api.qrserver.com/v1/create-qr-code/?data=$wallet&size=300x300&ecc=m";
}

function keyToTitle($text) {
    return ucfirst(preg_replace("/[^A-Za-z0-9 ]/", ' ', $text));
}

function camelCaseToTitleCase($str) {
    return preg_replace('/(?<!^)([A-Z])/', ' $1', $str);
}

function titleToKey($text) {
    return strtolower(str_replace(' ', '_', $text));
}

function strLimit($title = null, $length = 10) {
    return Str::limit($title, $length);
}

function getIpInfo() {
    $ipInfo = ClientInfo::ipInfo();
    return $ipInfo;
}

function osBrowser() {
    $osBrowser = ClientInfo::osBrowser();
    return $osBrowser;
}

function getTemplates() {
    $param['purchasecode'] = env("PURCHASECODE");
    $requestUri            = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
    $param['website']      = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '' . $requestUri . ' - ' . env("APP_URL");
    $url                   = VugiChugi::gttmp() . systemDetails()['name'];
    $response              = CurlRequest::curlPostContent($url, $param);
    if ($response) {
        return $response;
    } else {
        return null;
    }
}

function getPageSections($arr = false) {
    $jsonUrl  = resource_path('views/') . str_replace('.', '/', activeTemplate()) . 'sections.json';
    $sections = json_decode(file_get_contents($jsonUrl));
    if ($arr) {
        $sections = json_decode(file_get_contents($jsonUrl), true);
        ksort($sections);
    }
    return $sections;
}

function getImage($image, $size = null, $avatar = false) {
    $clean = '';
    if (file_exists($image) && is_file($image)) {
        return asset($image) . $clean;
    }
    if ($size) {
        return route('placeholder.image', $size);
    }

    if ($avatar) {
        return asset('assets/images/avatar.png');
    }
    return asset('assets/images/default.png');
}

function notify($user, $templateName, $shortCodes = null, $sendVia = null, $createLog = true, $pushImage = null) {
    $globalShortCodes = [
        'site_name'       => gs('site_name'),
        'site_currency'   => gs('cur_text'),
        'currency_symbol' => gs('cur_sym'),
    ];

    if (gettype($user) == 'array') {
        $user = (object) $user;
    }

    $shortCodes = array_merge($shortCodes ?? [], $globalShortCodes);

    $notify               = new Notify($sendVia);
    $notify->templateName = $templateName;
    $notify->shortCodes   = $shortCodes;
    $notify->user         = $user;
    $notify->createLog    = $createLog;
    $notify->pushImage    = $pushImage;
    $notify->userColumn   = isset($user->id) ? $user->getForeignKey() : 'user_id';
    $notify->send();
}

function getPaginate($paginate = null) {
    if (!$paginate) {
        $paginate = gs('paginate_number');
    }
    return $paginate;
}

function paginateLinks($data, $view = null) {
    return $data->appends(request()->all())->links($view);
}

function menuActive($routeName, $type = null, $param = null) {
    if ($type == 3) {
        $class = 'side-menu--open';
    } else if ($type == 2) {
        $class = 'sidebar-submenu__open';
    } else {
        $class = 'active';
    }

    if (is_array($routeName)) {
        foreach ($routeName as $key => $value) {
            if (request()->routeIs($value)) {
                return $class;
            }

        }
    } else if (request()->routeIs($routeName)) {

        $routeParam = array_values(isset(request()->route()->parameters) ? request()->route()->parameters : []);
        $firstParam = $routeParam[0] ?? null;

        if (is_string($firstParam) && is_string($param) && strcasecmp($firstParam, $param) === 0) {
            return $class;
        }

        return $class;
    }
}

function fileUploader($file, $location, $size = null, $old = null, $thumb = null, $filename = null) {
    $fileManager           = new FileManager($file);
    $fileManager->path     = $location;
    $fileManager->size     = $size;
    $fileManager->old      = $old;
    $fileManager->thumb    = $thumb;
    $fileManager->filename = $filename;
    $fileManager->upload();
    return $fileManager->filename;
}

function fileManager() {
    return new FileManager();
}

function getFilePath($key) {
    return fileManager()->$key()->path;
}

function getFileSize($key) {
    return fileManager()->$key()->size;
}

function getFileExt($key) {
    return fileManager()->$key()->extensions;
}

function diffForHumans($date) {
    $lang = session()->get('lang');
    if (!$lang) {
        $lang = getDefaultLang();
    }

    Carbon::setlocale($lang);
    return Carbon::parse($date)->diffForHumans();
}

function showDateTime($date, $format = 'Y-m-d h:i A') {
    if (!$date) {
        return '-';
    }
    $lang = getDefaultLang();
    Carbon::setlocale($lang);
    return Carbon::parse($date)->translatedFormat($format);
}

function getContent($dataKeys, $singleQuery = false, $limit = null, $orderById = false) {

    $templateName = activeTemplateName();
    if ($singleQuery) {
        $content = Frontend::where('tempname', $templateName)->where('data_keys', $dataKeys)->orderBy('id', 'desc')->first();
    } else {
        $article = Frontend::where('tempname', $templateName);
        $article->when($limit != null, function ($q) use ($limit) {
            return $q->limit($limit);
        });
        if ($orderById) {
            $content = $article->where('data_keys', $dataKeys)->orderBy('id')->get();
        } else {
            $content = $article->where('data_keys', $dataKeys)->orderBy('id', 'desc')->get();
        }
    }
    return $content;
}

function verifyG2fa($user, $code, $secret = null) {
    $authenticator = new GoogleAuthenticator();
    if (!$secret) {
        $secret = $user->tsc;
    }
    $oneCode  = $authenticator->getCode($secret);
    $userCode = $code;
    if ($oneCode == $userCode) {
        $user->tv = Status::YES;
        $user->save();
        return true;
    } else {
        return false;
    }
}

function urlPath($routeName, $routeParam = null) {
    if ($routeParam == null) {
        $url = route($routeName);
    } else {
        $url = route($routeName, $routeParam);
    }
    $basePath = route('home');
    $path     = str_replace($basePath, '', $url);
    return $path;
}

function showMobileNumber($number) {
    $length = strlen($number);
    return substr_replace($number, '***', 2, $length - 4);
}

function showEmailAddress($email) {
    $endPosition = strpos($email, '@') - 1;
    return substr_replace($email, '***', 1, $endPosition);
}

function getRealIP() {
    $ip = $_SERVER["REMOTE_ADDR"];
    //Deep detect ip
    if (filter_var(isset($_SERVER['HTTP_FORWARDED']) ? $_SERVER['HTTP_FORWARDED'] : '', FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_FORWARDED'];
    }
    if (filter_var(isset($_SERVER['HTTP_FORWARDED_FOR']) ? $_SERVER['HTTP_FORWARDED_FOR'] : '', FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_FORWARDED_FOR'];
    }
    if (filter_var(isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '', FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    if (filter_var(isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : '', FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    if (filter_var(isset($_SERVER['HTTP_X_REAL_IP']) ? $_SERVER['HTTP_X_REAL_IP'] : '', FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_X_REAL_IP'];
    }
    if (filter_var(isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : '', FILTER_VALIDATE_IP)) {
        $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
    }
    if ($ip == '::1') {
        $ip = '127.0.0.1';
    }

    return $ip;
}

function appendQuery($key, $value) {
    return request()->fullUrlWithQuery([$key => $value]);
}

function dateSort($a, $b) {
    return strtotime($a) - strtotime($b);
}

function dateSorting($arr) {
    usort($arr, "dateSort");
    return $arr;
}

function gs($key = null) {
    $general = Cache::get('GeneralSetting');
    if (!$general) {
        $general = GeneralSetting::first();
        Cache::put('GeneralSetting', $general);
    }
    if ($key) {
        return isset($general->$key) ? $general->$key : null;
    }

    return $general;
}
function isImage($string) {
    $allowedExtensions = array('jpg', 'jpeg', 'png', 'gif');
    $fileExtension     = pathinfo($string, PATHINFO_EXTENSION);
    if (in_array($fileExtension, $allowedExtensions)) {
        return true;
    } else {
        return false;
    }
}

function isHtml($string) {
    if (preg_match('/<.*?>/', $string)) {
        return true;
    } else {
        return false;
    }
}

function convertToReadableSize($size) {
    preg_match('/^(\d+)([KMG])$/', $size, $matches);
    $size = (int) $matches[1];
    $unit = $matches[2];

    if ($unit == 'G') {
        return $size . 'GB';
    }

    if ($unit == 'M') {
        return $size . 'MB';
    }

    if ($unit == 'K') {
        return $size . 'KB';
    }

    return $size . $unit;
}

function frontendImage($sectionName, $image, $size = null, $seo = false) {
    if ($seo) {
        return getImage('assets/images/frontend/' . $sectionName . '/seo/' . $image, $size);
    }
    return getImage('assets/images/frontend/' . $sectionName . '/' . $image, $size);
}

function buildResponse($remark, $status, $notify, $data = null) {
    $response = [
        'remark' => $remark,
        'status' => $status,
    ];
    $message = [];
    if ($notify instanceof \Illuminate\Support\MessageBag) {
        $message['error'] = collect($notify)->map(function ($item) {
            return $item[0];
        })->values()->toArray();
    } else {
        $message = [$status => collect($notify)->map(function ($item) {
            if (is_string($item)) {
                return $item;
            }
            if (count($item) > 1) {
                return $item[1];
            }
            return $item[0];
        })->toArray()];
    }
    $response['message'] = $message;
    if ($data) {
        $response['data'] = $data;
    }
    return response()->json($response);
}

function responseSuccess($remark, $notify, $data = null) {
    return buildResponse($remark, 'success', $notify, $data);
}

function responseError($remark, $notify, $data = null) {
    return buildResponse($remark, 'error', $notify, $data);
}

function can($code) {
    return Role::hasPermission($code);
}

function createBadge($type, $text) {
    return "<span class='badge badge--$type'>" . trans($text) . '</span>';
}

function getOtpFields() {
    $data = [];

    if (gs('modules')->otp_email) {
        $data[] = 'email';
    }

    if (gs('modules')->otp_sms) {
        $data[] = 'sms';
    }

    if (auth()->user()->ts) {
        $data[] = '2fa';
    }
    return $data;
}

function mergeOtpField($rules = []) {

    $otpFields = getOtpFields();
    if (count($otpFields)) {
        $otpFields          = implode(',', getOtpFields());
        $rules['auth_mode'] = "required|in:$otpFields";
    }
    return $rules;
}

function sessionVerificationId() {
    $id = session()->get('otp_id');
    if (!$id) {
        throw ValidationException::withMessages(['error' => 'Invalid session'])->redirectTo(route('user.home'));
    }
    return $id;
}

function showBadge($status) {

    if ($status) {
        $class = 'text--success';
        $text  = trans('Yes');
    } else {
        $class = 'text--danger';
        $text  = trans('No');
    }

    return '<span class="' . $class . '">' . $text . '</span>';
}

function prepareTableColumn($id, $name, $value = null, $sortable = true, $exportable = true, $filter = null, $filterColumn = null, $filterOptions = [], $link = null, $url = null, $className = null, $echoable = false, $wrapColumnValue = false, $wrapDivClass = null) {
    if (!$value) {
        $value = '$item->' . $id;
    }

    if (is_array($value)) {
        $value = implode(' . ', $value);
    }

    if (!$filterColumn) {
        $filterColumn = $id;
    }

    if ($echoable) {
        $value = 'echo ' . $value;
    } else {
        $value = 'return ' . $value;
    }

    return [
        'id'              => $id,
        'name'            => $name,
        'value'           => trans($value),
        'sortable'        => $sortable,
        'exportable'      => $exportable,
        'filter_column'   => $filterColumn,
        'filter'          => $filter,
        'filter_options'  => $filterOptions,
        'link'            => $link,
        'url'             => $url,
        'className'       => $className,
        'wrapColumnValue' => $wrapColumnValue,
        'wrapDivClass'    => $wrapDivClass,
    ];
}

function makeObject($array) {
    return json_decode(json_encode($array));
}

function tableConfiguration($tableName) {
    return TableConfiguration::where('admin_id', auth()->guard('admin')->id())->where('table_name', $tableName)->first();
}

function is_assoc(array $array) {
    return array_values($array) !== $array;
}

function authStaff() {
    return auth()->guard('branch_staff')->user();
}

function isManager() {
    return authStaff()->designation == Status::ROLE_MANAGER;
}

function checkIsOtpEnable() {
    if (gs('modules')->otp_email || gs('modules')->otp_sms || auth()->user()->ts) {
        return 1;
    }
    return 0;
}

function callApiMethod($routeName, $actionId) {
    $action     = \Route::getRoutes()->getByName($routeName)->getActionName();
    $data       = explode('@', $action);
    $controller = new $data[0];
    $method     = $data[1];
    return $controller->$method($actionId);
}

function downloadPdf($viewName, $data) {
    $pdfManager = new PDFManager($viewName, $data);
    return $pdfManager->generatePDF();
}

function addCustomValidation($validator, $key, $message) {
    $validator->after(function ($validator) use ($key, $message) {
        $validator->errors()->add($key, $message);
    });

    return $validator;
}

function verification() {
    $verification = [];
    $general      = gs();

    if (@$general->modules->otp_email || @$general->modules->otp_sms) {
        $verification['Email'] = @$general->modules->otp_email ? 1 : 0;
        $verification['Sms']   = @$general->modules->otp_sms ? 1 : 0;
    }
    return $verification;
}

function ordinal($number) {
    $ends = ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'];
    if ((($number % 100) >= 11) && (($number % 100) <= 13)) {
        return $number . 'th';
    } else {
        return $number . $ends[$number % 10];
    }
}

function displayRating(float $val) {
    $result = '';
    for ($i = 0; $i < intval($val); $i++) {
        $result .= '<i class="la la-star"></i>';
    }
    if (fmod($val, 1) == 0.5) {
        $i++;
        $result .= '<i class="las la-star-half-alt"></i>';
    }
    for ($k = 0; $k < 5 - $i; $k++) {
        $result .= '<i class="lar la-star"></i>';
    }
    return $result;
}

function generateAccountNumber() {
    $accountNumber = gs('account_no_prefix');
    $uniqueId      = substr(hexdec(uniqid()), -2);
    $accountNumber .= date('ydis') . rand(11, 99) . $uniqueId;
    $suffix = getNumber(gs('account_no_length') - strlen($accountNumber));
    $accountNumber .= $suffix;

    return $accountNumber;
}

function getReferees($user, $maxLevel, $data = [], $depth = 1, $layer = 0) {
    if ($user->allReferees->count() > 0 && $maxLevel > 0) {
        foreach ($user->allReferees as $under) {
            $i = 0;
            if ($i == 0) {
                $layer++;
            }
            $i++;

            $userData['id']       = $under->id;
            $userData['fullname'] = $under->fullname;
            $userData['username'] = $under->username;
            $userData['level']    = $depth;
            $data[]               = $userData;
            if ($under->allReferees->count() > 0 && $layer < $maxLevel) {
                $data = getReferees($under, $maxLevel, $data, $depth + 1, $layer);
            }
        }
    }
    return $data;
}

function getDefaultLang() {
    return Language::where('is_default', Status::YES)->first()->code ?? 'en';
}

function stripeSecretKey() {
    return gs('stripe_secret_key');
}

function stripePublishableKey() {
    return gs('stripe_publishable_key');
}

function stripeVersion() {
    return '2022-08-01';
}

function stripeValidCountryCodes() {
    $countryShortcodes = [
        'AT', // Austria
        'BE', // Belgium
        'HR', // Croatia
        'CY', // Cyprus
        'EE', // Estonia
        'FI', // Finland
        'FR', // France
        'DE', // Germany
        'GR', // Greece
        'IE', // Ireland
        'IT', // Italy
        'LV', // Latvia
        'LT', // Lithuania
        'LU', // Luxembourg
        'MT', // Malta
        'NL', // Netherlands
        'PT', // Portugal
        'SK', // Slovakia
        'SI', // Slovenia
        'ES', // Spain
        'GB', // United Kingdom
        'US', // United States
    ];
    return $countryShortcodes;
}

function countryStates($countryCode = 'US') {
    $states = config('states.' . strtoupper($countryCode), []);
    return $states;
}

function currencyRate($currency) {
    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_URL            => 'https://v6.exchangerate-api.com/v6/' . gs('currency_api_key') . '/pair/' . gs('cur_text') . '/' . $currency,
        CURLOPT_HTTPHEADER     => array(
            "Content-Type: text/plain",
        ),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => "",
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST  => "GET",
    ));

    $response = json_decode(curl_exec($curl));
    curl_close($curl);
    return $response->conversion_rate ?? 0;
}

function updateAccountLevel($user) {
    if (@gs('modules')->account_level) {
        $totalDeposits = Deposit::successful()->where('user_id', $user->id)->sum('amount');
        $accountLevels = AccountLevel::active()
            ->where('min_transaction_amount', '<=', $totalDeposits)
            ->when($user->accountLevel, function ($query) use ($user) {
                $query->where('min_transaction_amount', '>', ($user->accountLevel?->min_transaction_amount ?? 0));
            })
            ->orderBy('min_transaction_amount')
            ->get();

        foreach ($accountLevels as $accountLevel) {
            if ($accountLevel && $user->account_level_id != $accountLevel->id) {
                $user->account_level_id = $accountLevel->id;
                $user->save();

                if ($accountLevel->bonus_amount) {
                    accountLevelBonus($user, $accountLevel, $totalDeposits);
                }
            }
            continue;
        }
    }
}

function accountLevelBonus($user, $accountLevel, $totalDeposits) {
    if ($accountLevel->bonus_amount > 0) {
        $user->balance += $accountLevel->bonus_amount;
        $user->save();

        // transaction
        $transaction               = new Transaction();
        $transaction->user_id      = $user->id;
        $transaction->wallet_id    = 0;
        $transaction->amount       = $accountLevel->bonus_amount;
        $transaction->post_balance = $user->balance;
        $transaction->charge       = 0;
        $transaction->trx_type     = '+';
        $transaction->details      = 'Received account level up bonus (' . $accountLevel->name . ')';
        $transaction->remark       = 'received_level_up_bonus';
        $transaction->trx          = getTrx();
        $transaction->save();

        // notify
        notify($user, 'ACCOUNT_LEVEL_UP_BONUS', [
            'user_name'     => $user->user_name,
            'account_level' => $accountLevel->name,
            'bonus_amount'  => showAmount($accountLevel->bonus_amount, currencyFormat: false),
            'total_deposit' => showAmount($totalDeposits, currencyFormat: false),
            'post_balance'  => $user->balance,
        ]);
    }
}

function rewardTypes($key = null) {
    $types = [
        Status::DEPOSIT_REWARD             => "Deposit Reward",
        Status::WITHDRAW_REWARD            => "Withdraw Reward",
        Status::FDR_REWARD                 => "FDR Reward",
        Status::DPS_REWARD                 => "DPS Reward",
        Status::LOAN_REWARD                => "Loan Reward",
        Status::OWN_BANK_TRANSFER_REWARD   => "Own Bank Transfer Reward",
        Status::OTHER_BANK_TRANSFER_REWARD => "Other Bank Transfer Reward",
        Status::WIRE_TRANSFER_REWARD       => "Wire Transfer Reward",
    ];
    if ($key) {
        return $types[$key] ?? "";
    }
    return $types;
}

function updateRewardPoint($type, $user, $amount, $details) {
    $reward = RewardPointEarning::active('transaction_amount', $amount)
        ->where(function ($q) use ($user) {
            $q->whereNull('account_level_id')
                ->orWhere('account_level_id', $user->account_level_id);
        })
        ->where(function ($q) {
            $q->whereNull('started_at')
                ->orWhere('started_at', '<=', now());
        })
        ->where(function ($q) {
            $q->whereNull('expired_at')
                ->orWhere('expired_at', '>=', now());
        })
        ->whereJsonContains('reward_type', (string) $type)
        ->first();
    if ($reward && ($reward->max_use > $reward->total_used || $reward->max_use == -1)) {
        $totalReward = RewardPoint::where('user_id', $user->id)->where('reward_point_earning_id', $reward->id)->count();
        if ($reward->per_user_limit > $totalReward || $reward->per_user_limit == -1) {
            $reward->total_used++;
            $reward->save();

            $user->reward_point += $reward->reward_point;
            $user->save();

            $rewardPoint                          = new RewardPoint();
            $rewardPoint->user_id                 = $user->id;
            $rewardPoint->reward_point_earning_id = $reward->id;
            $rewardPoint->reward_point            = $reward->reward_point;
            $rewardPoint->details                 = $details;
            $rewardPoint->save();
        }
    }
}

function allowRewardRedeem($reward, $user) {
    if (($reward->account_level_id && $user->account_level_id == $reward->account_level_id) || !$reward->account_level_id) {
        if ($user->reward_point >= $reward->redeem_point) {
            return true;
        }
    }

    return false;
}
