<?php

namespace App\Models;

use App\Contracts\Model;
use App\Observers\SettingObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Attributes\WithoutIncrementing;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Carbon;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Models\Activity;
use Spatie\Activitylog\Traits\LogsActivity;

/**
 * @property string      $id
 * @property int         $offset
 * @property int         $order
 * @property string      $key
 * @property string      $name
 * @property string      $value
 * @property string|null $default
 * @property string|null $group
 * @property string|null $type
 * @property string|null $options
 * @property string|null $description
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @property-read Collection<int, Activity> $activities
 * @property-read int|null $activities_count
 *
 * @method static Builder<static>|Setting byKey(string $key)
 * @method static Builder<static>|Setting newModelQuery()
 * @method static Builder<static>|Setting newQuery()
 * @method static Builder<static>|Setting query()
 * @method static Builder<static>|Setting whereCreatedAt($value)
 * @method static Builder<static>|Setting whereDefault($value)
 * @method static Builder<static>|Setting whereDescription($value)
 * @method static Builder<static>|Setting whereGroup($value)
 * @method static Builder<static>|Setting whereId($value)
 * @method static Builder<static>|Setting whereKey($value)
 * @method static Builder<static>|Setting whereName($value)
 * @method static Builder<static>|Setting whereOffset($value)
 * @method static Builder<static>|Setting whereOptions($value)
 * @method static Builder<static>|Setting whereOrder($value)
 * @method static Builder<static>|Setting whereType($value)
 * @method static Builder<static>|Setting whereUpdatedAt($value)
 * @method static Builder<static>|Setting whereValue($value)
 *
 * @mixin \Eloquent
 */
#[ObservedBy(SettingObserver::class)]
#[WithoutIncrementing]
class Setting extends Model
{
    use LogsActivity;

    public $table = 'settings';

    protected $keyType = 'string';

    protected $fillable = [
        'name',
        'key',
        'value',
        'group',
        'type',
        'options',
        'description',
    ];

    public static function formatKey($key): string
    {
        return str_replace('.', '_', strtolower((string) $key));
    }

    /**
     * Force formatting the key
     */
    public function id(): Attribute
    {
        return Attribute::make(
            get: fn ($id, $attrs): string => self::formatKey(strtolower((string) $id))
        );
    }

    /**
     * Set the key to lowercase
     */
    public function key(): Attribute
    {
        return Attribute::make(
            set: fn ($key) => strtolower((string) $key)
        );
    }

    /**
     * Filter by setting key, applying the same `formatKey` normalization
     * that the id() accessor applies. Equivalent to find($formattedKey).
     */
    #[Scope]
    protected function byKey(Builder $q, string $key): Builder
    {
        return $q->where('id', self::formatKey($key));
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly($this->fillable)
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }
}
