<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Str;

class ApiSetting extends Model
{
    public const PROVIDER_FMP = 'financial_modeling_prep';
    public const PROVIDER_METAAPI = 'metaapi';

    protected $fillable = [
        'provider_name',
        'key_name',
        'api_key',
        'status',
    ];

    protected $hidden = [
        'api_key',
    ];

    public static function providers(): array
    {
        return [
            self::PROVIDER_FMP => 'Financial Modeling Prep',
            self::PROVIDER_METAAPI => 'MetaApi',
        ];
    }

    public static function keyNames(): array
    {
        return [
            self::PROVIDER_FMP => 'FMP_API_KEY',
            self::PROVIDER_METAAPI => 'METAAPI_TOKEN',
        ];
    }

    public function setApiKeyAttribute(?string $value): void
    {
        if (filled($value)) {
            $this->attributes['api_key'] = encrypt($value);
        }
    }

    public function decryptedApiKey(): ?string
    {
        if (! filled($this->attributes['api_key'] ?? null)) {
            return null;
        }

        try {
            return decrypt($this->attributes['api_key']);
        } catch (\Throwable) {
            return null;
        }
    }

    public function maskedApiKey(): string
    {
        $key = $this->decryptedApiKey();

        if (! filled($key)) {
            return 'Not available';
        }

        $visible = Str::substr($key, -4);

        return str_repeat('*', max(12, strlen($key) - 4)).$visible;
    }

    public function providerLabel(): string
    {
        return self::providers()[$this->provider_name] ?? Str::title(str_replace('_', ' ', $this->provider_name));
    }

    public function isActive(): bool
    {
        return $this->status === 'active';
    }

    public static function activeForProvider(string $provider): ?self
    {
        return self::query()
            ->where('provider_name', $provider)
            ->where('status', 'active')
            ->latest()
            ->first();
    }
}
