<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

use App\Events\AnnouncementSaved;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

use App\Traits\HasContentElementsTrait;
use App\Traits\AppendAttributesTrait;
use App\Traits\VersioningTrait;
use App\Traits\SlugTrait;
use App\Traits\TagsTrait;
use App\Traits\HasPermissionsTrait;
use App\Traits\FindByTagsTrait;

use App\Models\Page;
use App\Models\Tag;
use App\Models\ContentElement;

use App\Contracts\SearchResultContract;
use App\Utilities\SearchResult;

class Announcement extends Model
{
    use HasFactory;
    use SoftDeletes;
    use AppendAttributesTrait;
    use HasContentElementsTrait;
    use VersioningTrait;
    use SlugTrait;
    use TagsTrait;
    use HasPermissionsTrait;
    use FindByTagsTrait;

    protected $hidden = [
        'contentElements',
        'signed_url',
        'preview_url',
    ];

    public $append_attributes = [
        'actions',
        'full_type',
        'full_slug',
        'resource',
        'type',
        'name',
        'published_at',
        'first_published_at',
        //'version',
        //'can_be_published',
    ];

    protected $casts = [
        'unlisted' => 'boolean',
    ];

    protected $appends = ['type'];

    public function saveAnnouncement(array $input, $id = null)
    {
        if ($id) {
            $announcement = Announcement::findOrFail($id);
        } else {
            $announcement = new Announcement();
        }

        $announcement->author = Arr::get($input, 'author');
        $announcement->save();

        $announcement->saveVersion($input);
        $announcement->saveContentElements($input);
        $announcement->saveTags($input);

        cache()->tags([cache_name($announcement)])->flush();

        broadcast(new AnnouncementSaved($announcement))->toOthers();

        return $announcement;
    }

    public function getFullSlugAttribute()
    {
        return 'announcements/'.$this->getSlug();
    }

    public function getNextAnnouncementAttribute()
    {
        if (!$this->published_at) {
            return null;
        }

        $version = Version::whereHasMorph('versionable', [Announcement::class])
            ->whereNotNull('published_at')
            ->where('published_at', '>', $this->published_at)
            ->orderBy('published_at')
            ->first();

        return $version ? $version->versionable : null;
    }

    public function getPreviousAnnouncementAttribute()
    {
        if (!$this->published_at) {
            return null;
        }

        $version = Version::whereHasMorph('versionable', [Announcement::class])
            ->whereNotNull('published_at')
            ->where('published_at', '<', $this->published_at)
            ->orderByDesc('published_at')
            ->first();

        return $version ? $version->versionable : null;
    }
}
