<?php

use App\Enums\Status;
use App\Enums\TransactionStatus;
use App\Enums\OrderStatus;
use App\Enums\UserStatus;
use App\Helpers\MiHash;
use App\Models\Rate;
use App\Models\Setting;
use App\Services\ActivityLogger;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail;
use App\Mail\AppMailer;
use Carbon\Carbon;

/************** JSON HELPERS ***************/
if (!function_exists('is_json')) {
    function is_json($string, $decode = false)
    {
        if (is_array($string))
            return false;

        json_decode($string);
        $check = json_last_error() === JSON_ERROR_NONE;

        return $decode && $check ? json_decode($string) : $check;
    }
}

if (!function_exists('json_to_array')) {
    function json_to_array($string, $assoc = true)
    {
        return is_json($string) ? json_decode($string, $assoc) : $string;
    }
}

if (!function_exists('get_json_value')) {
    function get_json_value($string, $key)
    {
        $data = is_json($string) ? json_decode($string) : $string;
        return $data->$key ?? '';
    }
}

/************** SYSTEM & SITE HELPERS ***************/
if (!function_exists('system_details')) {
    function system_details(): array
    {
        return ['name' => 'Miclab', 'version' => '1.0'];
    }
}

if (!function_exists('site_details')) {
    function site_details(string $output = 'name')
    {
        $infos = [
            'apps' => env('APP_NAME', 'My App'),
            'name' => system_settings('site_name'),
            'author' => config('app.author'),
            'url' => url('/'),
            'url_only' => str_replace(['https://', 'http://'], '', url('/')),
            'url_app' => config('app.url')
        ];

        return $output === 'all' ? $infos : Arr::get($infos, $output, '');
    }
}

if (!function_exists('system_settings')) {
    function system_settings(string $key, $default = null)
    {
        $settings = Setting::getAllCached();

        $value = $settings[$key] ?? $default;

        if (is_string($value) && is_json($value)) {
            return json_decode($value, true);
        }

        return $value;
    }
}


if (!function_exists('active_theme')) {
    function active_theme(): string
    {
        $template = system_settings('active_theme') ?? 'default';
        $view = "template.$template.";
        return view()->exists($view . 'index') ? $view : 'template.default.';
    }
}

/************** COLLECTION CHECK ***************/
if (!function_exists('is_collection')) {
    function is_collection($param): bool
    {
        return $param instanceof \Illuminate\Support\Collection || $param instanceof \Illuminate\Database\Eloquent\Collection;
    }
}

/************** ENUM HELPERS ***************/
if (!function_exists('get_enums')) {
    function get_enums(string $enumClass, bool $flip = false): array
    {
        try {
            $cases = $enumClass::cases();

            $list = [];
            foreach ($cases as $case) {
                $list[$case->value] = $case->name;  // value => NAME
            }

            return $flip ? array_flip($list) : $list;

        } catch (\Throwable $e) {
            if (env('APP_DEBUG')) {
                save_error_log($e, 'enum-reflection');
            }
            return [];
        }
    }
}


/************** LOGGING HELPERS ***************/
if (!function_exists('login_log')) {
    function login_log($message = null)
    {
        app(ActivityLogger::class)->saveUserLogin($message);
    }
}

if (!function_exists('activity_log')) {
    function activity_log($mid, $cid, $activity = '', $message = null)
    {
        app(ActivityLogger::class)->saveActivityLog($mid, $cid, $activity, $message);
    }
}

if (!function_exists('randFloat')) {
    function randFloat($min, $max, $decimals = 2)
    {
        $float = $min + mt_rand() / mt_getrandmax() * ($max - $min);
        return round($float, $decimals);
    }
}
/************** SELECT HELPERS ***************/
if (!function_exists('get_selected')) {
    /**
     * Return "selected" if values match
     */
    function get_selected($val, $val2 = null): string
    {
        return $val == $val2 ? 'selected' : '';
    }
}

if (!function_exists('get_checked')) {
    /**
     * Return "checked" if values match
     */
    function get_checked($val, $val2 = null): string
    {
        return $val == $val2 ? 'checked' : '';
    }
}

