using System;
using Alibabacloud.Rum.Unity.Logs;
using Alibabacloud.Rum.Unity.Rum;
using UnityEngine;

namespace Alibabacloud.Rum.Unity
{
    public class AlibabacloudUnityLogHandler : ILogHandler
    {
        // private readonly DdLogger _logger;
        private readonly IAlibabacloudRum _rum;
        private ILogHandler _defaultLogHandler = null;
        private AlibabacloudOptions _options;
        
        public AlibabacloudUnityLogHandler(IAlibabacloudRum rum)
        {
            // _logger = logger;
            _rum = rum;
            _options = AlibabacloudSdk.Instance.Options;
        }
        public void Attach()
        {
            if (Debug.unityLogger.logHandler == this)
            {
                return;
            }

            _defaultLogHandler = Debug.unityLogger.logHandler;
            Debug.unityLogger.logHandler = this;
        }
        
        public void Detach()
        {
            if (Debug.unityLogger.logHandler != this)
            {
                return;
            }

            Debug.unityLogger.logHandler = _defaultLogHandler;
        }
        
        public void LogException(Exception exception, UnityEngine.Object context)
        {
            try
            {
                _rum.ReportException(exception);
            }
            catch(Exception)
            {
                // Silently ignore RUM reporting errors
            }
            finally
            {
                // Pass exception onto Unity
                _defaultLogHandler.LogException(exception, context);
            }
        }

        public void LogFormat(LogType logType, UnityEngine.Object context, string format, params object[] args)
        {
            // Check if structured logging is enabled and this log type should be captured
            if (_options.EnableStructuredLogging && ShouldCaptureLogType(logType))
            {
                // Format the log message
                string logContent = args != null && args.Length > 0 
                    ? string.Format(format, args) 
                    : format;

                // Don't forward internal logs
                if (logContent.Contains("ALIBABACLOUD")) // todo 先这样写死
                {
                    return;
                }
                
                // Get stack trace (only available for warnings and errors)
                string stackTrace = string.Empty;
                if (logType == LogType.Warning || logType == LogType.Error || logType == LogType.Exception)
                {
                    stackTrace = UnityEngine.StackTraceUtility.ExtractStackTrace();
                }
                
                // Map Unity LogType to string level
                string logLevel = MapLogTypeToLevel(logType);
                
                // Create extra info with context information
                var extraInfo = new System.Collections.Generic.Dictionary<string, object>();
                if (context != null)
                {
                    extraInfo["context"] = context.name;
                    extraInfo["contextType"] = context.GetType().Name;
                }
                extraInfo["platform"] = Application.platform.ToString();
                extraInfo["scene"] = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
                
                // Report log to RUM
                _rum.ReportLog(
                    logContent,
                    "Unity.Log",
                    logLevel,
                    stackTrace,
                    extraInfo);
            }
            
            // Always forward to default handler
            _defaultLogHandler.LogFormat(logType, context, format, args);
        }
        
        /// <summary>
        /// Determines if a log type should be captured based on options
        /// </summary>
        private bool ShouldCaptureLogType(LogType logType)
        {
            return logType switch
            {
                LogType.Log => _options.StructuredLogOnDebugLog,
                LogType.Warning => _options.StructuredLogOnDebugLogWarning,
                LogType.Error => _options.StructuredLogOnDebugLogError,
                LogType.Exception => _options.StructuredLogOnDebugLogException,
                LogType.Assert => _options.StructuredLogOnDebugLogAssertion,
                _ => false
            };
        }
        
        /// <summary>
        /// Maps Unity LogType to log level string
        /// </summary>
        private string MapLogTypeToLevel(LogType logType)
        {
            return logType switch
            {
                LogType.Log => "Info",
                LogType.Warning => "Warning",
                LogType.Error => "Error",
                LogType.Exception => "Error",
                LogType.Assert => "Error",
                _ => "Info"
            };
        }
    }
}