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

namespace OF_DL.Tests.Models.Mappers;

public class CommonMapperTests
{
    [Fact]
    public void MapAuthor_ReturnsNull_WhenDtoNull() => Assert.Null(CommonMapper.MapAuthor(null));

    [Fact]
    public void MapAuthor_ReturnsNull_WhenIdZero()
    {
        AuthorDto dto = new() { Id = 0 };

        Assert.Null(CommonMapper.MapAuthor(dto));
    }

    [Fact]
    public void MapAuthor_MapsId_WhenValid()
    {
        AuthorDto dto = new() { Id = 42 };

        Author? result = CommonMapper.MapAuthor(dto);

        Assert.NotNull(result);
        Assert.Equal(42, result.Id);
    }

    [Fact]
    public void MapFull_ReturnsNull_WhenUrlEmpty()
    {
        FullDto dto = new() { Url = "" };

        Assert.Null(CommonMapper.MapFull(dto));
    }

    [Fact]
    public void MapFull_MapsUrl_WhenPresent()
    {
        FullDto dto = new() { Url = "https://example.com/full.jpg" };

        Full? result = CommonMapper.MapFull(dto);

        Assert.NotNull(result);
        Assert.Equal(dto.Url, result.Url);
    }

    [Fact]
    public void MapPreview_ReturnsNull_WhenUrlEmpty()
    {
        PreviewDto dto = new() { Url = "" };

        Assert.Null(CommonMapper.MapPreview(dto));
    }

    [Fact]
    public void MapPreview_MapsUrl_WhenPresent()
    {
        PreviewDto dto = new() { Url = "https://example.com/preview.jpg" };

        Preview? result = CommonMapper.MapPreview(dto);

        Assert.NotNull(result);
        Assert.Equal(dto.Url, result.Url);
    }

    [Fact]
    public void MapManifest_ReturnsNull_WhenDashEmpty()
    {
        ManifestDto dto = new() { Dash = "" };

        Assert.Null(CommonMapper.MapManifest(dto));
    }

    [Fact]
    public void MapManifest_MapsDash_WhenPresent()
    {
        ManifestDto dto = new() { Dash = "dash.mpd" };

        Manifest? result = CommonMapper.MapManifest(dto);

        Assert.NotNull(result);
        Assert.Equal(dto.Dash, result.Dash);
    }

    [Fact]
    public void MapSignature_ReturnsNull_WhenDashEmpty()
    {
        SignatureDto dto = new() { Dash = new DashDto() };

        Assert.Null(CommonMapper.MapSignature(dto));
    }

    [Fact]
    public void MapSignature_MapsDash_WhenAnyDashFieldPresent()
    {
        SignatureDto dto = new() { Dash = new DashDto { CloudFrontPolicy = "policy" } };

        Signature? result = CommonMapper.MapSignature(dto);

        Assert.NotNull(result);
        Assert.NotNull(result.Dash);
        Assert.Equal("policy", result.Dash.CloudFrontPolicy);
    }

    [Fact]
    public void MapDrm_ReturnsNull_WhenDtoNull() => Assert.Null(CommonMapper.MapDrm(null));

    [Fact]
    public void MapDrm_MapsManifestAndSignature_WhenPresent()
    {
        DrmDto dto = new()
        {
            Manifest = new ManifestDto { Dash = "dash.mpd" },
            Signature = new SignatureDto { Dash = new DashDto { CloudFrontSignature = "signature" } }
        };

        Drm? result = CommonMapper.MapDrm(dto);

        Assert.NotNull(result);
        Assert.NotNull(result.Manifest);
        Assert.NotNull(result.Signature);
        Assert.Equal("dash.mpd", result.Manifest.Dash);
        Assert.Equal("signature", result.Signature.Dash?.CloudFrontSignature);
    }

    [Fact]
    public void MapFiles_ReturnsNull_WhenAllPartsNull()
    {
        FilesDto dto = new() { Full = { Url = "" }, Preview = { Url = "" }, Drm = null };

        Assert.Null(CommonMapper.MapFiles(dto));
    }

    [Fact]
    public void MapFiles_MapsParts_WhenPresent()
    {
        FilesDto dto = new()
        {
            Full = { Url = "https://example.com/full.jpg" }, Preview = { Url = "https://example.com/preview.jpg" }
        };

        Files? result = CommonMapper.MapFiles(dto);

        Assert.NotNull(result);
        Assert.NotNull(result.Full);
        Assert.NotNull(result.Preview);
        Assert.Equal(dto.Full.Url, result.Full.Url);
        Assert.Equal(dto.Preview.Url, result.Preview.Url);
    }

    [Fact]
    public void MapVideoSources_ReturnsNull_WhenAllEmpty()
    {
        VideoSourcesDto dto = new() { _240 = "", _720 = "" };

        Assert.Null(CommonMapper.MapVideoSources(dto));
    }

    [Fact]
    public void MapVideoSources_MapsFields_WhenPresent()
    {
        VideoSourcesDto dto = new() { _240 = "240.mp4", _720 = "720.mp4" };

        VideoSources? result = CommonMapper.MapVideoSources(dto);

        Assert.NotNull(result);
        Assert.Equal("240.mp4", result._240);
        Assert.Equal("720.mp4", result._720);
    }
}
