using System.Globalization;
using InABox.Core;
using Newtonsoft.Json;

namespace InABox.Avalonia.Platform.iOS
{
    
    public class iOS_AppVersion : IAppVersion
    {
        string _bundleName => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleName").ToString();
        string _bundleIdentifier => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleIdentifier").ToString();
        string _bundleVersion => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString();
        private Dictionary<string, object> _appstoreversion = new();
        
        
        public Logger Logger { get; set; }
        
        public string InstalledVersionNumber() => _bundleVersion;
        
        public async Task<bool> IsUsingLatestVersion()
        {
            
            try
            {                
                var info = await GetLatestVersion(false);
                return String.IsNullOrWhiteSpace(info.Version) 
                       || (Version.Parse(info.Version).CompareTo(Version.Parse(_bundleVersion)) <= 0);
            }
            catch (Exception e)
            {
                Logger?.Error($"Error in IsUsingLatestVersion(): {e.Message}\n{e.StackTrace}");
            }
            return true;
        }


        private async Task CheckAppStoreInfo()
        {
            
            // http://itunes.apple.com/lookup?bundleId=com.prsdigital.prssiteapp
            var url = $"http://itunes.apple.com/lookup?bundleId={_bundleIdentifier}";

            using (var request = new HttpRequestMessage(HttpMethod.Get, url))
            {
                using (var handler = new HttpClientHandler())
                {

                    handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
                    {
                        //bypass
                        return true;
                    };

                    using (var client = new HttpClient(handler))
                    {
                        using (var responseMsg = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead))
                        {
                            if (!responseMsg.IsSuccessStatusCode)
                            {
                                throw new LatestVersionException($"Error connecting to the App Store. Url={url}.");
                            }

                            try
                            {
                                var content = responseMsg.Content == null
                                    ? null
                                    : await responseMsg.Content.ReadAsStringAsync();

                                var _appstoreinfo =
                                    JsonConvert.DeserializeObject<Dictionary<string, object>>(
                                        content);

                                if (_appstoreinfo.TryGetValue("results", out var results)
                                    && results is Dictionary<string, object> dict
                                    && dict.FirstOrDefault().Value is Dictionary<string, object> verinfo)
                                    _appstoreversion = verinfo;
                            }
                            catch (Exception e)
                            {
                                Logger?.Error(
                                    $"Error parsing content from the App Store. Url={url}\n{e.Message}\n{e.StackTrace}");
                            }
                        }
                    }
                }
            }
        }

        private AppInfo _info = null;
        
        public async Task<AppInfo> GetLatestVersion(bool force)
        {
            
            if (force)
                _info = null;

            if (_info != null)
                return _info;
            
            
            _info = new AppInfo();
            try
            {
                await CheckAppStoreInfo();
                {
                    if (_appstoreversion.TryGetValue("releaseDate", out var releaseDateObj) &&
                        releaseDateObj is string releaseDateStr &&
                        DateTime.TryParse(releaseDateStr, out DateTime releaseDate))
                        _info.Date = releaseDate;
                    if (_appstoreversion.TryGetValue("version", out var versionObj) &&
                        versionObj is string versionStr)
                        _info.Version = versionStr;
                    if (_appstoreversion.TryGetValue("releaseNotes", out var releaseNotesObj) &&
                        releaseNotesObj is string releaseNotesStr)
                        _info.Notes = releaseNotesStr;
                }
            }
            catch (Exception e)
            {
                Logger?.Error($"Error in GetLatestVersion(): {e.Message}\n{e.StackTrace}");
            }
            return _info;

        }

        /// <inheritdoc />
        public Task OpenAppInStore()
        {
            try
            {
                var location = RegionInfo.CurrentRegion.Name.ToLower();
                if (_appstoreversion.TryGetValue("releaseNotes", out var trackIdObj) &&
                    trackIdObj is string trackIdStr)
                {
                    var url = String.Format("https://itunes.apple.com/{0}/app/{1}/id{2}?mt=8", location, _bundleName,
                        trackIdStr);
                    #if __IOS__
                        UIKit.UIApplication.SharedApplication.OpenUrl(new NSUrl(url)); 
                    #elif __MACOS__
                        AppKit.NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl($"http://appstore.com/mac/{appName}"));
                    #endif
                }
            }
            catch (Exception e)
            {
                Logger?.Error($"Error in OpenAppInStore(): {e.Message}\n{e.StackTrace}");
            }

            return Task.FromResult(true);
        }
    }
}