using OF_DL.Models.Dtos.Common;
using OF_DL.Models.Dtos.Messages;
using OF_DL.Models.Entities.Common;
using MessageEntities = OF_DL.Models.Entities.Messages;

namespace OF_DL.Models.Mappers;

public static class MessagesMapper
{
    public static MessageEntities.Messages FromDto(MessagesDto? dto)
    {
        MessageEntities.Messages mapped = new() { HasMore = dto?.HasMore ?? false };

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

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

        return mapped;
    }

    public static MessageEntities.SingleMessage FromDto(SingleMessageDto? dto)
    {
        MessageEntities.SingleMessage mapped = new();

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

        mapped.Id = dto.Id;
        mapped.Text = dto.Text;
        mapped.Price = dto.Price;
        mapped.CreatedAt = dto.CreatedAt;
        mapped.Media = MapMedia(dto.Media);
        mapped.Previews = dto.Previews;
        mapped.FromUser = MapFromUser(dto.FromUser);

        return mapped;
    }

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

    private static MessageEntities.ListItem MapListItem(ListItemDto dto) =>
        new()
        {
            Id = dto.Id,
            Text = dto.Text,
            Price = dto.Price,
            CanPurchaseReason = dto.CanPurchaseReason,
            CreatedAt = dto.CreatedAt,
            Media = MapMedia(dto.Media),
            Previews = dto.Previews,
            FromUser = MapFromUser(dto.FromUser)
        };

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

    private static FromUser? MapFromUser(FromUserDto? dto) =>
        dto?.Id == null ? null : new FromUser { Id = (long)dto.Id };

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

    private static Full? MapFull(FullDto? dto) => dto == null ? null : new Full { Url = dto.Url };

    private static Drm? MapDrm(DrmDto? dto) => dto == null
        ? null
        : new Drm { Manifest = MapManifest(dto.Manifest), Signature = MapSignature(dto.Signature) };

    private static Manifest? MapManifest(ManifestDto? dto) => dto == null ? null : new Manifest { Dash = dto.Dash };

    private static Signature? MapSignature(SignatureDto? dto) =>
        dto == null ? null : new Signature { Dash = MapDash(dto.Dash) };

    private static Dash? MapDash(DashDto? dto)
    {
        if (dto == null)
        {
            return null;
        }

        return new Dash
        {
            CloudFrontPolicy = dto.CloudFrontPolicy,
            CloudFrontSignature = dto.CloudFrontSignature,
            CloudFrontKeyPairId = dto.CloudFrontKeyPairId
        };
    }
}
