<?php

namespace App;

use App\Traits\CacheObject;
use Illuminate\Database\Eloquent\Model;
use Mtc\MercuryDataModels\Setting;

class SettingRepository
{
    use CacheObject;

    /**
     * List of loaded settings
     *
     * @var mixed[]
     */
    private $loaded_settings = [];

    /**
     * @param array $setting
     * @return Setting|Model
     */
    public function make(array $setting): Setting
    {
        /** @var Setting $entry */
        $entry = Setting::query()
            ->updateOrCreate([
                'config_key' => $setting['config_key'],
            ], [
                'tab' => $setting['tab'],
                'section' => $setting['section'],
                'group' => $setting['group'],
                'name' => $setting['name'],
                'type' => $setting['type'],
                'value' => $setting['value'] ?? null,
                'order' => $setting['order'] ?? 99,
                'choices' => $setting['choices'] ?? null,
                'description' => $setting['description'] ?? null,
                'min_tier' => $setting['min_tier'] ?? null,
                'validation_rules' => $setting['validation_rules'] ?? null,
            ]);

        if (!empty($this->loaded_settings)) {
            $this->loaded_settings[$entry->config_key] = $entry;
        }

        return $entry;
    }

    /**
     * Get a setting
     *
     * @param string $key
     * @return mixed
     */
    public function get(string $key, $default = null)
    {
        if (empty($this->loaded_settings) && tenant('id')) {
            $this->loaded_settings = $this->loadSettings();
        }

        return $this->loaded_settings[$key]?->value ?? $default;
    }

    public function getData(string $key): array
    {
        return Setting::query()
            ->where('config_key', $key)
            ->first()
            ?->data ?? [];
    }

    /**
     * Get a setting
     *
     * @param string $key
     * @return void
     */
    public function update(string $key, $value)
    {
        $setting = Setting::query()
            ->where('config_key', $key)
            ->firstOrFail();
        $setting->value = $value;
        $setting->update();

        $this->loaded_settings[$key] = $setting;
    }

    public function getOrder(string $key): int
    {
        if (!isset($this->loaded_settings[$key])) {
            $this->get($key);
        }
        return (int)$this->loaded_settings[$key]->order ?? 99;
    }

    private function loadSettings()
    {
        return $this->cache('settings', 60, fn () => Setting::query()
            ->get()
            ->keyBy('config_key'));
    }
}
