<?php

declare(strict_types=1);

final class MyronSitemapGenerator
{
    public function __construct(
        private readonly MyronContentRepository $repository,
    ) {
    }

    public function generate(): string
    {
        $lines = [
            '<?xml version="1.0" encoding="UTF-8"?>',
            '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
        ];

        foreach ($this->repository->findPublishedIndexablePages() as $page) {
            $lastmod = $this->formatLastmod((string) ($page['published_at'] ?? ''));
            $lines[] = '  <url>';
            $lines[] = '    <loc>' . $this->escape($this->absoluteUrl((string) ($page['path'] ?? '/'))) . '</loc>';
            if ($lastmod !== '') {
                $lines[] = '    <lastmod>' . $this->escape($lastmod) . '</lastmod>';
            }
            $lines[] = '    <changefreq>weekly</changefreq>';
            $lines[] = '    <priority>0.5</priority>';
            $lines[] = '  </url>';
        }

        $lines[] = '</urlset>';
        return implode("\n", $lines) . "\n";
    }

    private function absoluteUrl(string $path): string
    {
        return rtrim(myronAppUrl(), '/') . myronBuildPublicPageUrl($path);
    }

    private function formatLastmod(string $value): string
    {
        $trimmed = trim($value);
        if ($trimmed === '') {
            return '';
        }

        try {
            return (new DateTimeImmutable($trimmed))->format(DateTimeInterface::W3C);
        } catch (Throwable) {
            return '';
        }
    }

    private function escape(string $value): string
    {
        return htmlspecialchars($value, ENT_XML1 | ENT_QUOTES, 'UTF-8');
    }
}
