<?php

namespace App\Models;

use App\Enums\MethodType;
use App\Services\CurrencyConversionService;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;

class DepositMethod extends Model
{
    use HasFactory;

    protected $fillable = [
        'payment_gateway_id',
        'logo',
        'name',
        'type',
        'method_code',
        'currency',
        'currency_symbol',
        'min_deposit',
        'max_deposit',
        'rate_type',
        'conversion_rate_live',
        'conversion_rate',
        'charge_type',
        'charge',
        'fields',
        'receive_payment_details',
        'status',
    ];

    protected $casts = [
        'type'                 => MethodType::class,
        'payment_gateway_id'   => 'integer',
        'fields'               => 'array',
        'status'               => 'boolean',
        'min_limit'            => 'float',
        'max_limit'            => 'float',
        'conversion_rate_live' => 'boolean',
        'conversion_rate'      => 'float',
        'charge'               => 'float',
    ];

    public function paymentGateway()
    {
        return $this->belongsTo(PaymentGateway::class, 'payment_gateway_id');
    }

    public function scopeActive($query)
    {
        return $query->where('status', true);
    }

    public function scopeGetByCode($query, $code)
    {
        return $query->where('method_code', $code)->first();
    }

    public static function getByCode($code)
    {
        return Cache::rememberForever('deposit_method_'.$code, function () use ($code) {
            return self::where('method_code', $code)->first();
        });
    }

    public function getLogoAltAttribute(): string
    {
        if ($this->attributes['type'] !== MethodType::AUTOMATIC->value) {
            return $this->attributes['logo'] ?? '';
        }

        return $this->attributes['logo'] ?? $this->paymentGateway->logo;
    }

    /**
     * Get the conversion rate of the deposit method.
     *
     * This method will return the conversion rate of the deposit method. If the conversion rate is set to live, it will use the currency conversion service to convert the currency from the site's currency to the deposit method's currency. If the conversion rate is not set to live, it will return the fixed conversion rate.
     */
    public function getConversionRateAttribute(): string
    {
        // Check if the conversion rate is set to live.
        if ($this->attributes['conversion_rate_live'] && $this->attributes['type'] === 'auto') {
            // Get an instance of the currency conversion service.
            $currencyConversionService = new CurrencyConversionService;

            // Convert the currency from the site's currency to the deposit method's currency.
            // The conversion rate is returned as a string with two decimal places.
            return number_format($currencyConversionService->convertCurrency(1, siteCurrency(), $this->attributes['currency']), 2, '.', '');
        }

        return $this->attributes['conversion_rate'];
    }

    /**
     * The "booted" method of the model.
     */
    protected static function boot(): void
    {
        parent::boot();

        // Flush the cache when a deposit method is deleted.
        static::deleted(function ($model) {
            Cache::forget('deposit_method_'.$model->code);
        });

        // Flush the cache when a deposit method is updated.
        static::updated(function ($model) {
            Cache::forget('deposit_method_'.$model->code);
        });

        // Flush the cache when a deposit method is created.
        static::created(function ($model) {
            Cache::forget('deposit_method_'.$model->code);
        });
    }
}
