/// <summary>
        ///     Edit the caption/location of the media (photo/video/album)
        /// </summary>
        /// <param name="mediaId">The media ID</param>
        /// <param name="caption">The new caption</param>
        /// <param name="location">Location => Optional (get it from <seealso cref="LocationProcessor.SearchLocationAsync"/></param>
        /// <returns>Return true if everything is ok</returns>
        public async Task <IResult <InstaMedia> > EditMediaAsync(string mediaId, string caption, InstaLocationShort location = null)
        {
            UserAuthValidator.Validate(_userAuthValidate);
            try
            {
                var editMediaUri = UriCreator.GetEditMediaUri(mediaId);

                var data = new JObject
                {
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "_uid", _user.LoggedInUser.Pk },
                    { "_csrftoken", _user.CsrfToken },
                    { "caption_text", caption ?? string.Empty }
                };
                if (location != null)
                {
                    data.Add("location", location.GetJson());
                }
                var request  = _httpHelper.GetSignedRequest(HttpMethod.Post, editMediaUri, _deviceInfo, data);
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var mediaResponse = JsonConvert.DeserializeObject <InstaMediaItemResponse>(json,
                                                                                               new InstaMediaDataConverter());
                    var converter = ConvertersFabric.Instance.GetSingleMediaConverter(mediaResponse);
                    return(Result.Success(converter.Convert()));
                }
                var error = JsonConvert.DeserializeObject <BadStatusResponse>(json);
                return(Result.Fail(error.Message, (InstaMedia)null));
            }
            catch (Exception exception)
            {
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }
        private async Task <IResult <InstaMedia> > ConfigureAlbumAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, string[] imagesUploadIds, Dictionary <string, InstaVideo> videos, string caption, InstaLocationShort location)
        {
            try
            {
                upProgress.Name        = "Album upload";
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var instaUri        = UriCreator.GetMediaAlbumConfigureUri();
                var clientSidecarId = ApiRequestMessage.GenerateUploadId();
                var childrenArray   = new JArray();
                if (imagesUploadIds != null)
                {
                    foreach (var id in imagesUploadIds)
                    {
                        childrenArray.Add(new JObject
                        {
                            { "timezone_offset", "16200" },
                            { "source_type", 4 },
                            { "upload_id", id },
                            { "caption", "" },
                        });
                    }
                }
                if (videos != null)
                {
                    foreach (var id in videos)
                    {
                        childrenArray.Add(new JObject
                        {
                            { "timezone_offset", "16200" },
                            { "caption", "" },
                            { "upload_id", id.Key },
                            { "date_time_original", DateTime.Now.ToString("yyyy-dd-MMTh:mm:ss-0fffZ") },
                            { "source_type", "4" },
                            {
                                "extra", JsonConvert.SerializeObject(new JObject
                                {
                                    { "source_width", 0 },
                                    { "source_height", 0 }
                                })
                            },
                            {
                                "clips", JsonConvert.SerializeObject(new JArray {
                                    new JObject
                                    {
                                        { "length", id.Value.Length },
                                        { "source_type", "4" },
                                    }
                                })
                            },
                            {
                                "device", JsonConvert.SerializeObject(new JObject {
                                    { "manufacturer", _deviceInfo.HardwareManufacturer },
                                    { "model", _deviceInfo.DeviceModelIdentifier },
                                    { "android_release", _deviceInfo.AndroidVer.VersionNumber },
                                    { "android_version", _deviceInfo.AndroidVer.APILevel }
                                })
                            },
                            { "length", id.Value.Length },
                            { "poster_frame_index", 0 },
                            { "audio_muted", false },
                            { "filter_type", "0" },
                            { "video_result", "deprecated" },
                        });
                    }
                }
                var data = new JObject
                {
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "_uid", _user.LoggedInUser.Pk },
                    { "_csrftoken", _user.CsrfToken },
                    { "caption", caption },
                    { "client_sidecar_id", clientSidecarId },
                    { "upload_id", clientSidecarId },
                    {
                        "device", new JObject
                        {
                            { "manufacturer", _deviceInfo.HardwareManufacturer },
                            { "model", _deviceInfo.DeviceModelIdentifier },
                            { "android_release", _deviceInfo.AndroidVer.VersionNumber },
                            { "android_version", _deviceInfo.AndroidVer.APILevel }
                        }
                    },
                    { "children_metadata", childrenArray },
                };
                if (location != null)
                {
                    data.Add("location", location.GetJson());
                    data.Add("date_time_digitalized", DateTime.Now.ToString("yyyy:dd:MM+h:mm:ss"));
                }
                var request  = _httpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data);
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaMedia>(response, json));
                }
                var mediaResponse = JsonConvert.DeserializeObject <InstaMediaAlbumResponse>(json);
                var converter     = ConvertersFabric.Instance.GetSingleMediaFromAlbumConverter(mediaResponse);
                var obj           = converter.Convert();
                if (obj.Caption == null && !string.IsNullOrEmpty(caption))
                {
                    var editedMedia = await _instaApi.MediaProcessor.EditMediaAsync(obj.InstaIdentifier, caption, location);

                    if (editedMedia.Succeeded)
                    {
                        upProgress.UploadState = InstaUploadState.Configured;
                        progress?.Invoke(upProgress);
                        upProgress.UploadState = InstaUploadState.Completed;
                        progress?.Invoke(upProgress);
                        return(Result.Success(editedMedia.Value));
                    }
                }
                upProgress.UploadState = InstaUploadState.Configured;
                progress?.Invoke(upProgress);
                upProgress.UploadState = InstaUploadState.Completed;
                progress?.Invoke(upProgress);
                return(Result.Success(obj));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }
        private async Task <IResult <InstaMedia> > ConfigureVideoAsync(Action <InstaUploaderProgress> progress, InstaUploaderProgress upProgress, InstaVideo video, string uploadId, string caption, InstaLocationShort location)
        {
            try
            {
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var instaUri = UriCreator.GetMediaConfigureUri();
                var data     = new JObject
                {
                    { "caption", caption ?? string.Empty },
                    { "upload_id", uploadId },
                    { "source_type", "3" },
                    { "camera_position", "unknown" },
                    {
                        "extra", new JObject
                        {
                            { "source_width", 0 },
                            { "source_height", 0 }
                        }
                    },
                    {
                        "clips", new JArray {
                            new JObject
                            {
                                { "length", 0 },
                                { "creation_date", DateTime.Now.ToString("yyyy-dd-MMTh:mm:ss-0fff") },
                                { "source_type", "3" },
                                { "camera_position", "back" }
                            }
                        }
                    },
                    { "poster_frame_index", 0 },
                    { "audio_muted", false },
                    { "filter_type", "0" },
                    { "video_result", "" },
                    { "_csrftoken", _user.CsrfToken },
                    { "_uuid", _deviceInfo.DeviceGuid.ToString() },
                    { "_uid", _user.LoggedInUser.UserName }
                };
                if (location != null)
                {
                    data.Add("location", location.GetJson());
                    data.Add("date_time_digitalized", DateTime.Now.ToString("yyyy:dd:MM+h:mm:ss"));
                }
                var request = _httpHelper.GetSignedRequest(HttpMethod.Post, instaUri, _deviceInfo, data);
                request.Headers.Host = "i.instagram.com";
                var response = await _httpRequestProcessor.SendAsync(request);

                var json = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result.UnExpectedResponse <InstaMedia>(response, json));
                }
                upProgress.UploadState = InstaUploadState.Configured;
                progress?.Invoke(upProgress);
                var success = await ExposeVideoAsync(uploadId, caption, location);

                if (success.Succeeded)
                {
                    upProgress.UploadState = InstaUploadState.Completed;
                    progress?.Invoke(upProgress);
                    return(success);
                }

                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                return(Result.Fail <InstaMedia>("Cannot expose media"));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                _logger?.LogException(exception);
                return(Result.Fail <InstaMedia>(exception));
            }
        }