if (!function_exists('select_options')) {
    /**
     * Generate HTML <option> tags for select inputs.
     *
     * @param array|string $source Array of values, or 'fiat', 'crypto', 'all', 'countries'
     * @param mixed $selected Selected value(s)
     * @param bool $use_key_as_value If true, array keys are used as option values
     * @return string
     */
    function select_options(array|string $source, $selected = null, bool $use_key_as_value = true): string
    {
        // Handle special sources
        if (is_string($source)) {
            $source = match (strtolower($source)) {
                'fiat' => get_fiat_currency(),
                'crypto' => get_crypto_currency(),
                'all' => get_all_currency(),
                'countries' => config('countries.country_three_abbr', []), // from config/countries.php
                default => []
            };
        }

        $options_html = '';
        foreach ($source as $key => $value) {
            // Support both simple array and associative arrays
            if (is_array($value) && isset($value['code'], $value['name'])) {
                $val = $value['code'];
                $label = $value['name'] . " ({$val})";
            } else {
                $val = $use_key_as_value ? $key : $value;
                $label = $value;
            }

            $is_selected = (is_array($selected) ? in_array($val, $selected) : $val == $selected) ? ' selected' : '';
            $options_html .= "<option value='{$val}'{$is_selected}>{$label}</option>\n";
        }

        return $options_html;
    }
}


/************** SYSTEM INFO ***************/
if (!function_exists('get_mac_address')) {
    function get_mac_address(): ?string
    {
        if (stripos(PHP_OS, 'WIN') === 0) {
            @exec('getmac', $output);
            foreach ($output as $line) {
                if (preg_match('/([0-9A-F]{2}[:-]){5}[0-9A-F]{2}/i', $line, $matches))
                    return $matches[0];
            }
        }

        @exec('ifconfig -a 2>/dev/null || ip link 2>/dev/null', $output);
        foreach ($output as $line) {
            if (preg_match('/([0-9a-f]{2}[:-]){5}[0-9a-f]{2}/i', $line, $matches)) {
                $mac = $matches[0];
                if ($mac !== '00:00:00:00:00:00')
                    return $mac;
            }
        }

        return null;
    }
}

if (!function_exists('get_user_agent')) {
    function get_user_agent(): ?string
    {
        return request()->header('User-Agent');
    }
}

/************** HASH & UID HELPERS ***************/
if (!function_exists('hash_of')) {
    function hash_of($data, $match = null)
    {
        return MiHash::of($data, $match);
    }
}

if (!function_exists('generate_uid')) {
    function generate_uid($userID): string
    {
        return 'UID' . str_pad($userID, 5, '0', STR_PAD_LEFT);
    }
}

if (!function_exists('hash_to_id')) {
    function hash_to_id($data)
    {
        return MiHash::toID($data);
    }
}

/************** RANDOM STRINGS & USERNAMES ***************/
if (!function_exists('random_string')) {
    function random_string(string $type = 'alnum', int $length = 8): string
    {
        $pool = match ($type) {
            'basic' => (string) mt_rand(),
            'alpha' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
            'alnum' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
            'capalnum' => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
            'numeric' => '0123456789',
            'nozero' => '123456789',
            'md5', 'unique' => md5(uniqid(mt_rand(), true)),
            'sha1', 'encrypt' => sha1(uniqid(mt_rand(), true)),
            default => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        };

        return in_array($type, ['basic', 'md5', 'unique', 'sha1', 'encrypt']) ? $pool
            : substr(str_shuffle(str_repeat($pool, ceil($length / strlen($pool)))), 0, $length);
    }
}

if (!function_exists('generate_unique_username')) {
    function generate_unique_username(string $name = null, int $suffix = 4): string
    {
        $base = $name ? Str::slug($name) : 'user';
        $username = $base . '-' . random_string('alnum', $suffix);

        while (\App\Models\User::where('username', $username)->exists()) {
            $username = $base . '-' . random_string('alnum', $suffix);
        }

        return $username;
    }
}

/************** HTML AUTO PARAGRAPH ***************/
if (!function_exists('auto_paragraph')) {
    function auto_paragraph(string $text, bool $br = true): string
    {
        $text = trim(str_replace(["\r\n", "\r"], "\n", $text));
        if (empty($text))
            return '';

        $paragraphs = preg_split("/\n\s*\n/", $text, -1, PREG_SPLIT_NO_EMPTY);

        foreach ($paragraphs as &$p) {
            $p = '<p>' . trim($p) . '</p>';
            if ($br)
                $p = preg_replace("/(?<!<\/p>)\n/", "<br />\n", $p);
        }

        return implode("\n\n", $paragraphs);
    }
}

