using System.Globalization;
using System.Threading;
using Pixiview.Resources;
#if __IOS__
using System.Diagnostics.CodeAnalysis;
using Foundation;
using UIKit;
#elif __ANDROID__
using Android.OS;
using Xamarin.Forms.Platform.Android;
#endif
using Xamarin.Forms;

namespace Pixiview.Utils
{
    public class EnvironmentService
    {
        #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 static void SetStatusBarColor(Color color)
        {
#if __ANDROID_21__
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
            {
                Droid.MainActivity.Main.SetStatusBarColor(color.ToAndroid());
                Droid.MainActivity.Main.Window.DecorView.SystemUiVisibility =
                    App.CurrentTheme == Xamarin.Essentials.AppTheme.Dark ?
                    Android.Views.StatusBarVisibility.Visible :
                    (Android.Views.StatusBarVisibility)Android.Views.SystemUiFlags.LightStatusBar;
            }
#endif
        }

        public static void SetStatusBarStyle(StatusBarStyles style)
        {
#if __IOS__
            SetStatusBarStyle(ConvertStyle(style));
        }

        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;
            }
        }
#else
        }
#endif

        #endregion

        #region - Culture Info -

        public static void SetCultureInfo(CultureInfo ci)
        {
            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = ci;
#if LOG
            App.DebugPrint($"CurrentCulture set: {ci.Name}");
#endif
        }

        public static CultureInfo GetCurrentCultureInfo()
        {
            string lang;

#if __IOS__
            if (NSLocale.PreferredLanguages.Length > 0)
            {
                var pref = NSLocale.PreferredLanguages[0];
                lang = iOSToDotnetLanguage(pref);
            }
            else
            {
                lang = "zh-CN";
            }
#elif __ANDROID__
            var locale = Java.Util.Locale.Default;
            lang = AndroidToDotnetLanguage(locale.ToString().Replace('_', '-'));
#endif

            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;
        }

#if __IOS__
        [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
        private static 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;
            }

#if DEBUG
            App.DebugPrint($"iOS Language: {iOSLanguage}, .NET Language/Locale: {netLanguage}");
#endif
            return netLanguage;
        }
#elif __ANDROID__
        private static string AndroidToDotnetLanguage(string androidLanguage)
        {
            string netLanguage;

            //certain languages need to be converted to CultureInfo equivalent
            switch (androidLanguage)
            {
                case "ms-BN":   // "Malaysian (Brunei)" not supported .NET culture
                case "ms-MY":   // "Malaysian (Malaysia)" not supported .NET culture
                case "ms-SG":   // "Malaysian (Singapore)" not supported .NET culture
                    netLanguage = "ms"; // closest supported
                    break;
                case "in-ID":  // "Indonesian (Indonesia)" has different code in  .NET 
                    netLanguage = "id-ID"; // correct code for .NET
                    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 = androidLanguage;
                    break;
            }
#if DEBUG
            App.DebugPrint($"Android Language: {androidLanguage}, .NET Language/Locale: {netLanguage}");
#endif
            return netLanguage;
        }
#endif

        private static 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;
            }

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

        #endregion
    }
}
