<?php

declare(strict_types=1);

final class MyronMarkdownFrontMatterBuilder
{
    /**
     * @param array<string, mixed> $page
     */
    public function build(array $page): string
    {
        $resolved = myronSeoFieldResolver()->resolveAll($page);
        $fields = [
            'title' => $this->firstNonEmpty([$page['version_title'] ?? '', $page['title'] ?? '']),
            'seo_title' => $resolved['seo_title']['value'] ?? '',
            'meta_description' => $resolved['meta_description']['value'] ?? '',
            'canonical' => $resolved['canonical']['value'] ?? '',
            'og_title' => $resolved['og_title']['value'] ?? '',
            'og_description' => $resolved['og_description']['value'] ?? '',
            'og_image' => $resolved['og_image']['value'] ?? '',
            'twitter_title' => $resolved['twitter_title']['value'] ?? '',
            'twitter_description' => $resolved['twitter_description']['value'] ?? '',
            'robots' => $resolved['robots']['value'] ?? '',
            'published_at' => $this->firstNonEmpty([$page['published_at'] ?? '', myronNow()]),
            'bundle' => $this->firstNonEmpty([$page['source_bundle_id'] ?? '', $page['template_source_bundle_id'] ?? '']),
            'template' => $this->firstNonEmpty([$page['source_template_id'] ?? '', $page['template_source_template_id'] ?? '']),
        ];

        $lines = ['---'];
        foreach ($fields as $key => $value) {
            $value = trim((string) $value);
            if ($value === '' && !in_array($key, ['title', 'published_at'], true)) {
                continue;
            }
            $lines[] = $key . ': ' . $this->yamlScalar($value);
        }
        $lines[] = '---';

        return implode("\n", $lines) . "\n";
    }

    private function yamlScalar(string $value): string
    {
        $escaped = str_replace(['\\', '"', "\n", "\r"], ['\\\\', '\"', '\n', ''], $value);
        return '"' . $escaped . '"';
    }

    /**
     * @param list<mixed> $candidates
     */
    private function firstNonEmpty(array $candidates): string
    {
        foreach ($candidates as $candidate) {
            $value = trim((string) $candidate);
            if ($value !== '') {
                return $value;
            }
        }
        return '';
    }
}
