<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;

class Setting extends Model
{
    use HasFactory;

    protected $fillable = [
        'key',
        'value',
        'type',
        'is_encrypted',
    ];

    protected $casts = [
        'is_encrypted' => 'boolean',
    ];

    /**
     * Get a setting value by key
     */
    public static function get(string $key, $default = null)
    {
        $setting = static::where('key', $key)->first();

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

        return $setting->getValue();
    }

    /**
     * Set a setting value
     */
    public static function set(string $key, $value, string $type = 'string', bool $encrypt = false)
    {
        $formattedValue = $value;

        if ($type === 'json' && is_array($value)) {
            $formattedValue = json_encode($value);
        } elseif ($type === 'boolean') {
            $formattedValue = $value ? '1' : '0';
        }

        if ($encrypt) {
            $formattedValue = Crypt::encryptString($formattedValue);
        }

        return static::updateOrCreate(
            ['key' => $key],
            [
                'value' => $formattedValue,
                'type' => $type,
                'is_encrypted' => $encrypt,
            ]
        );
    }

    /**
     * Get the decoded/decrypted value
     */
    public function getValue()
    {
        $value = $this->value;

        // Decrypt if necessary
        if ($this->is_encrypted) {
            $value = Crypt::decryptString($value);
        }

        // Parse based on type
        return match ($this->type) {
            'json' => json_decode($value, true),
            'boolean' => filter_var($value, FILTER_VALIDATE_BOOLEAN),
            'integer' => (int) $value,
            default => $value,
        };
    }

    /**
     * Set the value with automatic encryption
     */
    public function setValue($value)
    {
        $formattedValue = $value;

        if ($this->type === 'json' && is_array($value)) {
            $formattedValue = json_encode($value);
        } elseif ($this->type === 'boolean') {
            $formattedValue = $value ? '1' : '0';
        }

        if ($this->is_encrypted) {
            $formattedValue = Crypt::encryptString($formattedValue);
        }

        $this->value = $formattedValue;
    }
}
