using System;
using UnityEngine;

public static class BasisDebug
{
    /// <summary>
    /// When true, all BasisDebug Log/LogWarning/LogError calls are suppressed.
    /// Wired to the DisableLogging setting from BasisSettingsDefaults.
    /// </summary>
    public static bool LoggingDisabled;

    public static LogTag? TagFilter;

    public static MessageType MinimumLevel = MessageType.Info;

    private static bool ShouldEmit(LogTag logTag, MessageType messageType)
    {
        if (LoggingDisabled) return false;
        if ((int)messageType < (int)MinimumLevel) return false;
        if (TagFilter.HasValue && TagFilter.Value != logTag) return false;
        return true;
    }

    [HideInCallstack]
    public static void LogError(string message, LogTag logTag = LogTag.System)
    {
        if (!ShouldEmit(logTag, MessageType.Error)) return;
        Debug.unityLogger.LogError("",FormatMessage(message, logTag, MessageType.Error));
    }
    [HideInCallstack]
    public static void LogError(string message, UnityEngine.Object Object, LogTag logTag = LogTag.System)
    {
        if (!ShouldEmit(logTag, MessageType.Error)) return;
        Debug.unityLogger.LogError("", FormatMessage(message, logTag, MessageType.Error), Object);
    }
    [HideInCallstack]
    public static void LogError(Exception message, LogTag logTag = LogTag.System)
    {
        if (!ShouldEmit(logTag, MessageType.Error)) return;
        Debug.unityLogger.LogError("", FormatMessage($"{message.Message} {message.StackTrace}", logTag, MessageType.Error));
    }
    [HideInCallstack]
    public static void LogWarning(string message, LogTag logTag = LogTag.System)
    {
        if (!ShouldEmit(logTag, MessageType.Warning)) return;
        LogInternal(message, logTag, MessageType.Warning);
    }
    [HideInCallstack]
    public static void Log(string message, LogTag logTag = LogTag.System)
    {
        if (!ShouldEmit(logTag, MessageType.Info)) return;
        LogInternal(message, logTag, MessageType.Info);
    }
    [HideInCallstack]
    public static void LogInternal(string message, LogTag logTag, MessageType messageType)
    {
        Debug.unityLogger.Log(FormatMessage(message, logTag, messageType));
    }
    [HideInCallstack]
    public static string FormatMessage(string message, LogTag logTag, MessageType messageType)
    {
        // Retrieve colors for the tag and message type
        string logTagColor = GetTagColor(logTag);
        string messageTypeColor = GetMessageTypeColor(messageType);

        // Format the message with proper syntax
        return $"<color=#242424>[<color={logTagColor}>{logTag}</color>]</color> <color={messageTypeColor}>{message}</color>";
    }
    [HideInCallstack]
    public static string GetTagColor(LogTag logTag)
    {
        return logTag switch
        {
            LogTag.System => "#9370DB",       // Medium Purple
            LogTag.Voice => "#FF69B4",        // Hot Pink
            LogTag.Networking => "#1E90FF",   // Dodger Blue
            LogTag.IK => "#32CD32",           // Lime Green
            LogTag.Core => "#FFD700",         // Gold
            LogTag.Event => "#FF4500",        // Orange Red
            LogTag.Device => "#00CED1",       // Dark Turquoise
            LogTag.Avatar => "#8B0000",       // Dark Red
            LogTag.Input => "#808000",        // Olive
            LogTag.Gizmo => "#FF6347",        // Tomato
            LogTag.Scene => "#4682B4",        // Steel Blue
            LogTag.Editor => "#4B0082",       // Indigo
            LogTag.Pickups => "#DAA520",      // Goldenrod
            LogTag.Camera => "#2E8B57",       // Sea Green
            LogTag.Mirror => "#708090",       // Slate Gray
            LogTag.Local => "#20B2AA",        // Light Sea Green
            LogTag.Remote => "#DC143C",       // Crimson
            LogTag.Video => "#00ffff",        // Cyan
            LogTag.Shims => "#FF00FF",        // Magenta
            LogTag.Props => "#FFB6C1",        // Light Pink
            LogTag.LocalNetwork => "#ff0055",
            _ => "#FFFFFF"                    // Default White
        };
    }
    [HideInCallstack]
    public static string GetMessageTypeColor(MessageType messageType)
    {
        return messageType switch
        {
            MessageType.Error => "#FF0000",    // Red for errors
            MessageType.Warning => "#FFA500", // Orange for warnings
            MessageType.Info => "#FFFFFF",    // Green for logs
            _ => "#FFFFFF"                    // Default White
        };
    }
    [HideInCallstack]
    public static string FormatLogMessage(LogTag logTag, MessageType messageType, string message)
    {
        string tagColor = GetTagColor(logTag);
        string messageTypeColor = GetMessageTypeColor(messageType);

        // Apply colors
        string formattedTag = $"<color=#808080>[{logTag}]</color>"; // Grey color for tag brackets
        string formattedMessage = $"<color={tagColor}>{message}</color>"; // Tag color for message text

        return $"{formattedTag} <color=#FFFFFF>{messageTypeColor}: {formattedMessage}</color>";
    }
    public enum LogTag
    {
        System,
        Voice,
        Networking,
        IK,
        Core,
        Event,
        Device,
        Avatar,
        Input,
        Gizmo,
        Scene,
        Editor,
        Pickups,
        Camera,
        Mirror,
        Local,
        Remote,
        Video,
        Shims,
        Props,
        LocalNetwork,
    }

    public enum MessageType
    {
        Info,
        Warning,
        Error
    }
}
