<?php

namespace App\Models;

use App\Events\NewArticleFetched;
use Database\Factories\ArticleFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Carbon;

/**
 * @method static firstOrCreate(array<string, mixed> $array)
 * @method static where(string $string, string $url)
 * @method static create(array<string, mixed> $array)
 *
 * @property int $id
 * @property int|null $feed_id
 * @property Feed $feed
 * @property string $url
 * @property string $title
 * @property string|null $description
 * @property string|null $content
 * @property Carbon|null $validated_at
 * @property Carbon $created_at
 * @property Carbon $updated_at
 * @property ArticlePublication|null $articlePublication
 */
class Article extends Model
{
    /** @use HasFactory<ArticleFactory> */
    use HasFactory;

    protected $fillable = [
        'feed_id',
        'url',
        'title',
        'description',
        'content',
        'image_url',
        'published_at',
        'author',
        'validated_at',
    ];

    /**
     * @return array<string, string>
     */
    public function casts(): array
    {
        return [
            'published_at' => 'datetime',
            'validated_at' => 'datetime',
            'created_at' => 'datetime',
            'updated_at' => 'datetime',
        ];
    }

    public function getIsPublishedAttribute(): bool
    {
        return $this->articlePublication()->exists();
    }

    /**
     * @return HasOne<ArticlePublication, $this>
     */
    public function articlePublication(): HasOne
    {
        return $this->hasOne(ArticlePublication::class);
    }

    /**
     * @return HasMany<ArticlePublication, $this>
     */
    public function articlePublications(): HasMany
    {
        return $this->hasMany(ArticlePublication::class);
    }

    /**
     * @return BelongsTo<Feed, $this>
     */
    public function feed(): BelongsTo
    {
        return $this->belongsTo(Feed::class);
    }

    /**
     * @return HasMany<RouteArticle, $this>
     */
    public function routeArticles(): HasMany
    {
        return $this->hasMany(RouteArticle::class);
    }

    public function dispatchFetchedEvent(): void
    {
        event(new NewArticleFetched($this));
    }
}
