<?php

namespace Artemis\Faq\Traits;

use Artemis\Faq\Models\Tag;
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

/** @mixin Model */
trait Taggable
{
    public function tags(): MorphToMany
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
    
    public function attachTags($tags): void
    {
        $tags = $this->removeInvalidTags($this->normalizeTags($tags));
        
        $this->tags()->syncWithoutDetaching($tags);
    }
    
    public function detachTags($tags): void
    {
        $this->tags()->detach($this->normalizeTags($tags));
    }
    
    public function syncTags($tags): void
    {
        $this->tags()->sync($this->normalizeTags($tags));
    }
    
    public function hasTag($tag): bool
    {
        if (is_int($tag)) {
            return $this->tags->contains('id', $tag);
        }
        
        if (is_string($tag)) {
            return $this->tags->contains('name', $tag);
        }
        
        return $this->tags->contains('id', $tag->id);
    }
    
    protected function normalizeTags($tags): array
    {
        if ($tags instanceof Collection) {
            return $tags->pluck('id')->toArray();
        }
        
        if (is_array($tags)) {
            return array_map(fn($tag) => $tag instanceof Tag ? $tag->id : $tag, $tags);
        }
        
        return [(is_int($tags) ? $tags : $tags->id)];
    }
    
    protected function removeInvalidTags(array $tags): array
    {
        $validTagIds = Tag::pluck('id')->toArray();
        
        return array_intersect($validTagIds, $tags);
    }
}
