using OF_DL.Models.Dtos.Common;
using OF_DL.Models.Dtos.Posts;
using OF_DL.Models.Entities.Posts;
using OF_DL.Models.Mappers;

namespace OF_DL.Tests.Models.Mappers;

public class PostMapperTests
{
    [Fact]
    public void PostFromDto_ReturnsDefaults_WhenDtoNull()
    {
        Post result = PostMapper.FromDto((PostDto?)null);

        Assert.False(result.HasMore);
        Assert.Null(result.TailMarker);
        Assert.Empty(result.List);
    }

    [Fact]
    public void FromDto_MapsListItems()
    {
        DateTime postedAt = new(2024, 5, 6, 7, 8, 9, DateTimeKind.Utc);

        PostDto dto = new()
        {
            HasMore = true,
            TailMarker = "tail",
            List =
            [
                new ListItemDto
                {
                    Id = 10,
                    PostedAt = postedAt,
                    Author = new AuthorDto { Id = 3 },
                    Text = "post",
                    RawText = "post",
                    IsOpened = true,
                    Price = "2.50",
                    IsArchived = true,
                    Media =
                    [
                        new MediumDto
                        {
                            Id = 20,
                            Type = "photo",
                            CanView = true,
                            Preview = "preview",
                            Files = new FilesDto
                            {
                                Full = new FullDto { Url = "https://example.com/full.jpg" },
                                Preview = new PreviewDto { Url = "https://example.com/preview.jpg" }
                            }
                        }
                    ]
                }
            ]
        };

        Post result = PostMapper.FromDto(dto);

        Assert.True(result.HasMore);
        Assert.Equal("tail", result.TailMarker);
        Assert.Single(result.List);

        ListItem item = result.List[0];
        Assert.Equal(10, item.Id);
        Assert.Equal(postedAt, item.PostedAt);
        Assert.NotNull(item.Author);
        Assert.Equal(3, item.Author.Id);
        Assert.Equal("post", item.Text);
        Assert.True(item.IsOpened);
        Assert.NotNull(item.Media);
        Assert.Single(item.Media);

        Medium media = item.Media[0];
        Assert.Equal(20, media.Id);
        Assert.Equal("photo", media.Type);
        Assert.NotNull(media.Files);
        Assert.NotNull(media.Files.Full);
        Assert.Equal("https://example.com/full.jpg", media.Files.Full.Url);
        Assert.NotNull(media.Files.Preview);
        Assert.Equal("https://example.com/preview.jpg", media.Files.Preview.Url);
    }

    [Fact]
    public void FromDto_MapsSinglePost()
    {
        DateTime postedAt = new(2024, 6, 7, 8, 9, 10, DateTimeKind.Utc);

        SinglePostDto dto = new()
        {
            Id = 77,
            PostedAt = postedAt,
            Author = new AuthorDto { Id = 8 },
            Text = "single",
            RawText = "single",
            IsOpened = true,
            Price = "4.00",
            IsArchived = false,
            Preview = ["preview"],
            Media =
            [
                new MediumDto
                {
                    Id = 88,
                    Type = "video",
                    CanView = true,
                    Preview = "preview",
                    Files = new FilesDto { Full = new FullDto { Url = "https://example.com/full.mp4" } },
                    VideoSources = new VideoSourcesDto { _240 = "240.mp4", _720 = "720.mp4" }
                }
            ]
        };

        SinglePost result = PostMapper.FromDto(dto);

        Assert.Equal(77, result.Id);
        Assert.Equal(postedAt, result.PostedAt);
        Assert.NotNull(result.Author);
        Assert.Equal(8, result.Author.Id);
        Assert.Equal("single", result.Text);
        Assert.True(result.IsOpened);
        Assert.NotNull(result.Media);
        Assert.Single(result.Media);

        Medium media = result.Media[0];
        Assert.Equal(88, media.Id);
        Assert.NotNull(media.Files);
        Assert.NotNull(media.Files.Full);
        Assert.Equal("https://example.com/full.mp4", media.Files.Full.Url);
        Assert.NotNull(media.VideoSources);
        Assert.Equal("240.mp4", media.VideoSources._240);
        Assert.Equal("720.mp4", media.VideoSources._720);
    }
}
