using StellaOps.Feedser.Storage.Mongo.Documents;

namespace StellaOps.Feedser.Source.Vndr.Chromium.Internal;

internal sealed record ChromiumDocumentMetadata(
    string PostId,
    string Title,
    Uri DetailUrl,
    DateTimeOffset Published,
    DateTimeOffset? Updated,
    string? Summary)
{
    private const string PostIdKey = "postId";
    private const string TitleKey = "title";
    private const string PublishedKey = "published";
    private const string UpdatedKey = "updated";
    private const string SummaryKey = "summary";

    public static ChromiumDocumentMetadata FromDocument(DocumentRecord document)
    {
        ArgumentNullException.ThrowIfNull(document);

        var metadata = document.Metadata ?? throw new InvalidOperationException("Chromium document metadata missing.");

        if (!metadata.TryGetValue(PostIdKey, out var postId) || string.IsNullOrWhiteSpace(postId))
        {
            throw new InvalidOperationException("Chromium document metadata missing postId.");
        }

        if (!metadata.TryGetValue(TitleKey, out var title) || string.IsNullOrWhiteSpace(title))
        {
            throw new InvalidOperationException("Chromium document metadata missing title.");
        }

        if (!metadata.TryGetValue(PublishedKey, out var publishedString) || !DateTimeOffset.TryParse(publishedString, out var published))
        {
            throw new InvalidOperationException("Chromium document metadata missing published timestamp.");
        }

        DateTimeOffset? updated = null;
        if (metadata.TryGetValue(UpdatedKey, out var updatedString) && DateTimeOffset.TryParse(updatedString, out var updatedValue))
        {
            updated = updatedValue;
        }

        metadata.TryGetValue(SummaryKey, out var summary);

        return new ChromiumDocumentMetadata(
            postId.Trim(),
            title.Trim(),
            new Uri(document.Uri, UriKind.Absolute),
            published.ToUniversalTime(),
            updated?.ToUniversalTime(),
            string.IsNullOrWhiteSpace(summary) ? null : summary.Trim());
    }

    public static IReadOnlyDictionary<string, string> CreateMetadata(string postId, string title, DateTimeOffset published, DateTimeOffset? updated, string? summary)
    {
        var dictionary = new Dictionary<string, string>(StringComparer.Ordinal)
        {
            [PostIdKey] = postId,
            [TitleKey] = title,
            [PublishedKey] = published.ToUniversalTime().ToString("O"),
        };

        if (updated.HasValue)
        {
            dictionary[UpdatedKey] = updated.Value.ToUniversalTime().ToString("O");
        }

        if (!string.IsNullOrWhiteSpace(summary))
        {
            dictionary[SummaryKey] = summary.Trim();
        }

        return dictionary;
    }
}
