<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Content extends Model
{
    public const TYPE_BLOG = 'blog';

    public const TYPE_GUIDE = 'guide';

    public const TYPE_NEWS = 'news';

    protected $fillable = [
        'type',
        'title',
        'slug',
        'excerpt',
        'body',
        'meta_title',
        'meta_description',
        'tag',
        'cta_label',
        'cta_url',
        'is_published',
        'sort_order',
        'published_at',
    ];

    protected function casts(): array
    {
        return [
            'is_published' => 'boolean',
            'published_at' => 'datetime',
        ];
    }

    public function getRouteKeyName(): string
    {
        return 'slug';
    }

    protected static function booted(): void
    {
        static::saving(function (Content $content): void {
            $slug = $content->slug === null ? '' : trim((string) $content->slug);
            if ($slug === '' && $content->title !== null && $content->title !== '') {
                $slug = Str::slug($content->title) ?: 'contenu';
            }
            if ($slug !== '') {
                $base = $slug;
                $unique = $base;
                $n = 0;
                $query = static::query()->where('slug', $unique);
                if ($content->exists) {
                    $query->where('id', '!=', $content->id);
                }
                while ($query->exists()) {
                    $unique = $base . '-' . (++$n);
                    $query = static::query()->where('slug', $unique);
                    if ($content->exists) {
                        $query->where('id', '!=', $content->id);
                    }
                }
                $content->slug = $unique;
            }
        });
    }

    public function scopePublished(Builder $query): Builder
    {
        return $query->where('is_published', true)
            ->where(function (Builder $q): void {
                $q->whereNull('published_at')
                    ->orWhere('published_at', '<=', now());
            });
    }

    public function scopeOfType(Builder $query, string $type): Builder
    {
        return $query->where('type', $type);
    }

    public function scopeOrdered(Builder $query): Builder
    {
        return $query->orderBy('sort_order')->orderByDesc('published_at')->orderByDesc('id');
    }

    public static function types(): array
    {
        return [
            self::TYPE_BLOG => 'Blog',
            self::TYPE_GUIDE => 'Guide',
            self::TYPE_NEWS => 'Actualite',
        ];
    }

    public function isPubliclyVisible(): bool
    {
        if (! $this->is_published) {
            return false;
        }

        if ($this->published_at !== null && $this->published_at->isFuture()) {
            return false;
        }

        return true;
    }
}