/************** CURRENCY HELPERS ***************/
if (!function_exists('get_fiat_currency')) {
    function get_fiat_currency($symbol = false)
    {
        $fiat = config('currencies.FIAT', []);
        return $symbol ? ($fiat[$symbol] ?? null) : $fiat;
    }
}

if (!function_exists('get_crypto_currency')) {
    function get_crypto_currency($symbol = false)
    {
        $crypto = config('currencies.CRYPTO', []);
        return $symbol ? ($crypto[$symbol] ?? null) : $crypto;
    }
}

if (!function_exists('get_all_currency')) {
    function get_all_currency(): array
    {
        return array_merge(get_fiat_currency(), get_crypto_currency());
    }
}

if (!function_exists('currency_select_html')) {
    function currency_select_html(string $type = 'all', $selected = null): string
    {
        $currencies = match ($type) {
            'fiat' => get_fiat_currency(),
            'crypto' => get_crypto_currency(),
            default => get_all_currency()
        };

        $html = '';
        foreach ($currencies as $cur) {
            $code = $cur['code'];
            $name = $cur['name'];
            $html .= "<option value='{$code}'" . ($code == $selected ? ' selected' : '') . ">{$name} ({$code})</option>";
        }
        return $html;
    }
}

/************** NUMBER FORMATTING HELPERS ***************/
if (!function_exists('format_number')) {
    function format_number($amount, $digits=2): string
    {
        return number_format($amount, $digits, '.', ',');
    }
}

if (!function_exists('coin_format')) {
    function coin_format($amount, $digits): string
    {
        return format_number($amount, $digits);
    }
}

if (!function_exists('fiat_format')) {
    function fiat_format($amount): string
    {
        $digits = system_settings('decimal_fiat', 2);
        return format_number($amount, $digits);
    }
}

/************** TRANSACTION HELPERS ***************/
if (!function_exists('generate_txn')) {
    function generate_txn(string $prefix = ''): string
    {
        return $prefix . mt_rand(10010, 99999) . substr(time(), -4);
    }
}

if (!function_exists('get_transaction_icon_status')) {
    function get_transaction_icon_status($status)
    {
        return $status;
    }
}


/************** DATE / TIME HELPERS ***************/
if (!function_exists('calculate_relative_time')) {
    function calculate_relative_time($time): string
    {
        $time = $time instanceof Carbon ? $time : Carbon::parse($time);
        return $time->diffForHumans(Carbon::now());
    }
}

if (!function_exists('format_date')) {
    function format_date($date, string $format = "M d, Y", bool $use_time = false, bool $timezone = false): ?string
    {
        if (empty($date))
            return null;
        $date = $date instanceof Carbon ? $date : (is_numeric($date) ? Carbon::createFromTimestamp($date) : Carbon::parse($date));

        if (!$format) {
            $format = system_settings('date_form', 'Y-m-d');
            if ($use_time)
                $format .= ' ' . system_settings('time_form', 'H:i:s');
        }

        if ($timezone) {
            $tz = system_settings('time_zone', config('app.timezone'));
            return $date->timezone($tz)->format($format);
        }

        return $date->format($format);
    }
}

/************** VERIFICATION HELPERS ***************/
if (!function_exists('has_recaptcha')) {
    function has_recaptcha(): bool
    {
        return system_settings('recaptcha') !== 'off'
            && !empty(system_settings('recaptcha_site_key'))
            && !empty(system_settings('recaptcha_site_secret'));
    }
}

if (!function_exists('require_email')) {
    function require_email(): bool
    {
        return (bool) system_settings('email_verification');
    }
}

if (!function_exists('require_2fa')) {
    function require_2fa(): bool
    {
        return system_settings('enable_2fa') !== 'off';
    }
}

/************** COUNTRY HELPERS ***************/
if (!function_exists('get_country_three_abbr')) {
    /**
     * Convert 2-letter country code to 3-letter code
     */
    function get_country_three_abbr($twoAbbr): string
    {
        $map = config('countries.country_two_to_three', []);
        return $map[$twoAbbr] ?? $twoAbbr;
    }
}

if (!function_exists('get_country_two_abbr')) {
    /**
     * Convert 3-letter country code to 2-letter code
     */
    function get_country_two_abbr(string $threeAbbr): string
    {
        $map = config('countries.country_three_to_two', []);
        return $map[$threeAbbr] ?? $threeAbbr;
    }
}

