<?php

namespace App\Support;

use App\Mixins\Financial\MultiCurrency;

class PaymentCurrency
{
    public const EGP = 'EGP';
    public const USD = 'USD';

    public static function allowed(): array
    {
        return [self::EGP, self::USD];
    }

    public static function defaultItemCurrency(): string
    {
        $configured = config('payment.default_item_currency', self::USD);

        return self::normalize($configured, self::USD);
    }

    public static function normalize(?string $currency, ?string $default = null): string
    {
        if ($default === null) {
            $default = self::defaultItemCurrency();
        }

        $currency = strtoupper(trim((string) $currency));

        return in_array($currency, self::allowed(), true) ? $currency : $default;
    }

    /**
     * Effective currency for a priced item (webinar, product, …).
     */
    public static function resolveForModel($model, ?string $fallback = null): string
    {
        if ($fallback === null) {
            $fallback = self::defaultItemCurrency();
        }

        if (empty($model)) {
            return self::normalize($fallback);
        }

        $table = method_exists($model, 'getTable') ? $model->getTable() : null;

        if (
            $table
            && \Illuminate\Support\Facades\Schema::hasColumn($table, 'currency')
            && !empty($model->currency)
        ) {
            $stored = self::normalize($model->currency, $fallback);

            if (
                $stored === self::EGP
                && config('payment.treat_legacy_egp_as_usd', false)
                && self::defaultItemCurrency() === self::USD
            ) {
                return self::USD;
            }

            return $stored;
        }

        return self::normalize($fallback);
    }

    public static function labels(): array
    {
        return [
            self::EGP => 'جنيه مصري (EGP)',
            self::USD => 'دولار أمريكي (USD)',
        ];
    }

    public static function sign(string $currency): string
    {
        switch (self::normalize($currency)) {
            case self::USD:
                return '$';
            case self::EGP:
                return 'ج.م';
            default:
                return $currency;
        }
    }

    /**
     * USD → EGP rate (1 USD = X EGP). Used when charging via EasyKash.
     */
    public static function usdToEgpRate(): float
    {
        $configured = config('services.easykash.usd_to_egp_rate') ?: config('payment.usd_to_egp_rate');
        if (is_numeric($configured) && (float) $configured > 0) {
            return (float) $configured;
        }

        try {
            $egp = (new MultiCurrency())->getSpecificCurrency(self::EGP);
            if ($egp && !empty($egp->exchange_rate) && (float) $egp->exchange_rate > 0) {
                return (float) $egp->exchange_rate;
            }
        } catch (\Throwable $e) {
            // ignore
        }

        return 48.0;
    }

    /**
     * Amount and currency for EasyKash (gateway only accepts EGP; USD orders are converted).
     *
     * @return array{amount: float, currency: string, original_amount: ?float, original_currency: ?string, usd_to_egp_rate: ?float}
     */
    public static function forEasyKashGateway(float $amount, ?string $orderCurrency): array
    {
        $orderCurrency = self::normalize($orderCurrency);
        $amount = round($amount, 2);

        if ($orderCurrency === self::USD) {
            $rate = self::usdToEgpRate();

            return [
                'amount' => round($amount * $rate, 2),
                'currency' => self::EGP,
                'original_amount' => $amount,
                'original_currency' => self::USD,
                'usd_to_egp_rate' => $rate,
            ];
        }

        return [
            'amount' => $amount,
            'currency' => self::EGP,
            'original_amount' => null,
            'original_currency' => null,
            'usd_to_egp_rate' => null,
        ];
    }
}
