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


namespace OF_DL.Models.Mappers;

public static class PostMapper
{
    public static Post FromDto(PostDto? dto)
    {
        Post mapped = new() { HasMore = dto?.HasMore ?? false, TailMarker = dto?.TailMarker };

        if (dto?.List == null)
        {
            return mapped;
        }

        foreach (ListItemDto entry in dto.List)
        {
            mapped.List.Add(MapList(entry));
        }

        return mapped;
    }

    public static SinglePost FromDto(SinglePostDto? dto)
    {
        SinglePost mapped = new();

        if (dto == null)
        {
            return mapped;
        }

        mapped.Id = dto.Id;
        mapped.PostedAt = dto.PostedAt;
        mapped.Author = CommonMapper.MapAuthor(dto.Author);
        mapped.Text = dto.Text;
        mapped.RawText = dto.RawText;
        mapped.IsOpened = dto.IsOpened;
        mapped.Price = dto.Price;
        mapped.IsArchived = dto.IsArchived;
        mapped.Media = MapSingleMedia(dto.Media);
        mapped.Preview = dto.Preview;

        return mapped;
    }

    private static ListItem MapList(ListItemDto dto) =>
        new()
        {
            Id = dto.Id,
            PostedAt = dto.PostedAt,
            Author = CommonMapper.MapAuthor(dto.Author),
            Text = dto.Text,
            RawText = dto.RawText,
            IsOpened = dto.IsOpened,
            Price = dto.Price,
            IsArchived = dto.IsArchived,
            Media = MapMedia(dto.Media),
            Preview = dto.Preview
        };

    private static List<Medium>? MapMedia(List<MediumDto>? media) =>
        media?.Select(MapMedium).ToList();

    private static Medium MapMedium(MediumDto dto) =>
        new()
        {
            Id = dto.Id,
            Type = dto.Type,
            CanView = dto.CanView,
            Preview = dto.Preview,
            Files = MapFiles(dto.Files)
        };

    private static Files? MapFiles(FilesDto? dto) => dto == null
        ? null
        : new Files
        {
            Full = CommonMapper.MapFull(dto.Full),
            Preview = CommonMapper.MapPreview(dto.Preview),
            Drm = CommonMapper.MapDrm(dto.Drm)
        };

    private static List<Medium>? MapSingleMedia(List<MediumDto>? media) =>
        media?.Select(MapSingleMedium).ToList();

    private static Medium MapSingleMedium(MediumDto dto) =>
        new()
        {
            Id = dto.Id,
            Type = dto.Type,
            CanView = dto.CanView,
            Preview = dto.Preview,
            Files = MapSingleFiles(dto.Files),
            VideoSources = CommonMapper.MapVideoSources(dto.VideoSources)
        };

    private static Files? MapSingleFiles(FilesDto? dto)
    {
        if (dto == null)
        {
            return null;
        }

        return new Files
        {
            Full = CommonMapper.MapFull(dto.Full),
            Preview = CommonMapper.MapPreview(dto.Preview),
            Drm = CommonMapper.MapDrm(dto.Drm)
        };
    }
}
