using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Threading;
using Foundation;
using Pixiview.iOS.Services;
using Pixiview.Resources;
using Pixiview.Utils;
using UIKit;
using Xamarin.Forms;

[assembly: Dependency(typeof(EnvironmentService))]
namespace Pixiview.iOS.Services
{
    public class EnvironmentService : IEnvironmentService
    {
        public EnvironmentParameter GetEnvironment()
        {
            return new EnvironmentParameter
            {
                IconLightFontFamily = "FontAwesome5Pro-Light",
                IconRegularFontFamily = "FontAwesome5Pro-Regular",
                IconSolidFontFamily = "FontAwesome5Pro-Solid",

                IconLeft = "\uf104"     // for android, it's "\uf060"
            };
        }

        #region - Theme -

        /*
        [SuppressMessage("Code Notifications", "XI0002:Notifies you from using newer Apple APIs when targeting an older OS version", Justification = "<Pending>")]
        public AppTheme GetApplicationTheme()
        {
            if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
            {
                var currentController = Platform.GetCurrentUIViewController();
                if (currentController == null)
                {
                    return AppTheme.Unspecified;
                }

                var style = currentController.TraitCollection.UserInterfaceStyle;
                if (style == UIUserInterfaceStyle.Dark)
                {
                    return AppTheme.Dark;
                }
                else if (style == UIUserInterfaceStyle.Light)
                {
                    return AppTheme.Light;
                }
            }

            return AppTheme.Unspecified;
        }
        //*/

        public void SetStatusBarStyle(StatusBarStyles style)
        {
            SetStatusBarStyle(ConvertStyle(style));
        }

        public void SetStatusBarColor(Color color)
        {
            // nothing need to do
        }

        #endregion

        public static void SetStatusBarStyle(UIStatusBarStyle style)
        {
            if (UIApplication.SharedApplication.StatusBarStyle == style)
            {
                return;
            }
            if (style == UIStatusBarStyle.BlackOpaque)
            {
                UIApplication.SharedApplication.SetStatusBarHidden(true, true);
            }
            else
            {
                UIApplication.SharedApplication.SetStatusBarStyle(style, true);
                UIApplication.SharedApplication.SetStatusBarHidden(false, true);
            }
        }

        [SuppressMessage("Code Notifications", "XI0002:Notifies you from using newer Apple APIs when targeting an older OS version", Justification = "<Pending>")]
        public static UIStatusBarStyle ConvertStyle(StatusBarStyles style)
        {
            switch (style)
            {
                case StatusBarStyles.DarkText:
                    return UIStatusBarStyle.DarkContent;
                case StatusBarStyles.WhiteText:
                    return UIStatusBarStyle.LightContent;
                case StatusBarStyles.Hidden:
                    return UIStatusBarStyle.BlackOpaque;
                case StatusBarStyles.Default:
                default:
                    return UIStatusBarStyle.Default;
            }
        }

        #region - Culture Info -

        public CultureInfo GetCurrentCultureInfo()
        {
            string lang;
            if (NSLocale.PreferredLanguages.Length > 0)
            {
                var pref = NSLocale.PreferredLanguages[0];
                lang = iOSToDotnetLanguage(pref);
            }
            else
            {
                lang = "zh-CN";
            }

            CultureInfo ci;
            var platform = new PlatformCulture(lang);
            try
            {
                ci = new CultureInfo(platform.Language);
            }
            catch (CultureNotFoundException e)
            {
                try
                {
                    var fallback = ToDotnetFallbackLanguage(platform);
                    App.DebugPrint($"{lang} failed, trying {fallback} ({e.Message})");
                    ci = new CultureInfo(fallback);
                }
                catch (CultureNotFoundException e1)
                {
                    App.DebugError("culture.get", $"{lang} couldn't be set, using 'zh-CN' ({e1.Message})");
                    ci = new CultureInfo("zh-CN");
                }
            }

            return ci;
        }

        [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
        string iOSToDotnetLanguage(string iOSLanguage)
        {
            string netLanguage;

            //certain languages need to be converted to CultureInfo equivalent
            switch (iOSLanguage)
            {
                case "ms-MY":   // "Malaysian (Malaysia)" not supported .NET culture
                case "ms-SG":   // "Malaysian (Singapore)" not supported .NET culture
                    netLanguage = "ms"; // closest supported
                    break;
                case "gsw-CH":  // "Schwiizertüütsch (Swiss German)" not supported .NET culture
                    netLanguage = "de-CH"; // closest supported
                    break;
                // add more application-specific cases here (if required)
                // ONLY use cultures that have been tested and known to work
                default:
                    netLanguage = iOSLanguage;
                    break;
            }

            App.DebugPrint($"iOS Language: {iOSLanguage}, .NET Language/Locale: {netLanguage}");
            return netLanguage;
        }

        string ToDotnetFallbackLanguage(PlatformCulture platCulture)
        {
            string netLanguage;

            switch (platCulture.LanguageCode)
            {
                // 
                case "pt":
                    netLanguage = "pt-PT"; // fallback to Portuguese (Portugal)
                    break;
                case "gsw":
                    netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app
                    break;
                // add more application-specific cases here (if required)
                // ONLY use cultures that have been tested and known to work
                default:
                    netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
                    break;
            }

            App.DebugPrint($".NET Fallback Language/Locale: {platCulture.LanguageCode} to {netLanguage} (application-specific)");
            return netLanguage;
        }

        public void SetCultureInfo(CultureInfo ci)
        {
            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = ci;

            App.DebugPrint($"CurrentCulture set: {ci.Name}");
        }

        #endregion
    }
}
