#if UNITY_STANDALONE || UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using _Combo;
using _Core;
using Sentry;
using UnityEngine.Scripting;

namespace Combo.Core
{
    [Preserve]
    public class SentryTracking : Singleton<SentryTracking>, IErrorTracking
    {
        public SentryTracking() { }

        public void Setup()
        {
        }

        public void SetTags(Dictionary<string, string> tagMap)
        {
            foreach(KeyValuePair<string,string> pair in tagMap)
            {
                SentrySdk.ConfigureScope(scope =>
                {
                    scope.SetTag(pair.Key, pair.Value);
                });
            }
            
        }
        public void SetUser(string id, Dictionary<string, string> extra = null)
        {
            var user = new SentryUser();
            SentrySdk.ConfigureScope(scope =>
            {
                user.Id = id;
                user.Other = extra;
                scope.User = user;
            });
        }

        public void SetBreadcrumbs(List<EventBreadcrumb> breadcrumbs)
        {
            foreach (var breadcrumb in breadcrumbs)
            {
                SentrySdk.AddBreadcrumb(breadcrumb.Message, breadcrumb.Category, data: breadcrumb.Extra, level: breadcrumb.Level);
            }
            
        }

        public void SetContexts(Dictionary<string, object> contextMap)
        {
            foreach (KeyValuePair<string, object> pair in contextMap)
            {
                SentrySdk.ConfigureScope(scope => {
                    scope.Contexts[pair.Key] = pair.Value;
                });
            }
            
        }

        public void SetExtra(Dictionary<string, string> extra)
        {
            foreach (KeyValuePair<string, string> pair in extra)
            {
                SentrySdk.ConfigureScope(scope => {
                    scope.SetExtra(pair.Key, pair.Value);
                });
            }
        }

        public void SetFingerprint(List<string> fingerprint)
        {
            SentrySdk.ConfigureScope(scope => {
                scope.SetFingerprint(fingerprint);
            });
        }

        public void CaptureMessage(string message, SentryLevel eventLevel, EventScope eventScope = null)
        {
            if(eventScope == null)
            {
                SentrySdk.CaptureMessage(message, eventLevel);
            }
            else
            {
                SentrySdk.CaptureMessage(message, scope => {
                    ConfigureScope(scope,
                        eventScope.ContextMap,
                        eventScope.TagMap,
                        eventScope.Breadcrumbs,
                        eventScope.Attachments,
                        eventScope.Extra,
                        eventScope.Fingerprint
                    );
                }, eventLevel);
            }
            
        }

        public void CaptureException(Exception exception, EventScope eventScope = null)
        {
            if(eventScope == null)
            {
                SentrySdk.CaptureException(exception);
            }
            else
            {
                SentrySdk.CaptureException(exception, scope => {
                    ConfigureScope(scope,
                        eventScope.ContextMap,
                        eventScope.TagMap,
                        eventScope.Breadcrumbs,
                        eventScope.Attachments,
                        eventScope.Extra,
                        eventScope.Fingerprint
                    );
                });
            }
            
        }

        private void ConfigureScope(Scope scope,
            Dictionary<string, object> contextDic = null,
            Dictionary<string, object> tagDic = null,
            List<EventBreadcrumb> breadcrumbs = null,
            List<string> attachments = null,
            Dictionary<string, string> extra = null,
            List<string> fingerprint = null
        ) {
            if(contextDic != null)
            {
                foreach (KeyValuePair<string, object> pair in contextDic)
                {
                    scope.Contexts[pair.Key] = pair.Value;
                }
            }

            if(tagDic != null)
            {
                foreach (KeyValuePair<string, object> pair in tagDic)
                {
                    scope.SetTag(pair.Key, pair.Value.ToString());
                }
            }

            if(breadcrumbs != null)
            {
                foreach(var breadcrumb in breadcrumbs)
                {
                    scope.AddBreadcrumb(new Breadcrumb(breadcrumb.Message, breadcrumb.Category, breadcrumb.Extra, level: breadcrumb.Level));
                }
            }

            if(attachments != null)
            {
                foreach(var filePath in attachments)
                {
                    if(File.Exists(filePath))
                    {
                        scope.AddAttachment(filePath);
                    }
                }
            }

            if(extra != null)
            {
                foreach (KeyValuePair<string, string> pair in extra)
                {
                    scope.SetExtra(pair.Key, pair.Value);
                }
            }

            if(fingerprint != null)
            {
                scope.SetFingerprint(fingerprint);
            }
        }
    }
}
#endif