<?php

namespace App\Helpers\Formats;


class FormatCurrencyHelper
{
    /**
     * Toma un valor numérico (dado en cualquier presentación), y lo adecua a una
     * presentación financiera acorde a la configuración monetaria del sistema.
     *
     *  @param mixed $amount Cantidad numérica a formatear (12.0000, 24, "12.000", "24", "2,200.00", "-2,200.00", -12.00, -0.4)
     *  @param ?bool $useSymbol ¿Se desea presentar el valor con el símbolo de su divisa?''
     *  @param ?int  $decimals Cantidad de decimales a utilizar en el resultado final
     *
     *  @return string
     *  Ejemplos:
     *  - $useSymbol (true) = $0.00 | 0.00$
     *  - $useSymbol (false) = 0.00 MXN($)
     */
    public static function formatCurrency($amount, ?string $currency = null, $useSymbol = true, $decimals= 2)
    {
        // Dynamic Currency Symbol
            $currencies = config('constants.banxico_currencies'); // Supported banxico currencies

            if($currency && isset($currencies[ strtoupper($currency) ]) ){ //If banxico support currency
                $currency_data = $currencies[strtoupper($currency)]; // Extract data

                $symbol = $currency_data['symbol'];
                $code = strtoupper($currency);
                $position = 'before';
            } else { // Fallback: Use session currency configured
                $symbol   = session('currency.symbol', '$');
                $position = session('currency.position', 'before');
                $code     = session('currency.code', 'MXN');
            }

        // Normalizar el valor recibido
          // Quitar comillas y espacios
            $raw = is_null($amount) ? '0' : (string)$amount;
            $raw = trim($raw, " \t\n\r\0\x0B\"'");

          // Conservar solo dígitos, punto, coma y guion
            $clean_amount = preg_replace('/[^0-9,\.\-]/', '', $raw);

          // Detectar signo
            $is_negative = false;
            if (strpos($clean_amount, '-') !== false) {
                $is_negative = true;
                $clean_amount = str_replace('-', '', $clean_amount);
            }

          // Limpiar separadores
            if (strpos($clean_amount, '.') !== false && strpos($clean_amount, ',') !== false) {
                $clean_amount = str_replace(',', '', $clean_amount);
            } elseif (strpos($clean_amount, ',') !== false) {
                $clean_amount = str_replace(',', '.', $clean_amount);
            }

          // Convertir a valor numérico
            $numeric_amount = is_numeric($clean_amount) ? (float)$clean_amount : 0.0;
                if ($is_negative) $numeric_amount = -abs($numeric_amount);

        // Formatear valor absoluto (miles y 2 decimales)
        $abs_amount = number_format(abs($numeric_amount), $decimals, '.', ',');

        // Remover decimales innecesarios
        $abs_amount = QuantityConverterHelper::removeUnnecessaryDecimal($abs_amount);

        // Si se usa el símbolo
        if ($useSymbol) {
            $formatted_amount = ($position === 'before')
                ? ($symbol . $abs_amount)
                : ($abs_amount . ' ' . $symbol);
        } else {
            $formatted_amount = $abs_amount . ' ' . $code . ' (' . $symbol . ')';
        }

        // Si no, se uda el código de la moneda
        return $numeric_amount < 0 ? ('-' . $formatted_amount) : $formatted_amount;
    }

    /**
     * Función destinada unicamente a representar el valor inicial de algún campo o calculo monetario,
     * dependiendo de la configuración del sistema
     *
     * @return string Ejemplo: $0.00 | 0.00$
    */
    public static function currencyPlaceHolder() :string {
        $symbol = session('currency.symbol', '$'); // Símbolo de la moneda
        $position = session('currency.position', 'before'); // Posición del símbolo

        return $position == 'before' ? $symbol . ' 0.00' : '0.00 ' . $symbol;
    }

    /**
     * Función de soporte diseñada específicamente para convertir cantidades monetarias extranjeras, a su
     * equivalencia en pesos mexicanos
     *
     * @param mixed $amount         Cantidad monetaria a convertir a pesos mexicanos
     * @param mixed $exchange_rate  Equivalencia en pesos, de la moneda con la cual se presenta la cantidad a convertir
    */
    public static function convertDivisaToPesos(mixed $amount, mixed $exchange_rate){
        $amount= (float) $amount;
        $exchange_rate= ($exchange_rate);

        if(empty($exchange_rate) || $exchange_rate == 0){
            $exchange_amount = $amount;
        }else{
            $exchange_amount = $amount*$exchange_rate;
        }

        // Return amount as Mexican Pesos
        return self::formatCurrency($exchange_amount, true, 2);
    }

}
