<?php

namespace App\Services\Settings;

use App\Contracts\SettingRepositoryContract;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

class SettingService
{
    public function __construct(
        private readonly SettingRepositoryContract $settings,
    ) {}

    public function all(): Collection
    {
        return Cache::remember(
            config('settings.cache_key'),
            config('settings.cache_ttl'),
            fn () => $this->settings->all()
        );
    }

    public function getByCategory(string $category): Collection
    {
        return $this->all()->where('category', $category)->values();
    }

    public function get(string $key, mixed $default = null): mixed
    {
        $setting = $this->all()->firstWhere('key', $key);

        if (! $setting) {
            return $default;
        }

        return $this->castValue($setting->value, $setting->type);
    }

    /**
     * @param  array<string, array{value: mixed, category?: string, type?: string}>  $settings
     */
    public function updateMany(array $settings): void
    {
        foreach ($settings as $key => $config) {
            $this->settings->set(
                $key,
                $config['value'] ?? '',
                $config['category'] ?? 'general',
                $config['type'] ?? 'string'
            );
        }

        $this->flushCache();
    }

    public function flushCache(): void
    {
        Cache::forget(config('settings.cache_key'));
    }

    private function castValue(?string $value, string $type): mixed
    {
        return match ($type) {
            'boolean' => filter_var($value, FILTER_VALIDATE_BOOLEAN),
            'integer' => (int) $value,
            'float' => (float) $value,
            'json' => json_decode($value ?? 'null', true),
            default => $value,
        };
    }
}
