private async Task <Result <bool> > ConfigureVideo(Action <UploaderProgress> progress, UploaderProgress upProgress, string uploadId, bool isDirectVideo, bool isDisappearingVideo, string caption,
                                                           VisualMediaViewMode viewMode, InstaStoryType storyType, string recipients, string threadId, Uri uri, StoryUploadOptions uploadOptions = null)
        {
            try
            {
                upProgress.UploadState = InstaUploadState.Configuring;
                progress?.Invoke(upProgress);
                var instaUri      = UriCreator.GetDirectConfigVideoUri();
                var retryContext  = GetRetryContext();
                var clientContext = Guid.NewGuid().ToString();

                if (isDirectVideo)
                {
                    var data = new Dictionary <string, string>
                    {
                        { "action", "send_item" },
                        { "client_context", clientContext },
                        { "_csrftoken", Session.CsrfToken },
                        { "video_result", "" },
                        { "_uuid", Device.Uuid.ToString() },
                        { "upload_id", uploadId }
                    };
                    if (!string.IsNullOrEmpty(recipients))
                    {
                        data.Add("recipient_users", $"[[{recipients}]]");
                    }
                    else
                    {
                        data.Add("thread_ids", $"[{threadId}]");
                    }

                    instaUri = UriCreator.GetDirectConfigVideoUri();
                    var request = new HttpRequestMessage(HttpMethod.Post, instaUri);
                    request.Content = new HttpFormUrlEncodedContent(data);
                    request.Headers.Add("retry_context", retryContext);
                    var response = await _httpClient.SendRequestAsync(request);

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

                    DebugLogger.LogResponse(response);

                    if (response.StatusCode != HttpStatusCode.Ok)
                    {
                        upProgress.UploadState = InstaUploadState.Error;
                        progress?.Invoke(upProgress);
                        return(Result <bool> .Fail(json, response.ReasonPhrase));
                    }
                    var obj = JsonConvert.DeserializeObject <DefaultResponse>(json);

                    if (obj.Status.ToLower() == "ok")
                    {
                        upProgress.UploadState = InstaUploadState.Configured;
                        progress?.Invoke(upProgress);
                    }
                    else
                    {
                        upProgress.UploadState = InstaUploadState.Completed;
                        progress?.Invoke(upProgress);
                    }

                    return(obj.IsOk()
                        ? Result <bool> .Success(true, json, obj.Message)
                        : Result <bool> .Fail(json, obj.Message));
                }
                else
                {
                    var rnd  = new Random();
                    var data = new JObject
                    {
                        { "filter_type", "0" },
                        { "timezone_offset", "16200" },
                        { "_csrftoken", Session.CsrfToken },
                        { "client_shared_at", (DateTimeOffset.UtcNow.ToUnixTimeSeconds() - rnd.Next(25, 55)).ToString() },
                        { "story_media_creation_date", (DateTimeOffset.UtcNow.ToUnixTimeSeconds() - rnd.Next(50, 70)).ToString() },
                        { "media_folder", "Camera" },
                        { "source_type", "4" },
                        { "video_result", "" },
                        { "_uid", Session.LoggedInUser.Pk.ToString() },
                        { "_uuid", Device.Uuid.ToString() },
                        { "caption", caption ?? string.Empty },
                        { "date_time_original", DateTimeOffset.Now.ToString("yyyy-dd-MMTh:mm:ss-0fffZ") },
                        { "capture_type", "normal" },
                        { "mas_opt_in", "NOT_PROMPTED" },
                        { "upload_id", uploadId },
                        { "client_timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
                        {
                            "device", new JObject {
                                { "manufacturer", Device.HardwareManufacturer },
                                { "model", Device.HardwareModel },
                                { "android_release", Device.AndroidVersion.VersionNumber },
                                { "android_version", Device.AndroidVersion.APILevel }
                            }
                        },
                        { "length", 0 },
                        {
                            "extra", new JObject
                            {
                                { "source_width", 0 },
                                { "source_height", 0 }
                            }
                        },
                        { "audio_muted", false },
                        { "poster_frame_index", 0 },
                    };
                    if (isDisappearingVideo)
                    {
                        data.Add("view_mode", viewMode.ToString().ToLower());
                        data.Add("configure_mode", "2");
                        data.Add("recipient_users", "[]");
                        data.Add("thread_ids", $"[{threadId}]");
                    }
                    else
                    {
                        switch (storyType)
                        {
                        case InstaStoryType.SelfStory:
                        default:
                            data.Add("configure_mode", "1");
                            break;

                        case InstaStoryType.Direct:
                            data.Add("configure_mode", "2");
                            data.Add("view_mode", "replayable");
                            data.Add("recipient_users", "[]");
                            data.Add("thread_ids", $"[{threadId}]");
                            break;

                        case InstaStoryType.Both:
                            data.Add("configure_mode", "3");
                            data.Add("view_mode", "replayable");
                            data.Add("recipient_users", "[]");
                            data.Add("thread_ids", $"[{threadId}]");
                            break;
                        }

                        if (uri != null)
                        {
                            var webUri = new JArray
                            {
                                new JObject
                                {
                                    { "webUri", uri.ToString() }
                                }
                            };
                            var storyCta = new JArray
                            {
                                new JObject
                                {
                                    { "links", webUri }
                                }
                            };
                            data.Add("story_cta", storyCta.ToString(Formatting.None));
                        }

                        if (uploadOptions != null)
                        {
                            if (uploadOptions.Hashtags?.Count > 0)
                            {
                                var hashtagArr = new JArray();
                                foreach (var item in uploadOptions.Hashtags)
                                {
                                    hashtagArr.Add(item.ToJson());
                                }

                                data.Add("story_hashtags", hashtagArr.ToString(Formatting.None));
                            }

                            if (uploadOptions.Locations?.Count > 0)
                            {
                                var locationArr = new JArray();
                                foreach (var item in uploadOptions.Locations)
                                {
                                    locationArr.Add(item.ToJson());
                                }

                                data.Add("story_locations", locationArr.ToString(Formatting.None));
                            }
                            if (uploadOptions.Slider != null)
                            {
                                var sliderArr = new JArray
                                {
                                    uploadOptions.Slider.ToJson()
                                };

                                data.Add("story_sliders", sliderArr.ToString(Formatting.None));
                                if (uploadOptions.Slider.IsSticker)
                                {
                                    data.Add("story_sticker_ids", $"emoji_slider_{uploadOptions.Slider.Emoji}");
                                }
                            }
                            else
                            {
                                if (uploadOptions.Polls?.Count > 0)
                                {
                                    var pollArr = new JArray();
                                    foreach (var item in uploadOptions.Polls)
                                    {
                                        pollArr.Add(item.ToJson());
                                    }

                                    data.Add("story_polls", pollArr.ToString(Formatting.None));
                                }
                                if (uploadOptions.Questions?.Count > 0)
                                {
                                    var questionArr = new JArray();
                                    foreach (var item in uploadOptions.Questions)
                                    {
                                        questionArr.Add(item.ToJson());
                                    }

                                    data.Add("story_questions", questionArr.ToString(Formatting.None));
                                }
                            }
                            if (uploadOptions.Countdown != null)
                            {
                                var countdownArr = new JArray
                                {
                                    uploadOptions.Countdown.ToJson()
                                };

                                data.Add("story_countdowns", countdownArr.ToString(Formatting.None));
                                data.Add("story_sticker_ids", "countdown_sticker_time");
                            }
                        }
                    }
                    instaUri = UriCreator.GetVideoStoryConfigureUri(true);
                    var request = GetSignedRequest(instaUri, data);

                    request.Headers.Add("retry_context", retryContext);
                    var response = await _httpClient.SendRequestAsync(request);

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

                    DebugLogger.LogResponse(response);

                    if (response.IsSuccessStatusCode)
                    {
                        var mediaResponse = JsonConvert.DeserializeObject <DefaultResponse>(json);

                        if (mediaResponse.IsOk())
                        {
                            upProgress.UploadState = InstaUploadState.Configured;
                            progress?.Invoke(upProgress);
                        }
                        else
                        {
                            upProgress.UploadState = InstaUploadState.Completed;
                            progress?.Invoke(upProgress);
                        }
                        return(mediaResponse.IsOk() ? Result <bool> .Success(true) : Result <bool> .Fail(json, mediaResponse.Message));
                    }
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result <bool> .Fail(json, response.ReasonPhrase));
                }
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                DebugLogger.LogException(exception);
                return(Result <bool> .Except(exception));
            }
        }
        /// <summary>
        ///     Send video story, direct video, disappearing video
        /// </summary>
        /// <param name="isDirectVideo">Direct video</param>
        /// <param name="isDisappearingVideo">Disappearing video</param>
        private async Task <Result <bool> > SendVideoAsync(Action <UploaderProgress> progress, bool isDirectVideo, bool isDisappearingVideo, string caption,
                                                           VisualMediaViewMode viewMode, InstaStoryType storyType, string recipients, string threadId, InstaVideoUpload video, Uri uri = null, StoryUploadOptions uploadOptions = null)
        {
            var upProgress = new UploaderProgress
            {
                Caption     = caption ?? string.Empty,
                UploadState = InstaUploadState.Preparing
            };

            try
            {
                var uploadId        = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
                var videoHashCode   = video.Video.Url?.GetHashCode() ?? $"C:\\{GenerateRandomString(13)}.mp4".GetHashCode();
                var waterfallId     = Guid.NewGuid().ToString();
                var videoEntityName = $"{uploadId}_0_{videoHashCode}";
                var videoUri        = UriCreator.GetStoryUploadVideoUri(uploadId, videoHashCode);
                var retryContext    = GetRetryContext();
                HttpRequestMessage  request;
                HttpResponseMessage response;
                string videoUploadParams = null;
                string json = null;
                upProgress.UploadId = uploadId;
                progress?.Invoke(upProgress);
                var videoUploadParamsObj = new JObject();
                if (isDirectVideo)
                {
                    videoUploadParamsObj = new JObject
                    {
                        { "upload_media_height", "0" },
                        { "direct_v2", "1" },
                        { "upload_media_width", "0" },
                        { "upload_media_duration_ms", "0" },
                        { "upload_id", uploadId },
                        { "retry_context", retryContext },
                        { "media_type", "2" }
                    };

                    videoUploadParams = JsonConvert.SerializeObject(videoUploadParamsObj);
                    request           = new HttpRequestMessage(HttpMethod.Get, videoUri);
                    request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId);
                    request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams);
                    response = await _httpClient.SendRequestAsync(request);

                    json = await response.Content.ReadAsStringAsync();

                    DebugLogger.LogResponse(response);

                    if (response.StatusCode != HttpStatusCode.Ok)
                    {
                        upProgress.UploadState = InstaUploadState.Error;
                        progress?.Invoke(upProgress);
                        return(Result <bool> .Fail(json, response.ReasonPhrase));
                    }
                }
                else
                {
                    videoUploadParamsObj = new JObject
                    {
                        { "_csrftoken", Session.CsrfToken },
                        { "_uid", Session.LoggedInUser.Pk },
                        { "_uuid", Device.Uuid.ToString() },
                        {
                            "media_info", new JObject
                            {
                                { "capture_mode", "normal" },
                                { "media_type", 2 },
                                { "caption", caption ?? string.Empty },
                                { "mentions", new JArray() },
                                { "hashtags", new JArray() },
                                { "locations", new JArray() },
                                { "stickers", new JArray() },
                            }
                        }
                    };
                    request  = GetSignedRequest(UriCreator.GetStoryMediaInfoUploadUri(), videoUploadParamsObj);
                    response = await _httpClient.SendRequestAsync(request);

                    json = await response.Content.ReadAsStringAsync();

                    DebugLogger.LogResponse(response);

                    videoUploadParamsObj = new JObject
                    {
                        { "upload_media_height", "0" },
                        { "upload_media_width", "0" },
                        { "upload_media_duration_ms", "0" },
                        { "upload_id", uploadId },
                        { "retry_context", "{\"num_step_auto_retry\":0,\"num_reupload\":0,\"num_step_manual_retry\":0}" },
                        { "media_type", "2" }
                    };
                    if (isDisappearingVideo)
                    {
                        videoUploadParamsObj.Add("for_direct_story", "1");
                    }
                    else
                    {
                        switch (storyType)
                        {
                        case InstaStoryType.SelfStory:
                        default:
                            videoUploadParamsObj.Add("for_album", "1");
                            break;

                        case InstaStoryType.Direct:
                            videoUploadParamsObj.Add("for_direct_story", "1");
                            break;

                        case InstaStoryType.Both:
                            videoUploadParamsObj.Add("for_album", "1");
                            videoUploadParamsObj.Add("for_direct_story", "1");
                            break;
                        }
                    }
                    videoUploadParams = JsonConvert.SerializeObject(videoUploadParamsObj);
                    request           = new HttpRequestMessage(Windows.Web.Http.HttpMethod.Get, videoUri);
                    request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId);
                    request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams);
                    response = await _httpClient.SendRequestAsync(request);

                    json = await response.Content.ReadAsStringAsync();

                    DebugLogger.LogResponse(response);

                    if (response.StatusCode != HttpStatusCode.Ok)
                    {
                        upProgress.UploadState = InstaUploadState.Error;
                        progress?.Invoke(upProgress);
                        return(Result <bool> .Fail(json, response.ReasonPhrase));
                    }
                }

                // video part
                IBuffer videoUploadBuffer;
                if (video.Video.UploadBuffer == null)
                {
                    if (video.Video.Url == null)
                    {
                        throw new NullReferenceException("No upload buffer or file path are provided for video upload.");
                    }
                    var videoFile = await StorageFile.GetFileFromPathAsync(video.Video.Url.AbsolutePath);

                    videoUploadBuffer = await FileIO.ReadBufferAsync(videoFile);
                }
                else
                {
                    videoUploadBuffer = video.Video.UploadBuffer;
                }

                var videoContent = new HttpBufferContent(videoUploadBuffer);

                request = new HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, videoUri)
                {
                    Content = videoContent
                };
                upProgress.UploadState = InstaUploadState.Uploading;
                progress?.Invoke(upProgress);
                var vidExt = Path.GetExtension(video.Video.Url?.AbsolutePath ?? $"C:\\{GenerateRandomString(13)}.mp4")
                             .Replace(".", "").ToLower();
                if (vidExt == "mov")
                {
                    request.Headers.Add("X-Entity-Type", "video/quicktime");
                }
                else
                {
                    request.Headers.Add("X-Entity-Type", "video/mp4");
                }

                request.Headers.Add("Offset", "0");
                request.Headers.Add("X-Instagram-Rupload-Params", videoUploadParams);
                request.Headers.Add("X-Entity-Name", videoEntityName);
                request.Headers.Add("X-Entity-Length", videoUploadBuffer.Length.ToString());
                request.Headers.Add("X_FB_VIDEO_WATERFALL_ID", waterfallId);
                response = await _httpClient.SendRequestAsync(request);

                json = await response.Content.ReadAsStringAsync();

                if (response.StatusCode != HttpStatusCode.Ok)
                {
                    upProgress.UploadState = InstaUploadState.Error;
                    progress?.Invoke(upProgress);
                    return(Result <bool> .Fail(json, response.ReasonPhrase));
                }
                upProgress.UploadState = InstaUploadState.Uploaded;
                progress?.Invoke(upProgress);
                //upProgress = progressContent?.UploaderProgress;
                if (!isDirectVideo)
                {
                    upProgress.UploadState = InstaUploadState.UploadingThumbnail;
                    progress?.Invoke(upProgress);
                    var photoHashCode        = video.VideoThumbnail.Url?.GetHashCode() ?? $"C:\\{GenerateRandomString(13)}.jpg".GetHashCode();
                    var photoEntityName      = $"{uploadId}_0_{photoHashCode}";
                    var photoUri             = UriCreator.GetStoryUploadPhotoUri(uploadId, photoHashCode);
                    var photoUploadParamsObj = new JObject
                    {
                        { "retry_context", retryContext },
                        { "media_type", "2" },
                        { "upload_id", uploadId },
                        { "image_compression", "{\"lib_name\":\"moz\",\"lib_version\":\"3.1.m\",\"quality\":\"95\"}" },
                    };

                    var     photoUploadParams = JsonConvert.SerializeObject(photoUploadParamsObj);
                    IBuffer thumbnailUploadBuffer;
                    if (video.VideoThumbnail.UploadBuffer == null)
                    {
                        if (video.VideoThumbnail.Url == null)
                        {
                            throw new NullReferenceException("No upload buffer or file path are provided for video thumbnail upload.");
                        }
                        var videoFile = await StorageFile.GetFileFromPathAsync(video.VideoThumbnail.Url.AbsolutePath);

                        thumbnailUploadBuffer = await FileIO.ReadBufferAsync(videoFile);
                    }
                    else
                    {
                        thumbnailUploadBuffer = video.VideoThumbnail.UploadBuffer;
                    }
                    var imageContent = new HttpBufferContent(thumbnailUploadBuffer);
                    imageContent.Headers.Add("Content-Transfer-Encoding", "binary");
                    imageContent.Headers.Add("Content-Type", "application/octet-stream");
                    request         = new HttpRequestMessage(HttpMethod.Post, photoUri);
                    request.Content = imageContent;
                    request.Headers.Add("X-Entity-Type", "image/jpeg");
                    request.Headers.Add("Offset", "0");
                    request.Headers.Add("X-Instagram-Rupload-Params", photoUploadParams);
                    request.Headers.Add("X-Entity-Name", photoEntityName);
                    request.Headers.Add("X-Entity-Length", thumbnailUploadBuffer.Length.ToString());
                    request.Headers.Add("X_FB_PHOTO_WATERFALL_ID", waterfallId);
                    response = await _httpClient.SendRequestAsync(request);

                    json = await response.Content.ReadAsStringAsync();

                    DebugLogger.LogResponse(response);

                    upProgress.UploadState = InstaUploadState.ThumbnailUploaded;
                    progress?.Invoke(upProgress);
                }
                return(await ConfigureVideo(progress, upProgress, uploadId, isDirectVideo, isDisappearingVideo, caption, viewMode, storyType, recipients, threadId, uri, uploadOptions));
            }
            catch (Exception exception)
            {
                upProgress.UploadState = InstaUploadState.Error;
                progress?.Invoke(upProgress);
                DebugLogger.LogException(exception);
                return(Result <bool> .Except(exception));
            }
        }