if (!function_exists('get_country_name')) {
    /**
     * Get full country name from 2-letter or 3-letter code
     */
    function get_country_name($code = ''): mixed
    {
        $countries = config('countries.country_three_abbr', []); // code => name
        return $countries[$code] ?? $code;
    }
}

if (!function_exists('country_select_html')) {
    /**
     * Generate <option> tags for countries
     *
     * @param string|array|null $selected
     * @param string $value_type 'two', 'three', 'name'
     */
    function country_select_html($selected = null, string $value_type = 'three'): string
    {
        $countries = config('countries.country_three_abbr', []);
        $options = '';

        foreach ($countries as $three => $name) {
            $value = match ($value_type) {
                'two' => get_country_two_abbr($three),
                'name' => $name,
                default => $three,
            };

            $isSelected = (is_array($selected) ? in_array($value, $selected) : $value == $selected) ? ' selected' : '';
            $options .= "<option value='{$value}'{$isSelected}>{$name}</option>\n";
        }

        return $options;
    }
}


/************** BALANCE HELPERS ***************/

if (!function_exists('get_exchange_price')) {
    function get_exchange_price($base, $quote)
    {
        $cacheKey = "{$base}-{$quote}";

        $price = cache()->remember($cacheKey, 600, function () use ($base, $quote) {
            return Rate::where('from_currency', $base)
                ->where('to_currency', $quote)
                ->first();
        });
        $price = Rate::where('from_currency', $base)
                ->where('to_currency', $quote)
                ->first();
        
        return [
            'price'    => $price?->rate ?? 1,
            'previous' => $price?->previous_rate ?? 1,
        ];
    }
}

if (!function_exists('get_exchange_current')) {
    function get_exchange_current($base, $quote)
    {
        // Get full rate array
        $rate = get_exchange_price($base, $quote);

        // Always return numeric price (float)
        return floatval($rate['price'] ?? 1);
    }
}

if (!function_exists('get_exchange_previous')) {
    function get_exchange_previous($base, $quote)
    {
        // Get full rate array
        $rate = get_exchange_price($base, $quote);

        // Always return numeric price (float)
        return floatval($rate['previous'] ?? 1);
    }
}


if (!function_exists('get_user_exchange_rate')) {
    function get_user_exchange_rate()
    {
        $user = auth()->user();
        return get_exchange_price(system_settings('currency'), $user->currency ?? 'USD');
    }
}


if (!function_exists('get_system_exchange_price')) {
    function get_system_exchange_price($quote)
    {
        return get_exchange_price(system_settings('currency'), $quote);
    }
}


if (!function_exists('get_total_balance')) {
    function get_total_balance()
    {
        $user = auth()->user();
        $wallets = $user->wallets;

        $fiatAmount = 0;

        foreach ($wallets as $wallet) {
            // Convert each wallet balance to fiat
            $fiatAmount += $wallet->convertedBalance($user->userCurrency) ;
      
        }

        // Convert fiat total to crypto using user's preferred crypto currency
        $cryptoPrice  = get_exchange_current($user->userCurrency , $user->cryptoCurrency) ?? 1;
        $cryptoAmount = $cryptoPrice * $fiatAmount;

        return [
            'fiat'   => $fiatAmount,
            'crypto' => $cryptoAmount,
        ];
    }
}

