using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Services.Store;
using Windows.System;
using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces;

namespace Wino.Core.UWP.Services
{
    public class StoreRatingService : IStoreRatingService
    {
        private const string RatedStorageKey = nameof(RatedStorageKey);
        private const string LatestAskedKey = nameof(LatestAskedKey);

        private readonly IConfigurationService _configurationService;
        private readonly IMailDialogService _dialogService;

        public StoreRatingService(IConfigurationService configurationService, IMailDialogService dialogService)
        {
            _configurationService = configurationService;
            _dialogService = dialogService;
        }

        private bool IsAskingThresholdExceeded()
        {
            var latestAskedDate = _configurationService.Get(LatestAskedKey, DateTime.MinValue);

            // Never asked before.
            // Set the threshold and wait for the next trigger.

            if (latestAskedDate == DateTime.MinValue)
            {
                _configurationService.Set(LatestAskedKey, DateTime.UtcNow);
            }
            else if (DateTime.UtcNow >= latestAskedDate.AddMinutes(30))
            {
                return true;
            }

            return false;
        }

        public async Task PromptRatingDialogAsync()
        {
            // Annoying.
            if (Debugger.IsAttached) return;

            // Swallow all exceptions. App should not crash in any errors.

            try
            {
                bool isRated = _configurationService.GetRoaming(RatedStorageKey, false);

                if (isRated) return;

                if (!isRated)
                {
                    if (!IsAskingThresholdExceeded()) return;

                    var isRateWinoApproved = await _dialogService.ShowWinoCustomMessageDialogAsync(Translator.StoreRatingDialog_Title,
                        Translator.StoreRatingDialog_MessageFirstLine,
                        Translator.Buttons_RateWino,
                        Domain.Enums.WinoCustomMessageDialogIcon.Question,
                        Translator.Buttons_No,
                        RatedStorageKey);

                    if (isRateWinoApproved)
                    {
                        // In case of failure of this call, we will navigate users to Store page directly.

                        try
                        {
                            await ShowPortableRatingDialogAsync();
                        }
                        catch (Exception)
                        {
                            await Launcher.LaunchUriAsync(new Uri($"ms-windows-store://review/?ProductId=9NCRCVJC50WL"));
                        }
                    }
                }
            }
            catch (Exception) { }
            finally
            {
                _configurationService.Set(LatestAskedKey, DateTime.UtcNow);
            }
        }

        private async Task ShowPortableRatingDialogAsync()
        {
            var _storeContext = StoreContext.GetDefault();

            StoreRateAndReviewResult result = await _storeContext.RequestRateAndReviewAppAsync();

            // Check status
            switch (result.Status)
            {
                case StoreRateAndReviewStatus.Succeeded:
                    if (result.WasUpdated)
                        _dialogService.InfoBarMessage(Translator.Info_ReviewSuccessTitle, Translator.Info_ReviewUpdatedMessage, Domain.Enums.InfoBarMessageType.Success);
                    else
                        _dialogService.InfoBarMessage(Translator.Info_ReviewSuccessTitle, Translator.Info_ReviewNewMessage, Domain.Enums.InfoBarMessageType.Success);

                    _configurationService.Set(RatedStorageKey, true);
                    break;
                case StoreRateAndReviewStatus.CanceledByUser:
                    break;

                case StoreRateAndReviewStatus.NetworkError:
                    _dialogService.InfoBarMessage(Translator.Info_ReviewNetworkErrorTitle, Translator.Info_ReviewNetworkErrorMessage, Domain.Enums.InfoBarMessageType.Warning);
                    break;
                default:
                    _dialogService.InfoBarMessage(Translator.Info_ReviewUnknownErrorTitle, string.Format(Translator.Info_ReviewUnknownErrorMessage, result.ExtendedError.Message), Domain.Enums.InfoBarMessageType.Warning);
                    break;
            }
        }

        public async Task LaunchStorePageForReviewAsync()
        {
            try
            {
                await CoreApplication.GetCurrentView()?.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
                {
                    // TODO: Get it from package info.
                    await Launcher.LaunchUriAsync(new Uri($"ms-windows-store://review/?ProductId=9NCRCVJC50WL"));
                });
            }
            catch (Exception) { }
        }
    }
}
