<?php

namespace App\Models\CMS\Media;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\EloquentSortable\SortableTrait;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\Translatable\HasTranslations;

class Story extends Model implements HasMedia
{
    use HasFactory;
    use HasTranslations;
    use InteractsWithMedia;
    use SortableTrait;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'id',
        'title',
        'expires_at',
        'sort_order',
        'is_visible',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'expires_at' => 'datetime',
        'is_visible' => 'boolean',
    ];

    /**
     * Translatable attributes.
     *
     * @var array<string>
     */
    public $translatable = ['title'];

    /**
     * Sortable attributes.
     *
     * @var array<string, mixed>
     */
    public $sortable = [
        'order_column_name' => 'sort_order',
        'sort_when_creating' => true,
    ];

    /**
     * The "booted" method of the model.
     */
    protected static function booted(): void
    {
        static::saving(function (Story $story) {
            if (blank($story->expires_at)) {
                $story->expires_at = now()->addDay();
            }
        });
    }

    /**
     * Media collections.
     */
    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('photo')
            ->singleFile();
    }

    /**
     * Media conversions.
     */
    public function registerMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('thumb200x200')
            ->fit(Manipulations::FIT_CONTAIN, 200, 200);

        $this->addMediaConversion('thumb720x1280')
            ->fit(Manipulations::FIT_CONTAIN, 720, 1280);
    }

    /**
     * Active stories are visible and not expired.
     */
    public function scopeActive(Builder $query): Builder
    {
        return $query
            ->where('is_visible', true)
            ->where('expires_at', '>', now());
    }

    /**
     * Story photo URL.
     */
    public function photo(?string $conversion = null): string
    {
        if ($conversion) {
            return $this->getFirstMediaUrl('photo', $conversion);
        }

        return $this->getFirstMediaUrl('photo');
    }
}
