<?php

namespace App\Components\Tag;

use App\Interface\HistoryOwner;
use App\Models\Claim\Claim;
use App\Models\Tag;
use App\Services\HistoryService;
use Illuminate\Database\Eloquent\Model;
use Livewire\Component;

class TagAssigner extends Component {
    public Model $model;
    public $search = '';

    public function mount(Model $model) {
        $this->model = $model;
        $this->model->load('tags');
    }

    public function getAvailableTagsProperty()
    {
        return Tag::whereNotIn('id', $this->model->tags->pluck('id'))
            ->when($this->search, fn($q) => $q->where('name', 'like', '%' . $this->search . '%'))
            ->orderBy('name')
            ->get();
    }

    public function assignTag(HistoryService $history, $tagId) {
        $tag = Tag::findOrFail($tagId);

        $this->model->tags()->syncWithoutDetaching([$tagId]);
        $this->model->load('tags');
        $this->search = '';

        $this->recordTagChange($history, "Tag added: {$tag->name}", $tag);
    }

    public function removeTag(HistoryService $history, $tagId) {
        $tag = Tag::findOrFail($tagId);

        $this->model->tags()->detach($tagId);
        $this->model->load('tags');

        $this->recordTagChange($history, "Tag removed: {$tag->name}", $tag);
    }

    private function recordTagChange(HistoryService $history, string $event, Tag $tag): void
    {
        $context = ['tag_id' => $tag->id, 'tag_name' => $tag->name];

        if ($this->model instanceof Claim) {
            $history->addForClaim($this->model, $event, $context);
        } elseif ($this->model instanceof HistoryOwner) {
            $history->add($this->model, $event, $context);
        }
    }

    public function render() {
        return view('components.tag.tag-assigner', [
            'availableTags' => $this->availableTags,
        ]);
    }
}