<?php

declare(strict_types=1);

namespace App\Services\Sitemaps;

use DateTimeInterface;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;

abstract class AbstractSitemapBuilder implements SitemapBuilder
{
    protected function contentTypeSlugs(): array
    {
        return array_values((array) config('sitemaps.content_type_slugs', []));
    }

    protected function newest(mixed ...$timestamps): ?DateTimeInterface
    {
        $filtered = array_values(array_filter(array_map(fn (mixed $value): ?Carbon => $this->dateTime($value), $timestamps)));

        if ($filtered === []) {
            return null;
        }

        usort($filtered, static fn (DateTimeInterface $left, DateTimeInterface $right): int => $left < $right ? 1 : -1);

        return $filtered[0];
    }

    protected function dateTime(mixed $value): ?Carbon
    {
        if ($value instanceof Carbon) {
            return $value;
        }

        if ($value instanceof DateTimeInterface) {
            return Carbon::instance($value);
        }

        if (is_string($value) && trim($value) !== '') {
            return Carbon::parse($value);
        }

        return null;
    }

    protected function absoluteUrl(?string $url): ?string
    {
        $value = trim((string) $url);

        if ($value === '') {
            return null;
        }

        if (Str::startsWith($value, ['http://', 'https://'])) {
            return $value;
        }

        return url($value);
    }

    protected function image(?string $url, ?string $title = null): ?SitemapImage
    {
        $absolute = $this->absoluteUrl($url);

        if ($absolute === null) {
            return null;
        }

        return new SitemapImage($absolute, $title !== '' ? $title : null);
    }

    /**
     * @param  array<int, SitemapImage|null>  $images
     * @return list<SitemapImage>
     */
    protected function images(array $images): array
    {
        return array_values(array_filter($images, static fn (mixed $image): bool => $image instanceof SitemapImage));
    }
}