<?php

declare(strict_types=1);

namespace App\Livewire\Blog;

use App\Models\BlogCategory;
use App\Models\BlogPost;
use App\Models\BlogTag;
use Livewire\Attributes\Computed;
use Livewire\Component;
use Livewire\WithPagination;

final class IndexPage extends Component
{
    use WithPagination;

    public string $search = '';

    public ?string $categorySlug = null;

    public ?string $tagSlug = null;

    public function mount(?string $categorySlug = null, ?string $tagSlug = null): void
    {
        $this->categorySlug = $categorySlug;
        $this->tagSlug = $tagSlug;

        if ($this->categorySlug !== null && $this->categorySlug !== '' && ! BlogCategory::query()->where('slug', $this->categorySlug)->exists()) {
            abort(404);
        }

        if ($this->tagSlug !== null && $this->tagSlug !== '' && ! BlogTag::query()->where('slug', $this->tagSlug)->exists()) {
            abort(404);
        }
    }

    public function updatingSearch(): void
    {
        $this->resetPage();
    }

    #[Computed]
    public function activeCategory(): ?BlogCategory
    {
        if ($this->categorySlug === null || $this->categorySlug === '') {
            return null;
        }

        return BlogCategory::query()->where('slug', $this->categorySlug)->first();
    }

    #[Computed]
    public function activeTag(): ?BlogTag
    {
        if ($this->tagSlug === null || $this->tagSlug === '') {
            return null;
        }

        return BlogTag::query()->where('slug', $this->tagSlug)->first();
    }

    #[Computed]
    public function posts()
    {
        return BlogPost::query()
            ->with(['author:id,name', 'category', 'tags'])
            ->published()
            ->when($this->search, function ($query): void {
                $query->where(function ($inner): void {
                    $inner->where('title', 'like', '%'.$this->search.'%')
                        ->orWhere('excerpt', 'like', '%'.$this->search.'%')
                        ->orWhere('content', 'like', '%'.$this->search.'%');
                });
            })
            ->when($this->activeCategory, fn ($q, BlogCategory $category) => $q->where('blog_category_id', $category->id))
            ->when($this->activeTag, fn ($q, BlogTag $tag) => $q->whereHas('tags', fn ($tq) => $tq->where('blog_tags.id', $tag->id)))
            ->orderByDesc('published_at')
            ->orderByDesc('id')
            ->paginate(9);
    }

    public function render()
    {
        $title = 'Blog';
        if ($this->activeCategory) {
            $title = $this->activeCategory->name;
        } elseif ($this->activeTag) {
            $title = 'Tag: '.$this->activeTag->name;
        }

        return view('livewire.blog.index-page', [
            'pageTitle' => $title,
        ])->layout('layouts.home', array_filter([
            'title' => $title,
            'seoDescription' => config('settings.seo_default_meta_description') ?: null,
            'seoCanonical' => url()->current(),
        ], fn ($v) => $v !== null && $v !== ''));
    }
}
