<?php

declare(strict_types=1);

namespace App\Services\Sitemaps\Builders;

use App\Services\Sitemaps\AbstractSitemapBuilder;
use App\Services\Sitemaps\SitemapUrl;
use App\Services\Sitemaps\SitemapUrlBuilder;
use DateTimeInterface;
use cPad\Plugins\News\Models\NewsArticle;
use cPad\Plugins\News\Models\NewsCategory;
use cPad\Plugins\News\Models\NewsTag;

final class NewsSitemapBuilder extends AbstractSitemapBuilder
{
    public function __construct(private readonly SitemapUrlBuilder $urls)
    {
    }

    public function name(): string
    {
        return 'news';
    }

    public function items(): array
    {
        $articles = NewsArticle::query()
            ->published()
            ->orderBy('id')
            ->cursor()
            ->map(fn (NewsArticle $article): ?SitemapUrl => $this->urls->news($article))
            ->filter()
            ->values();

        $categories = NewsCategory::query()
            ->active()
            ->whereHas('publishedArticles')
            ->ordered()
            ->cursor()
            ->map(fn (NewsCategory $category): ?SitemapUrl => $this->urls->newsCategory($category))
            ->filter()
            ->values();

        $tags = NewsTag::query()
            ->whereHas('articles', fn ($query) => $query->published())
            ->orderBy('name')
            ->cursor()
            ->map(fn (NewsTag $tag): ?SitemapUrl => $this->urls->newsTag($tag))
            ->filter()
            ->values();

        return $articles->concat($categories)->concat($tags)->values()->all();
    }

    public function lastModified(): ?DateTimeInterface
    {
        return $this->dateTime(\collect([
            NewsArticle::query()->published()->max('updated_at'),
            NewsCategory::query()->active()->whereHas('publishedArticles')->max('updated_at'),
            NewsTag::query()->whereHas('articles', fn ($query) => $query->published())->max('updated_at'),
        ])->filter()->max());
    }
}