<?php

namespace AleshaCMS\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Post extends Model implements HasMedia
{
    use SoftDeletes, InteractsWithMedia;

    protected $fillable = [
        'user_id', 'content_type', 'title', 'slug', 'content',
        'excerpt', 'custom_fields', 'seo', 'status', 'published_at',
        'parent_id', 'sort_order', 'page_builder', 'builder_fullpage',
    ];

    protected $casts = [
        'custom_fields' => 'array',
        'seo' => 'array',
        'page_builder' => 'array',
        'published_at' => 'datetime',
        'builder_fullpage' => 'boolean',
    ];

    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function parent(): BelongsTo
    {
        return $this->belongsTo(Post::class, 'parent_id');
    }

    public function children(): HasMany
    {
        return $this->hasMany(Post::class, 'parent_id');
    }

    public function meta(): HasMany
    {
        return $this->hasMany(PostMeta::class);
    }

    public function taxonomies(): BelongsToMany
    {
        return $this->belongsToMany(\AleshaCMS\Models\CMS\Taxonomy::class, 'post_taxonomy');
    }

    public function scopePublished($query)
    {
        return $query->where('status', 'published')
            ->where(function ($q) {
                $q->whereNull('published_at')->orWhere('published_at', '<=', now());
            });
    }

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

    public function getMeta(string $key, mixed $default = null): mixed
    {
        $meta = $this->meta->firstWhere('key', $key);
        return $meta ? $meta->value : $default;
    }

    public function setMeta(string $key, mixed $value): void
    {
        $this->meta()->updateOrCreate(['key' => $key], ['value' => $value]);
    }

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('featured')->singleFile();
        $this->addMediaCollection('gallery');
    }
}