if (!function_exists('get_exchange_difference')) {
    function get_exchange_difference($curr1, $curr2)
    {
        $rate = get_exchange_current($curr1, $curr2);
        $previous_rate = get_exchange_previous($curr1, $curr2);

        // Prevent division by zero or null
        if ($rate === null || $rate == 0) {
            return [
                'class' => '',
                'diff' => 0,
                'percentage' => 0
            ];
        }

        // Default previous rate to current if null
        if ($previous_rate === null) {
            $previous_rate = $rate;
        }

        $dif = $rate - $previous_rate;
        $per = $dif / $rate;

        // Determine class color
        $class = '';
        $d = '';
        if ($dif < 0) {
            $class = 'text-red-400';
            
        } elseif ($dif > 0) {
            $class = 'text-green-400';
            $d  = "+";
        }
        

        return [
            'd' => $d,
            'class' => $class,
            'diff' => $d . fiat_format($dif),
            'percentage' => $d . fiat_format($per)."%"
        ];
    }
}


 if (!function_exists('get_historic_price')) {
     /**
      * @Get crypto Price
      * Param $string , $default value
      * @version 1.0.0
      * @return object or json
      */
     function get_historic_price($curr1, $curr2, $limit = 365)
     {
         $cachename = strtoupper($curr1) . strtoupper($curr2) . 'history';
         $price = Cache::remember($cachename, 600, function () use ($curr1, $curr2, $limit) {
             $Api = new CryptoCompare();
             $priceHistory = $Api->get_price_history($curr1, $curr2, $limit);
             $prices = [];

             if ($priceHistory['Response'] == 'Success') {
                 if (array_key_exists('Data', $priceHistory)) {
                     $ndata = $priceHistory['Data']['Data'];

                     foreach ($ndata as $n) {
                         $prices[] = $n['close'];
                     }
                 }
             }

             return $prices;
         });

         return $price;
     }
 }

/************** USER HELPERS ***************/

if (!function_exists('get_status_badge')) {
    function get_status_badge(string $status, $type): string
    {
        $status = strtoupper($status);

        return match ($type) {
            'success' =>
            "<span class='bg-gradient-to-tl from-emerald-500 to-teal-400 px-2.5 py-1.4 text-xs rounded-1.8 font-bold text-white uppercase'>{$status}</span>",
            'primary' =>
            "<span class='bg-gradient-to-tl from-blue-600 to-blue-300  px-2.5 text-xs rounded-1.8 py-1.4 inline-block whitespace-nowrap text-center align-baseline font-bold uppercase leading-none text-white'>{$status}</span",

            'danger' =>
            "<span class='bg-gradient-to-tl from-red-500 to-red-200 px-2.5 text-xs rounded-1.8 py-1.4 inline-block whitespace-nowrap text-center align-baseline font-bold uppercase leading-none text-white'>{$status}</span",

            'info' =>
            "<span class='bg-gradient-to-tl from-slate-600 to-slate-300  px-2.5 text-xs rounded-1.8 py-1.4 inline-block whitespace-nowrap text-center align-baseline font-bold uppercase leading-none text-white'>{$status}</span",

            default =>
            "<span class='bg-gradient-to-tl from-slate-600 to-slate-300  px-2.5 text-xs rounded-1.8 py-1.4 inline-block whitespace-nowrap text-center align-baseline font-bold uppercase leading-none text-white'>{$status}</span",
        };
    }
}

if (!function_exists('get_user_status_badge')) {
    function get_user_status_badge(string $status): string
    {
        $status = strtolower($status);
        $type = match ($status) {
            'active' => 'success',
            'inactive', 'suspended', 'disabled', 'held' => 'danger',
            'review', 'id_review', 'pending' => 'info',
            default => 'primary',
        };

        return get_status_badge($status, $type);
    }
}

if (!function_exists('get_active_status_badge')) {
    function get_active_status_badge(int $status): string
    {

        $status = $status ? 'active' : 'inactive';
        $type = match ($status) {
            'active' => 'success',
            'inactive' => 'danger',
            default => 'primary',
        };

        return get_status_badge($status, $type);
    }
}

if (!function_exists('get_kyc_status')) {
    function get_kyc_status($status)
    {
        return match($status){
            '0' => 'Unverified',
            '1' => 'Verified',
            '2' => 'Pending',
            '3' => 'Rejected',
            default => 'Unverified'
        };
    }
}

if (!function_exists('status_select')) {
    function status_select($selected = null)
    {
        return select_options([
            Status::ACTIVE->value => 'active',
            Status::INACTIVE->value => 'inactive',
        ], $selected);
    }
}

if (!function_exists('user_status_select')) {
    function user_status_select($selected = null)
    {
        $userStatus = get_enums(UserStatus::class);
        return select_options($userStatus, $selected);
    }
}

if (!function_exists('transaction_status_select')) {
    function transaction_status_select($selected = null)
    {
        $transactionStatus = get_enums(TransactionStatus::class);
        return select_options($transactionStatus, $selected);
    }
}

if (!function_exists('get_order_edit_select')) {
    function get_order_edit_select($selected = null)
    {
        $transactionStatus = get_enums(OrderStatus::class);
        return select_options($transactionStatus, $selected);
    }
}

