using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using UnityEngine;

namespace TracyProfiler
{
    /// <summary>
    /// Tracy 性能分析器的 Unity 封装
    /// 提供简单易用的 C# API 来使用 Tracy 性能分析功能
    /// </summary>
    public static class Tracy
    {
#if UNITY_IOS && !UNITY_EDITOR
        private const string DLL_NAME = "__Internal";
#else
        private const string DLL_NAME = "UnityTracyPlugin";
#endif

        #region Native Methods

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracyInit();

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracyShutdown();

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracyFrameMark();

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracyPlotValue(string name, double value);

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracySendMessage(string message);

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracySetThreadName(string name);

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracyZoneScopedBegin(string name, string function = "", string file = "",
                                                        int line = 0);

        [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
        private static extern void TracyZoneScopedEnd(string name);

        #endregion

        private static bool s_initialized = false;
        private static bool s_enabled = true;

        /// <summary>
        /// Tracy 是否已启用
        /// </summary>
        public static bool Enabled
        {
            get => s_enabled;
            set => s_enabled = value;
        }

        /// <summary>
        /// Tracy 是否已初始化
        /// </summary>
        public static bool IsInitialized => s_initialized;

        /// <summary>
        /// 初始化 Tracy
        /// </summary>
        public static void Initialize()
        {
            if (s_initialized) return;

            try
            {
#if TRACY_ENABLE
                TracyInit();
                s_initialized = true;
                Debug.Log("[Tracy] 性能分析器已初始化");
#else
                Debug.Log("[Tracy] 性能分析器已禁用（编译时未定义 TRACY_ENABLE）");
#endif
            }
            catch (DllNotFoundException e)
            {
                Debug.LogWarning($"[Tracy] 未找到 Tracy Plugin DLL: {e.Message}");
                s_enabled = false;
            }
            catch (Exception e)
            {
                Debug.LogError($"[Tracy] 初始化失败: {e.Message}");
                s_enabled = false;
            }
        }

        /// <summary>
        /// 关闭 Tracy
        /// </summary>
        public static void Shutdown()
        {
            if (!s_initialized) return;

            try
            {
                TracyShutdown();
                s_initialized = false;
                Debug.Log("[Tracy] 性能分析器已关闭");
            }
            catch (Exception e)
            {
                Debug.LogError($"[Tracy] 关闭失败: {e.Message}");
            }
        }

        /// <summary>
        /// 标记帧边界（通常在每帧末尾调用）
        /// </summary>
        [System.Diagnostics.Conditional("TRACY_ENABLE")]
        public static void MarkFrame()
        {
            if (!s_initialized || !s_enabled) return;
            TracyFrameMark();
        }

        /// <summary>
        /// 绘制数值（用于实时监控变量）
        /// </summary>
        [System.Diagnostics.Conditional("TRACY_ENABLE")]
        public static void Plot(string name, double value)
        {
            if (!s_initialized || !s_enabled) return;
            TracyPlotValue(name, value);
        }

        /// <summary>
        /// 绘制整数值
        /// </summary>
        [System.Diagnostics.Conditional("TRACY_ENABLE")]
        public static void Plot(string name, int value)
        {
            Plot(name, (double)value);
        }

        /// <summary>
        /// 绘制浮点数值
        /// </summary>
        [System.Diagnostics.Conditional("TRACY_ENABLE")]
        public static void Plot(string name, float value)
        {
            Plot(name, (double)value);
        }

        /// <summary>
        /// 发送消息到 Tracy
        /// </summary>
        [System.Diagnostics.Conditional("TRACY_ENABLE")]
        public static void Message(string message)
        {
            if (!s_initialized || !s_enabled) return;
            TracySendMessage(message);
        }

        /// <summary>
        /// 设置当前线程名称
        /// </summary>
        [System.Diagnostics.Conditional("TRACY_ENABLE")]
        public static void SetThreadName(string name)
        {
            if (!s_initialized || !s_enabled) return;
            TracySetThreadName(name);
        }

        /// <summary>
        /// Tracy Zone 的作用域包装器
        /// 使用 using 语句自动管理生命周期
        /// </summary>
        public struct ZoneScope : IDisposable
        {
            private bool isValid;
            private string zoneName;

            public ZoneScope(string name, string function = "", string file = "", int line = 0)
            {
                zoneName = name;
                isValid = s_initialized && s_enabled;
#if TRACY_ENABLE
                if (isValid)
                {
                    TracyZoneScopedBegin(name, function, file, line);
                }
#endif
            }

            public void Dispose()
            {
#if TRACY_ENABLE
                if (isValid && s_initialized && s_enabled)
                {
                    TracyZoneScopedEnd(zoneName);
                }
#endif
            }
        }

        /// <summary>
        /// 创建一个 Tracy Zone（性能追踪区域）
        /// 使用 using 语句确保自动结束
        /// </summary>
        /// <example>
        /// using (Tracy.Zone("MyFunction"))
        /// {
        ///     // 要追踪的代码
        /// }
        /// </example>
        public static ZoneScope Zone(string name,
                [CallerMemberName] string function = "",
                [CallerFilePath] string file = "",
                [CallerLineNumber] int line = 0)
        {
            return new ZoneScope(name, function, file, line);
        }
    }

    /// <summary>
    /// Tracy Zone 的属性标记版本
    /// 可以标记在方法上，自动追踪整个方法
    /// 注意：需要配合 AOP 或代码生成工具使用
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class TracyZoneAttribute : Attribute
    {
        public string Name { get; set; }

        public TracyZoneAttribute(string name = null)
        {
            Name = name;
        }
    }
}

