﻿using System;
using BugseePlugin.Appearance;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace BugseePlugin.Internals
{
    internal sealed class AppearancePropertiesManager
    {
        internal AppearancePropertiesManager()
        {
        }

        internal static AppearanceValue GetOrSetProperty(BugseeAppearanceProperties prop, AppearanceValue value)
        {
            return GetOrSetPropertyPlatform(prop, value);
        }

        private static IBugseeColor HexToColor(string hex)
        {
            hex = hex.Replace("#", string.Empty);
            byte a = (byte)(Convert.ToUInt32(hex.Substring(0, 2), 16));
            byte r = (byte)(Convert.ToUInt32(hex.Substring(2, 2), 16));
            byte g = (byte)(Convert.ToUInt32(hex.Substring(4, 2), 16));
            byte b = (byte)(Convert.ToUInt32(hex.Substring(6, 2), 16));
            return BugseeColor.FromArgb(a, r, g, b);
        }

#if UNITY_IPHONE && !UNITY_EDITOR
        [DllImport("__Internal")]
        private static extern void bugsee_setAppearanceProperty_String(string pName, string pValue);

        [DllImport("__Internal")]
        private static extern void bugsee_setAppearanceProperty_Color(string pName, short r, short g, short b, short a);

        [DllImport("__Internal")]
        private static extern IntPtr bugsee_getAppearanceProperty_String(string pName);

        [DllImport("__Internal")]
        private static extern IntPtr bugsee_getAppearanceProperty_Color(string pName);


        private static AppearanceValue GetOrSetPropertyPlatform(BugseeAppearanceProperties prop, AppearanceValue value)
        {
            bool isSetOperation = value != null;
            IBugseeColor colorToGet = BugseeColor.Empty;
            IntPtr returnValue = IntPtr.Zero;
            String stringToGet = null;

            string propertyName = Enum.GetName(typeof(BugseeAppearanceProperties), prop);
            propertyName = propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);

            switch (prop)
            {
                case BugseeAppearanceProperties.ReportSummaryPlaceholder:
                case BugseeAppearanceProperties.ReportDescriptionPlaceholder:
                case BugseeAppearanceProperties.ReportLabelsPlaceholder:
                case BugseeAppearanceProperties.ReportEmailPlaceholder:
                    // string props
                    if (isSetOperation)
                        bugsee_setAppearanceProperty_String(propertyName, value.String);
                    else
                    {
                        returnValue = bugsee_getAppearanceProperty_String(propertyName);
                        stringToGet = Marshal.PtrToStringAuto(returnValue);
                    }
                    break;

                case BugseeAppearanceProperties.ReportVersionColor:
                case BugseeAppearanceProperties.ReportTextColor:
                case BugseeAppearanceProperties.ReportBackgroundColor:
                case BugseeAppearanceProperties.FeedbackBackgroundColor:
                case BugseeAppearanceProperties.FeedbackIncomingBubbleColor:
                case BugseeAppearanceProperties.FeedbackOutgoingBubbleColor:
                case BugseeAppearanceProperties.FeedbackIncomingTextColor:
                case BugseeAppearanceProperties.FeedbackOutgoingTextColor:
                case BugseeAppearanceProperties.FeedbackTitleTextColor:
                case BugseeAppearanceProperties.FeedbackEmailBackgroundColor:
                case BugseeAppearanceProperties.FeedbackEmailContinueNotActiveColor:
                case BugseeAppearanceProperties.FeedbackEmailContinueActiveColor:
                case BugseeAppearanceProperties.FeedbackInputTextColor:
                case BugseeAppearanceProperties.ReportCellBackgroundColor:
                case BugseeAppearanceProperties.ReportSendButtonColor:
                case BugseeAppearanceProperties.ReportPlaceholderColor:
                case BugseeAppearanceProperties.ReportNavigationBarColor:
                case BugseeAppearanceProperties.ReportCloseButtonColor:
                case BugseeAppearanceProperties.FeedbackBarsColor:
                case BugseeAppearanceProperties.FeedbackEmailSkipColor:
                case BugseeAppearanceProperties.FeedbackCloseButtonColor:
                case BugseeAppearanceProperties.FeedbackNavigationBarColor:
                    // color props
                    if (isSetOperation)
                        bugsee_setAppearanceProperty_Color(propertyName, value.Color.R, value.Color.G, value.Color.B, value.Color.A);
                    else
                    {
                        returnValue = bugsee_getAppearanceProperty_Color(propertyName);
                        if (returnValue != IntPtr.Zero)
                        {
                            var hexString = Marshal.PtrToStringAuto(returnValue);
                            if (!string.IsNullOrEmpty(hexString))
                            {
                                colorToGet = HexToColor(hexString);
                            }
                        }
                    }

                    break;

                default:
                    // Other props are no-op
                    break;
            }

            return AppearanceValue.Create(colorToGet, stringToGet);
        }
#elif UNITY_ANDROID && !UNITY_EDITOR
        private static UnityEngine.AndroidJavaObject appearanceObj;

        private static UnityEngine.AndroidJavaObject ToAndroidInteger(int? value)
        {
            UnityEngine.AndroidJavaObject integer = null;

            if (value.HasValue)
            {
                using (UnityEngine.AndroidJavaClass integerClass = new UnityEngine.AndroidJavaClass("java.lang.Integer"))
                {
                    integer = integerClass.CallStatic<UnityEngine.AndroidJavaObject>("valueOf", value);
                }
            }

            return integer;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        private static void InitializeGlueLayerAndroid()
        {
            if (appearanceObj == null)
            {
                UnityEngine.AndroidJavaClass bugseeClass = new UnityEngine.AndroidJavaClass("com.bugsee.library.BugseeUnityAdapter");
                appearanceObj = bugseeClass.CallStatic<UnityEngine.AndroidJavaObject>("getAppearance");
            }
        }

        private static AppearanceValue GetOrSetPropertyPlatform(BugseeAppearanceProperties prop, AppearanceValue value)
        {
            InitializeGlueLayerAndroid();

            bool isSetOperation = value != null;
            IBugseeColor colorToGet = BugseeColor.Empty;
            String stringToGet = null;

            if (appearanceObj != null)
            {
                string propertyName = Enum.GetName(typeof(BugseeAppearanceProperties), prop);

                switch (prop)
                {
                    case BugseeAppearanceProperties.ReportSummaryPlaceholder:
                    case BugseeAppearanceProperties.ReportDescriptionPlaceholder:
                    case BugseeAppearanceProperties.ReportLabelsPlaceholder:
                    case BugseeAppearanceProperties.ReportEmailPlaceholder:
                        // string props
                        if (isSetOperation)
                            appearanceObj.Set<string>(propertyName, value.String);
                        else
                            stringToGet = appearanceObj.Get<string>(propertyName);
                            break;

                    case BugseeAppearanceProperties.ReportVersionColor:
                    case BugseeAppearanceProperties.ReportTextColor:
                    case BugseeAppearanceProperties.ReportBackgroundColor:
                    case BugseeAppearanceProperties.ReportActionBarColor:
                    case BugseeAppearanceProperties.ReportActionBarTextColor:
                    case BugseeAppearanceProperties.ReportActionBarButtonBackgroundClickedColor:
                    case BugseeAppearanceProperties.ReportEditTextBackgroundColor:
                    case BugseeAppearanceProperties.ReportHintColor:
                    case BugseeAppearanceProperties.ReportSeverityLabelActiveColor:
                    case BugseeAppearanceProperties.FeedbackBackgroundColor:
                    case BugseeAppearanceProperties.FeedbackIncomingBubbleColor:
                    case BugseeAppearanceProperties.FeedbackOutgoingBubbleColor:
                    case BugseeAppearanceProperties.FeedbackIncomingTextColor:
                    case BugseeAppearanceProperties.FeedbackOutgoingTextColor:
                    case BugseeAppearanceProperties.FeedbackTitleTextColor:
                    case BugseeAppearanceProperties.FeedbackEmailBackgroundColor:
                    case BugseeAppearanceProperties.FeedbackEmailContinueNotActiveColor:
                    case BugseeAppearanceProperties.FeedbackEmailContinueActiveColor:
                    case BugseeAppearanceProperties.FeedbackInputTextColor:
                    case BugseeAppearanceProperties.FeedbackActionBarColor:
                    case BugseeAppearanceProperties.FeedbackActionBarButtonBackgroundClickedColor:
                    case BugseeAppearanceProperties.FeedbackDateTextColor:
                    case BugseeAppearanceProperties.FeedbackEmailSkipTextColor:
                    case BugseeAppearanceProperties.FeedbackEmailSkipBackgroundClickedColor:
                    case BugseeAppearanceProperties.FeedbackEmailContinueClickedColor:
                    case BugseeAppearanceProperties.FeedbackInputTextHintColor:
                    case BugseeAppearanceProperties.FeedbackBottomDelimiterColor:
                    case BugseeAppearanceProperties.FeedbackLoadingBarBackgroundColor:
                    case BugseeAppearanceProperties.FeedbackLoadingTextColor:
                    case BugseeAppearanceProperties.FeedbackErrorTextColor:
                    case BugseeAppearanceProperties.FeedbackVersionChangedBackgroundColor:
                    case BugseeAppearanceProperties.FeedbackVersionChangedTextColor:
                        // color props
                        if (isSetOperation)
                        {
                            appearanceObj.Set<UnityEngine.AndroidJavaObject>(propertyName, ToAndroidInteger(value.Color.ToArgb()));
                        }
                        else
                        {
                            UnityEngine.AndroidJavaObject argbObj = appearanceObj.Get<UnityEngine.AndroidJavaObject>(propertyName);
                            if (argbObj != null)
                            {
                                int argb = argbObj.Call<int>("intValue");
                                colorToGet = BugseeColor.FromArgb(argb);
                            }
                        }

                        break;

                    default:
                        // Other props are no-op
                        break;
                }
            }

            return AppearanceValue.Create(colorToGet, stringToGet);
        }
#else
        private static AppearanceValue GetOrSetPropertyPlatform(BugseeAppearanceProperties prop, AppearanceValue value)
        {
            return AppearanceValue.Create(BugseeColor.Empty, "");
        }
#endif
    }
}