if (!function_exists('get_transaction_status')) {
    /**
     * Get Country 2 letter Abbreviation .
     * @version 1.0.0
     * @since 1.0
     */
    function get_transaction_class($status)
    {
        if ($status == TransactionStatus::CONFIRMED->value) {
            return "text-success";
        } elseif ($status == TransactionStatus::HOLD->value || $status == TransactionStatus::PENDING->value) {
            return "text-warning";
        } elseif ($status == TransactionStatus::FAILED->value || $status == TransactionStatus::CANCELLED->value || $status == TransactionStatus::DECLINED->value) {
            return "text-danger";
        }
        return '';
    }
}

if (!function_exists('upload_files')) {
    /**
     * Upload a file to a specified location.
     *
     * @param \Illuminate\Http\Request $request The HTTP request object
     * @param string $field The name of the file input field
     * @param string $location Relative path from base_path to store file
     * @param bool $is_image Whether to validate for image MIME types
     * @return array An array with 'status', 'photoPath', and optionally 'error'
     */
    function upload_files($request, string $field, string $location, bool $is_image = true): array
    {
        $data = [
            'status' => false,
            'photoPath' => null,
        ];

        if ($request->hasFile($field)) {
            try {
                $path = public_path('/uploads/' . $location);

                if (!file_exists($path)) {
                    mkdir($path, 0755, true);
                }

                $file = $request->file($field);
                $extension = $file->getClientOriginalExtension();
                if ($is_image) {
                    if (!in_array($extension, ['jpeg', 'png', 'gif', 'jpg'])) {
                        throw new \Exception('Upload must be a jpg, png, or gif image.');
                    }

                    if (!in_array($file->getClientMimeType(), ['image/jpeg', 'image/png', 'image/gif', 'image/jpg'])) {
                        throw new \Exception('Upload must be a jpg, png, or gif image.');
                    }
                }
                $extension = $file->getClientOriginalExtension();
                $filename = time() . '_' . md5($file->getClientOriginalName()) . '.' . $extension;
                $file->move($path, $filename);

                $data['status'] = true;
                $data['file'] = $filename;
            } catch (\Exception $e) {
                $data['error'] = $e->getMessage();
            }
        } else {
            $data['nullable'] = true;
            $data['error'] = 'No file uploaded';
        }

        return $data;
    }
}

if (!function_exists('currency_sign')) {
    /**
     * Get Country 2 letter Abbreviation .
     * @version 1.0.0
     * @since 1.0
     */
    function currency_sign($status){
        $currencies = get_all_currency();
        return $currencies[$status]['sign'] ?? '$';
    }
}

if(!function_exists('route_class')){
    function route_class($sym = 'dashboard'){
        $symbol = 'boss';
     if(Route::is($sym)){
        $symbol =  'active'; 
     }  else{
        $symbol =  Route::currentRouteName();  
     }
     return $symbol;
    }
}

 if (!function_exists('get_currency_select')) {
     /**
      * Get Country 2 letter Abbreviation .
      * @version 1.0.0
      * @since 1.0
      */
     function get_currency_select($type = 'all', $selected = null)
     {
         if ($type == 'fiat') {
             $currencies = get_fiat_currency();
         } elseif ($type == 'crypto') {
             $currencies = get_crypto_currency();
         } elseif ($type == 'all') {
             $currencies = get_all_currency();
         }
         $select = '';
         foreach ($currencies as $currency) {
             $code = $currency['code'];
             $name = $currency['name'];
             $select .= "<option value = '" . $code . "' ";
             if ($code == $selected) {
                 $select .= 'selected';
             }
             $select .= " >" . $name . " (" . $code . ")</option>";
         }
         return $select;
     }
 }
 
  if (!function_exists('get_country_select_html')) {
     /**
      * Get Country 2 letter Abbreviation .
      * @version 1.0.0
      * @since 1.0
      */
     function get_country_select_html($selected = null)
     {
         $countries = config('countries.country_three_abbr');

         $select = '';
         foreach ($countries as $key => $country) {
             $select .= "<option value = '" . $key . "' ";
             if ($key == $selected) {
                 $select .= 'selected';
             }
             $select .= " >" . $country . "</option>";
         }
         return $select;
     }
 }
 
  if (!function_exists('get_country_full_select_html')) {
     /**
      * Get Country 2 letter Abbreviation .
      * @version 1.0.0
      * @since 1.0
      */
     function get_country_full_select_html($selected = null)
     {
         $countries = config('countries.country_three_abbr');

         $select = '';
         foreach ($countries as $country) {
             $select .= "<option value = '" . $country . "' ";
             if ($country == $selected) {
                 $select .= 'selected';
             }
             $select .= " >" . $country . "</option>";
         }
         return $select;
     }
 }
 
 if (!function_exists('get_transaction_type_select')) {
    function get_transaction_type_select(?string $selected = null): string
    {
        $reflection = new \ReflectionClass(\App\Enums\TransactionType::class);
        $constants = $reflection->getConstants();

        $html = '';
        foreach ($constants as $val) {
            $value = $val->value;
            $isSelected = $selected === $value ? 'selected' : '';
            $html .= "<option value=\"$value\" $isSelected>" . ucfirst($value) . "</option>\n";
        }
        return $html;
    }
}

