using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes;

namespace StellaOps.Feedser.Storage.Mongo.Exporting;

[BsonIgnoreExtraElements]
public sealed class ExportStateDocument
{
    [BsonId]
    public string Id { get; set; } = string.Empty;

    [BsonElement("baseExportId")]
    public string? BaseExportId { get; set; }

    [BsonElement("baseDigest")]
    public string? BaseDigest { get; set; }

    [BsonElement("lastFullDigest")]
    public string? LastFullDigest { get; set; }

    [BsonElement("lastDeltaDigest")]
    public string? LastDeltaDigest { get; set; }

    [BsonElement("exportCursor")]
    public string? ExportCursor { get; set; }

    [BsonElement("targetRepo")]
    public string? TargetRepository { get; set; }

    [BsonElement("exporterVersion")]
    public string? ExporterVersion { get; set; }

    [BsonElement("updatedAt")]
    public DateTime UpdatedAt { get; set; }

    [BsonElement("files")]
    public List<ExportStateFileDocument>? Files { get; set; }
}

public sealed class ExportStateFileDocument
{
    [BsonElement("path")]
    public string Path { get; set; } = string.Empty;

    [BsonElement("length")]
    public long Length { get; set; }

    [BsonElement("digest")]
    public string Digest { get; set; } = string.Empty;
}

internal static class ExportStateDocumentExtensions
{
    public static ExportStateDocument FromRecord(ExportStateRecord record)
        => new()
        {
            Id = record.Id,
            BaseExportId = record.BaseExportId,
            BaseDigest = record.BaseDigest,
            LastFullDigest = record.LastFullDigest,
            LastDeltaDigest = record.LastDeltaDigest,
            ExportCursor = record.ExportCursor,
            TargetRepository = record.TargetRepository,
            ExporterVersion = record.ExporterVersion,
            UpdatedAt = record.UpdatedAt.UtcDateTime,
            Files = record.Files.Select(static file => new ExportStateFileDocument
            {
                Path = file.Path,
                Length = file.Length,
                Digest = file.Digest,
            }).ToList(),
        };

    public static ExportStateRecord ToRecord(this ExportStateDocument document)
        => new(
            document.Id,
            document.BaseExportId,
            document.BaseDigest,
            document.LastFullDigest,
            document.LastDeltaDigest,
            document.ExportCursor,
            document.TargetRepository,
            document.ExporterVersion,
            DateTime.SpecifyKind(document.UpdatedAt, DateTimeKind.Utc),
            (document.Files ?? new List<ExportStateFileDocument>())
                .Where(static entry => !string.IsNullOrWhiteSpace(entry.Path))
                .Select(static entry => new ExportFileRecord(entry.Path, entry.Length, entry.Digest))
                .ToArray());
}
