<?php

namespace Yajny\Traits;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Yajny\Member\Models\Currencies;

trait HasCurrency
{
    public function applyCurrencyConversion(Currencies $currency = null, $disablePrecision = false)
    {
        $currencyConversionFields = $this->currencyConversionFields ?? [];
        $currencyFormatFields = $this->currencyFormatFields ?? [];
        $currencyFieldName = $this->currencyFieldName ?? 'currency';
        foreach ($currencyConversionFields as $currencyField) {
            $this->{$currencyField} *= $currency->conversion_rate;
            $this->{"{$currencyField}_formatted"} = $this->currencyValueFormatted($this->{$currencyField}, $currency, $currencyField, $disablePrecision);
        }
        if ($currencyFormatFields && (!isset($currency) || (isset($this->{$currencyFieldName}) && $this->{$currencyFieldName} != $currency->code))) {
            $allCurrencies = Cache::rememberForever('currencies', function () {
                return Currencies::all()->mapWithKeys(function ($currency) {
                    return [$currency->iso_code => $currency];
                });
            });
            $currency = $allCurrencies[$this->{$currencyFieldName}] ?? $currency;
            if (!isset($currency)) {
                Log::error('unexpected behavior', ['model' => $this->toArray(), 'request' => request()->all()]);
                $currency = $allCurrencies['USD'];
            }
        }
        foreach ($currencyFormatFields as $currencyField) {
            $this->{"{$currencyField}_formatted"} = $this->currencyValueFormatted($this->{$currencyField}, $currency, $currencyField, $disablePrecision);
        }
    }

    private function currencyValueFormatted($value, $currency, $field = null, $disablePrecision = false): string
    {
        $precisionFields = $this->precisions ?? [];
        if ($field && $precisionFields && isset($precisionFields[$field])) {
            $precisionDirection = $precisionFields[$field];
            $value = $precisionDirection($value);
        } else {
            $value = round($value, ($disablePrecision) ? 0 : 2);
        }

        $formattedValue = "{$value} {$currency->symbol}";
        if ($currency->display_as == 'prefix')
            $formattedValue = "{$currency->symbol} {$value}";
        return $formattedValue;
    }

    private function userCurrencyFormat($amount): string
    {
        $allCurrencies = Cache::rememberForever('currencies', function () {
            return Currencies::all()->mapWithKeys(function ($currency) {
                return [$currency->iso_code => $currency];
            });
        });
        $currency = $allCurrencies['USD'];
        $userCurrency = request('userCurrency');
        if ($userCurrency)
            $currency = $allCurrencies[$userCurrency];
        return $this->currencyValueFormatted($amount * $currency->conversion_rate, $currency);
    }
}