if (!function_exists('get_transaction_status_select')) {
    function get_transaction_status_select(?string $selected = null): string
    {
        $reflection = new \ReflectionClass(\App\Enums\TransactionStatus::class);
        $constants = $reflection->getConstants();

        $html = '';
        foreach ($constants as $val) {
            $value = $val->value;
            $isSelected = $selected === $value ? 'selected' : '';
            $html .= "<option value=\"$value\" $isSelected>" . ucfirst($value) . "</option>\n";
        }
        return $html;
    }
}

if (!function_exists('get_transaction_edit_select')) {

    /**
     * Generate an HTML <select> dropdown with options based on TransactionStatus enum.
     *
     * @param string|null $selected The selected option value.
     * @return string The HTML <select> element.
     */
    function get_transaction_edit_select(?string $selected = null): string
    {
      
        $statuses = [\App\Enums\TransactionStatus::COMPLETED->value, \App\Enums\TransactionStatus::HOLD->value, \App\Enums\TransactionStatus::PENDING->value, \App\Enums\TransactionStatus::FAILED->value, \App\Enums\TransactionStatus::DECLINED->value,\App\Enums\TransactionStatus::NOT_PAID->value];
        
        $html = '';
        foreach ($statuses as $value) {
          
            $isSelected = $selected === $value ? 'selected' : '';
      
            $html .= "    <option value=\"$value\" $isSelected>" . ucfirst($value) . "</option>\n";
        }

      

        return $html;
    }

}

if (!function_exists('update_balance')) {

function update_balance($userId, $amount, $operation = 'increase')
{
    // Validate inputs
    if (!in_array($operation, ['increase', 'decrease'])) {
        return response()->json(['error' => 'Invalid operation'], 400);
    }
    

    \Illuminate\Support\Facades\DB::beginTransaction();

    try {
        // Fetch user balance record
        $userBalance = \App\Models\UserBalance::where('user', $userId)->lockForUpdate()->first();

        if (!$userBalance) {
            return response()->json(['error' => 'User balance record not found'], 404);
        }
     
        // Adjust balance based on operation
        if ($operation === 'increase') {
            $userBalance->balance += $amount; 
        } elseif ($operation === 'decrease') {
        
            if ($userBalance->balance < $amount) {
                return response()->json(['error' => 'Insufficient balance'], 400);
            }
            $userBalance->balance -= $amount; // Decrease balance
        }

       
        $userBalance->save();

       
        \Illuminate\Support\Facades\DB::commit();

        return response()->json([
            'success' => true,
            'message' => "Balance {$operation}d successfully",
            'new_balance' => $userBalance->balance,
        ], 200);
    } catch (\Exception $e) {
       
        \Illuminate\Support\Facades\DB::rollBack();

        return response()->json([
            'error' => 'Failed to update balance',
            'message' => $e->getMessage(),
        ], 500);
    }
}

}

if (!function_exists('get_account_type')) {
    function get_account_type($account){
        return match($account){
        'holding_balance' => 'holding',
        'trading_balance_total' => 'balance',
        'mining_balance' => 'mining',
        default => 'balance'
    };
    }
}


if (!function_exists('send_app_mail')) {
    function send_app_mail(
        string $to,
        string $slug,
        array $data = [],
        string $subject = null
    ) {
        $subject = $subject ?? config('app.name');

        Mail::to($to)->send(
            new AppMailer($slug, $data, $subject)
        );
    }
}
 