using Sentry.Unity;
using Newtonsoft.Json;
using Sentry;
using Combo.Platform;
using System.Collections.Generic;
using System;

namespace Combo.Core
{
    public class SentryManager : SentryRuntimeOptionsConfiguration
    {
        /// Called at the player startup by SentryInitialization.
        /// You can alter configuration for the C# error handling and also
        /// native error handling in platforms **other** than iOS, macOS and Android.
        /// Learn more at https://docs.sentry.io/platforms/unity/configuration/options/#programmatic-configuration
        [System.Serializable]
        internal class Parameters
        {
#if UNITY_ANDROID
            [JsonProperty("sentry_android_dsn")]
#elif UNITY_IOS
            [JsonProperty("sentry_ios_dsn")]
#elif UNITY_STANDALONE
            [JsonProperty("sentry_windows_dsn")]
#elif UNITY_WEBGL
            [JsonProperty("sentry_webgl_dsn")]
#elif UNITY_OPENHARMONY
            [JsonProperty("sentry_harmonyos_dsn")]
#endif
            public string dsn;

            [JsonProperty("sentry_unity_enabled")]
            [JsonConverter(typeof(EmptyStringToBoolConverter))]
            public bool enabled = true;

            [JsonProperty("sentry_unity_debug_enabled")]
            [JsonConverter(typeof(EmptyStringToBoolConverter))]
            public bool debugEnabled = false;

            [JsonProperty("sentry_unity_send_default_pii_enabled")]
            [JsonConverter(typeof(EmptyStringToBoolConverter))]
            public bool sendDefaultPiiEnabled = true;
            [JsonProperty("sentry_unity_attach_screenshot_enabled")]
            public bool attachScreenShotEnabled = false;
            [JsonProperty("sentry_unity_max_breadcrumbs")]
            public int maxBreadcrumbs = 100;

            [JsonProperty("sentry_unity_add_breadcrumb_log_types")]
            public string addBreadcrumbsForLogTypes;

            [JsonProperty("sentry_unity_capture_logging_error_enabled")]
            public bool captureLoggingErrorEnabled = false;
        }

        public override void Configure(SentryUnityOptions options)
        {
#if UNITY_EDITOR
            options.Enabled = false;
            return;
#else
            var parameters = Native.GetParameters<Parameters>();
#if UNITY_ANDROID
            options.AndroidNativeSupportEnabled = true;
            options.NdkIntegrationEnabled = true;
            options.NdkScopeSyncEnabled = true;
#elif UNITY_IOS
            options.IosNativeSupportEnabled = true;
#elif UNITY_STANDALONE
            options.WindowsNativeSupportEnabled = true;
#endif

            if (string.IsNullOrEmpty(parameters.dsn))
            {
                Log.E("The sentry dsn must be is not empty!");
                return;
            }
            Log.I($"Start sentry, dsn = {parameters.dsn}");
            options.Enabled = parameters.enabled;
            options.Debug = parameters.debugEnabled;
            options.AttachScreenshot = false;
            options.AttachStacktrace = true;
            options.SendDefaultPii = parameters.sendDefaultPiiEnabled;
            options.Dsn = parameters.dsn;
            options.AttachScreenshot = parameters.attachScreenShotEnabled;
            options.MaxBreadcrumbs = parameters.maxBreadcrumbs;
            if (!parameters.captureLoggingErrorEnabled)
            {
                options.DisableUnityApplicationLoggingIntegration();
            }
            options.AddBreadcrumbsForLogType = GetBreadcrumbsForLogType(parameters.addBreadcrumbsForLogTypes);
            options.DisableAnrIntegration();

#endif
        }

        internal static Dictionary<UnityEngine.LogType, bool> GetBreadcrumbsForLogType(string logTypesCsv)
        {
            Dictionary<UnityEngine.LogType, bool> result = new Dictionary<UnityEngine.LogType, bool>
            {
                { UnityEngine.LogType.Log, false },
                { UnityEngine.LogType.Warning, false },
                { UnityEngine.LogType.Assert, false },
                { UnityEngine.LogType.Error, false },
                { UnityEngine.LogType.Exception, false }
            };

            if (string.IsNullOrEmpty(logTypesCsv))
            {
                return result;
            }

            string[] logTypes = logTypesCsv.Split(',');
            foreach (string type in logTypes)
            {
                if (Enum.TryParse(type.Trim(), out UnityEngine.LogType logType))
                {
                    result[logType] = true;
                }
            }

            return result;
        }

        internal static void Setup()
        {
#if !UNITY_EDITOR
            // TODO: Add more
            SentrySdk.ConfigureScope(scope =>
            {
                var variant = Native.GetVariant();
                if (!string.IsNullOrEmpty(variant))
                {
                    scope.SetTag("combo.variant", variant);
                }

                var subvariant = Native.GetSubvariant();
                if (!string.IsNullOrEmpty(subvariant))
                {
                    scope.SetTag("combo.subvariant", subvariant);
                }
                scope.SetTag("combo.device_id", Native.GetDeviceId());
                scope.SetTag("combo.distro", Native.GetDistro());
                scope.SetTag("combo.sdk.unity_version", Version.SDKVersion);
            });
#endif
        }
    }
}
