using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Timers;
using Decal.Adapter;
using Decal.Adapter.Wrappers;
using MosswartMassacre.Views;
using Mag.Shared.Constants;

namespace MosswartMassacre
{
    [FriendlyName("Mosswart Massacre")]
    public class PluginCore : PluginBase
    {
        internal static PluginHost MyHost;
        internal static int totalKills = 0;
        internal static int rareCount = 0;
        internal static int sessionDeaths = 0;  // Deaths this session
        internal static int totalDeaths = 0;    // Total deaths from character
        internal static DateTime lastKillTime = DateTime.Now;
        internal static double killsPer5Min = 0;
        internal static double killsPerHour = 0;
        internal static DateTime statsStartTime = DateTime.Now;
        internal static Timer updateTimer;
        public static bool RareMetaEnabled { get; set; } = true;

        // VVS View Management
        private static class ViewManager
        {
            public static void ViewInit()
            {
                Views.VVSTabbedMainView.ViewInit();
            }

            public static void ViewDestroy()
            {
                Views.VVSTabbedMainView.ViewDestroy();
            }

            public static void UpdateKillStats(int totalKills, double killsPer5Min, double killsPerHour)
            {
                Views.VVSTabbedMainView.UpdateKillStats(totalKills, killsPer5Min, killsPerHour);
            }

            public static void UpdateElapsedTime(TimeSpan elapsed)
            {
                Views.VVSTabbedMainView.UpdateElapsedTime(elapsed);
            }

            public static void UpdateRareCount(int rareCount)
            {
                Views.VVSTabbedMainView.UpdateRareCount(rareCount);
            }

            public static void SetRareMetaToggleState(bool enabled)
            {
                Views.VVSTabbedMainView.SetRareMetaToggleState(enabled);
            }

            public static void RefreshSettingsFromConfig()
            {
                Views.VVSTabbedMainView.RefreshSettingsFromConfig();
            }
        }
        public static bool RemoteCommandsEnabled { get; set; } = false;
        public static bool HttpServerEnabled { get; set; } = false;
        public static string CharTag { get; set; } = "";
        public static bool TelemetryEnabled { get; set; } = false;
        public static bool WebSocketEnabled { get; set; } = false;
        public bool InventoryLogEnabled { get; set; } = false;
        public static bool AggressiveChatStreamingEnabled { get; set; } = true;
        private MossyInventory _inventoryLogger;
        public static NavVisualization navVisualization;

        private static Queue<string> rareMessageQueue = new Queue<string>();
        private static DateTime _lastSent = DateTime.MinValue;
        private static readonly Queue<string> _chatQueue = new Queue<string>();

        protected override void Startup()
        {
            try
            {
                MyHost = Host;
                

                // Note: Startup messages will appear after character login
                // Subscribe to chat message event
                CoreManager.Current.ChatBoxMessage += new EventHandler<ChatTextInterceptEventArgs>(OnChatText);
                CoreManager.Current.ChatBoxMessage += new EventHandler<ChatTextInterceptEventArgs>(AllChatText);
                CoreManager.Current.CommandLineText += OnChatCommand;
                CoreManager.Current.CharacterFilter.LoginComplete += CharacterFilter_LoginComplete;
                CoreManager.Current.CharacterFilter.Death += OnCharacterDeath;
                CoreManager.Current.WorldFilter.CreateObject += OnSpawn;
                CoreManager.Current.WorldFilter.ReleaseObject += OnDespawn;
                // Initialize VVS view after character login
                ViewManager.ViewInit();

                // Initialize the timer
                updateTimer = new Timer(1000); // Update every second
                updateTimer.Elapsed += UpdateStats;
                updateTimer.Start();

                // Note: View initialization moved to LoginComplete for VVS compatibility

                // Enable TLS1.2
                ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
                //Enable vTank interface
                vTank.Enable();
                //lyssna på commands
                WebSocket.OnServerCommand += HandleServerCommand;
                //starta inventory. Hanterar subscriptions  i den med

                _inventoryLogger = new MossyInventory();

                // Initialize navigation visualization system
                navVisualization = new NavVisualization();

                // Note: DECAL Harmony patches will be initialized in LoginComplete event
                // where the chat system is available for error messages

            }
            catch (Exception ex)
            {
                WriteToChat("Error during startup: " + ex.Message);
            }
        }

        protected override void Shutdown()
        {
            try
            {
                PluginSettings.Save();
                if (TelemetryEnabled)
                    Telemetry.Stop();   // ensure no dangling timer / HttpClient
                WriteToChat("Mosswart Massacre is shutting down...");

                // Unsubscribe from chat message event
                CoreManager.Current.ChatBoxMessage -= new EventHandler<ChatTextInterceptEventArgs>(OnChatText);
                CoreManager.Current.CommandLineText -= OnChatCommand;
                CoreManager.Current.ChatBoxMessage -= new EventHandler<ChatTextInterceptEventArgs>(AllChatText);
                CoreManager.Current.CharacterFilter.Death -= OnCharacterDeath;
                CoreManager.Current.WorldFilter.CreateObject -= OnSpawn;
                CoreManager.Current.WorldFilter.ReleaseObject -= OnDespawn;
              

                // Stop and dispose of the timer
                if (updateTimer != null)
                {
                    updateTimer.Stop();
                    updateTimer.Dispose();
                    updateTimer = null;
                }

                // Clean up the view
                ViewManager.ViewDestroy();
                //Disable vtank interface
                vTank.Disable();
                // sluta lyssna på commands
                WebSocket.OnServerCommand -= HandleServerCommand;
                WebSocket.Stop();
                //shutdown inv
                _inventoryLogger.Dispose();

                // Clean up navigation visualization
                if (navVisualization != null)
                {
                    navVisualization.Dispose();
                    navVisualization = null;
                }

                // Clean up Harmony patches
                DecalHarmonyClean.Cleanup();

                MyHost = null;
            }
            catch (Exception ex)
            {
                WriteToChat("Error during shutdown: " + ex.Message);
            }
        }
        private void CharacterFilter_LoginComplete(object sender, EventArgs e)
        {
            CoreManager.Current.CharacterFilter.LoginComplete -= CharacterFilter_LoginComplete;

            WriteToChat("Mosswart Massacre has started!");



            PluginSettings.Initialize(); // Safe to call now

            // Apply the values
            RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
            WebSocketEnabled = PluginSettings.Instance.WebSocketEnabled;
            RemoteCommandsEnabled = PluginSettings.Instance.RemoteCommandsEnabled;
            HttpServerEnabled = PluginSettings.Instance.HttpServerEnabled;
            TelemetryEnabled = PluginSettings.Instance.TelemetryEnabled;
            CharTag = PluginSettings.Instance.CharTag;
            ViewManager.SetRareMetaToggleState(RareMetaEnabled);
            ViewManager.RefreshSettingsFromConfig(); // Refresh all UI settings after loading
            if (TelemetryEnabled)
                Telemetry.Start();
            if (WebSocketEnabled)
                WebSocket.Start();

            // Initialize Harmony patches using UtilityBelt's loaded DLL
            try
            {
                bool success = DecalHarmonyClean.Initialize();
                if (success)
                    WriteToChat("[OK] Plugin message interception active");
                else
                    WriteToChat("[FAIL] Could not initialize message interception");
            }
            catch (Exception ex)
            {
                WriteToChat($"[ERROR] Harmony initialization failed: {ex.Message}");
            }

            // Initialize death tracking
            totalDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
            sessionDeaths = 0;

        }


        private async void OnSpawn(object sender, CreateObjectEventArgs e)
        {
            var mob = e.New;
            if (mob.ObjectClass != ObjectClass.Monster) return;

            try
            {
                var coords = mob.Coordinates();
                const string fmt = "F7";
                string ns = coords.NorthSouth.ToString(fmt, CultureInfo.InvariantCulture);
                string ew = coords.EastWest.ToString(fmt, CultureInfo.InvariantCulture);

                await WebSocket.SendSpawnAsync(ns, ew, mob.Name);
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[WS] Spawn send failed: {ex}");
            }
        }

 
        private void OnDespawn(object sender, ReleaseObjectEventArgs e)
        {
            var mob = e.Released;
            if (mob.ObjectClass != ObjectClass.Monster) return;

        
            // var c = mob.Coordinates();
            // PluginCore.WriteToChat(
            //     $"[Despawn] {mob.Name} @ (NS={c.NorthSouth:F1}, EW={c.EastWest:F1})");
        }

        private async void AllChatText(object sender, ChatTextInterceptEventArgs e)
        {
            try
            {
                string cleaned = NormalizeChatLine(e.Text);
                
                // Send to WebSocket
                await WebSocket.SendChatTextAsync(e.Color, cleaned);
                
                // Note: Plugin message analysis is now handled by Harmony patches
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[WS] Chat send failed: {ex}");
            }
        }

        private static string NormalizeChatLine(string raw)
        {
            if (string.IsNullOrEmpty(raw))
                return raw;

            // 1) Remove all <…> tags
            var noTags = Regex.Replace(raw, "<[^>]+>", "");

            // 2) Trim trailing newline or carriage-return
            var trimmed = noTags.TrimEnd('\r', '\n');

            // 3) Collapse multiple spaces into one
            var collapsed = Regex.Replace(trimmed, @"[ ]{2,}", " ");

            return collapsed;
        }

        private void OnCharacterDeath(object sender, Decal.Adapter.Wrappers.DeathEventArgs e)
        {
            sessionDeaths++;
            totalDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
        }

        private void HandleServerCommand(CommandEnvelope env)
        {
            // Skicka commands
            DispatchChatToBoxWithPluginIntercept(env.Command);
            CoreManager.Current.Actions.InvokeChatParser($"/a Executed '{env.Command}' from Mosswart Overlord");
        }
        private void OnChatText(object sender, ChatTextInterceptEventArgs e)
        {
            try
            {
                // WriteToChat($"[Debug] Chat Color: {e.Color}, Message: {e.Text}");

                if (IsKilledByMeMessage(e.Text))
                {
                    totalKills++;
                    lastKillTime = DateTime.Now;
                    CalculateKillsPerInterval();
                    ViewManager.UpdateKillStats(totalKills, killsPer5Min, killsPerHour);
                }

                if (IsRareDiscoveryMessage(e.Text, out string rareText))
                {
                    rareCount++;
                    ViewManager.UpdateRareCount(rareCount);

                    if (RareMetaEnabled)
                    {
                        Decal_DispatchOnChatCommand("/vt setmetastate loot_rare");
                    }
                    
                    DelayedCommandManager.AddDelayedCommand($"/a {rareText}", 3000);
                    // Fire and forget: we don't await, since sending is not critical and we don't want to block.
                    _ = WebSocket.SendRareAsync(rareText);
                }

                if (e.Color == 18 && e.Text.EndsWith("!report\""))
                {
                    TimeSpan elapsed = DateTime.Now - statsStartTime;
                    string reportMessage = $"Total Kills: {totalKills}, Kills per Hour: {killsPerHour:F2}, Elapsed Time: {elapsed:dd\\.hh\\:mm\\:ss}, Rares Found: {rareCount}";
                    WriteToChat($"[Mosswart Massacre] Reporting to allegiance: {reportMessage}");
                    MyHost.Actions.InvokeChatParser($"/a {reportMessage}");
                }
                if (RemoteCommandsEnabled && e.Color == 18)
                {
                    string characterName = Regex.Escape(CoreManager.Current.CharacterFilter.Name);
                    string pattern = $@"^\[Allegiance\].*Dunking Rares.*say[s]?, \""!do {characterName} (?<command>.+)\""$";
                    string tag = Regex.Escape(PluginCore.CharTag);
                    string patterntag = $@"^\[Allegiance\].*Dunking Rares.*say[s]?, \""!dot {tag} (?<command>.+)\""$";


                    var match = Regex.Match(e.Text, pattern);
                    var matchtag = Regex.Match(e.Text, patterntag);

                    if (match.Success)
                    {
                        string command = match.Groups["command"].Value;
                        DispatchChatToBoxWithPluginIntercept(command);
                        DelayedCommandManager.AddDelayedCommand($"/a [Remote] Executing: {command}", 2000);
                    }
                    else if (matchtag.Success)
                    {
                        string command = matchtag.Groups["command"].Value;
                        DispatchChatToBoxWithPluginIntercept(command);
                        DelayedCommandManager.AddDelayedCommand($"/a [Remote] Executing: {command}", 2000);
                    }

                }








            }
            catch (Exception ex)
            {
                WriteToChat("Error processing chat message: " + ex.Message);
            }
        }
        private void OnChatCommand(object sender, ChatParserInterceptEventArgs e)
        {
            try
            {
                if (e.Text.StartsWith("/mm", StringComparison.OrdinalIgnoreCase))
                {
                    e.Eat = true; // Prevent the message from showing in chat
                    HandleMmCommand(e.Text);
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Error] Failed to process /mm command: {ex.Message}");
            }
        }

        private void UpdateStats(object sender, ElapsedEventArgs e)
        {
            try
            {
                // Update the elapsed time
                TimeSpan elapsed = DateTime.Now - statsStartTime;
                ViewManager.UpdateElapsedTime(elapsed);

                // Recalculate kill rates
                CalculateKillsPerInterval();
                ViewManager.UpdateKillStats(totalKills, killsPer5Min, killsPerHour);

            }
            catch (Exception ex)
            {
                WriteToChat("Error updating stats: " + ex.Message);
            }
        }

        private void CalculateKillsPerInterval()
        {
            double minutesElapsed = (DateTime.Now - statsStartTime).TotalMinutes;

            if (minutesElapsed > 0)
            {
                killsPer5Min = (totalKills / minutesElapsed) * 5;
                killsPerHour = (totalKills / minutesElapsed) * 60;
            }
        }

        private bool IsKilledByMeMessage(string text)
        {
            string[] killPatterns = new string[]
            {
                @"^You flatten (?<targetname>.+)'s body with the force of your assault!$",
                @"^You bring (?<targetname>.+) to a fiery end!$",
                @"^You beat (?<targetname>.+) to a lifeless pulp!$",
                @"^You smite (?<targetname>.+) mightily!$",
                @"^You obliterate (?<targetname>.+)!$",
                @"^You run (?<targetname>.+) through!$",
                @"^You reduce (?<targetname>.+) to a sizzling, oozing mass!$",
                @"^You knock (?<targetname>.+) into next Morningthaw!$",
                @"^You split (?<targetname>.+) apart!$",
                @"^You cleave (?<targetname>.+) in twain!$",
                @"^You slay (?<targetname>.+) viciously enough to impart death several times over!$",
                @"^You reduce (?<targetname>.+) to a drained, twisted corpse!$",
                @"^Your killing blow nearly turns (?<targetname>.+) inside-out!$",
                @"^Your attack stops (?<targetname>.+) cold!$",
                @"^Your lightning coruscates over (?<targetname>.+)'s mortal remains!$",
                @"^Your assault sends (?<targetname>.+) to an icy death!$",
                @"^You killed (?<targetname>.+)!$",
                @"^The thunder of crushing (?<targetname>.+) is followed by the deafening silence of death!$",
                @"^The deadly force of your attack is so strong that (?<targetname>.+)'s ancestors feel it!$",
                @"^(?<targetname>.+)'s seared corpse smolders before you!$",
                @"^(?<targetname>.+) is reduced to cinders!$",
                @"^(?<targetname>.+) is shattered by your assault!$",
                @"^(?<targetname>.+) catches your attack, with dire consequences!$",
                @"^(?<targetname>.+) is utterly destroyed by your attack!$",
                @"^(?<targetname>.+) suffers a frozen fate!$",
                @"^(?<targetname>.+)'s perforated corpse falls before you!$",
                @"^(?<targetname>.+) is fatally punctured!$",
                @"^(?<targetname>.+)'s death is preceded by a sharp, stabbing pain!$",
                @"^(?<targetname>.+) is torn to ribbons by your assault!$",
                @"^(?<targetname>.+) is liquified by your attack!$",
                @"^(?<targetname>.+)'s last strength dissolves before you!$",
                @"^Electricity tears (?<targetname>.+) apart!$",
                @"^Blistered by lightning, (?<targetname>.+) falls!$",
                @"^(?<targetname>.+)'s last strength withers before you!$",
                @"^(?<targetname>.+) is dessicated by your attack!$",
                @"^(?<targetname>.+) is incinerated by your assault!$"
            };

            foreach (string pattern in killPatterns)
            {
                if (Regex.IsMatch(text, pattern))
                    return true;
            }

            return false;
        }
        private bool IsRareDiscoveryMessage(string text, out string rareTextOnly)
        {
            rareTextOnly = null;

            // Match pattern: "<name> has discovered the <something>!"
            string pattern = @"^(?<name>['A-Za-z ]+)\s(?<text>has discovered the .*!$)";
            Match match = Regex.Match(text, pattern);

            if (match.Success && match.Groups["name"].Value == CoreManager.Current.CharacterFilter.Name)
            {
                rareTextOnly = match.Groups["text"].Value; // just "has discovered the Ancient Pickle!"
                return true;
            }

            return false;
        }
        public static void WriteToChat(string message)
        {
            MyHost.Actions.AddChatText("[Mosswart Massacre] " + message, 0, 1);
        }
        public static void RestartStats()
        {
            totalKills = 0;
            rareCount = 0;
            sessionDeaths = 0;  // Reset session deaths only
            statsStartTime = DateTime.Now;
            killsPer5Min = 0;
            killsPerHour = 0;

            WriteToChat($"Stats have been reset. Session deaths: {sessionDeaths}, Total deaths: {totalDeaths}");
            ViewManager.UpdateKillStats(totalKills, killsPer5Min, killsPerHour);
            ViewManager.UpdateRareCount(rareCount);
        }
        public static void ToggleRareMeta()
        {
            PluginSettings.Instance.RareMetaEnabled = !PluginSettings.Instance.RareMetaEnabled;
            RareMetaEnabled = PluginSettings.Instance.RareMetaEnabled;
            ViewManager.SetRareMetaToggleState(RareMetaEnabled);
        }

        [DllImport("Decal.dll")]
        private static extern int DispatchOnChatCommand(ref IntPtr str, [MarshalAs(UnmanagedType.U4)] int target);

        public static bool Decal_DispatchOnChatCommand(string cmd)
        {
            IntPtr bstr = Marshal.StringToBSTR(cmd);

            try
            {
                bool eaten = (DispatchOnChatCommand(ref bstr, 1) & 0x1) > 0;
                return eaten;
            }
            finally
            {
                Marshal.FreeBSTR(bstr);
            }
        }
        public static void DispatchChatToBoxWithPluginIntercept(string cmd)
        {
            if (!Decal_DispatchOnChatCommand(cmd))
                CoreManager.Current.Actions.InvokeChatParser(cmd);
        }
        private void HandleMmCommand(string text)
        {
            // Remove the /mm prefix and trim extra whitespace
            string[] args = text.Substring(3).Trim().Split(' ');

            if (args.Length == 0 || string.IsNullOrEmpty(args[0]))
            {
                WriteToChat("Usage: /mm <command>. Try /mm help");
                return;
            }

            string subCommand = args[0].ToLower();

            switch (subCommand)
            {
                case "telemetry":
                    if (args.Length > 1)
                    {
                        if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
                        {
                            TelemetryEnabled = true;
                            Telemetry.Start();
                            PluginSettings.Instance.TelemetryEnabled = true;
                            WriteToChat("Telemetry streaming ENABLED.");
                        }
                        else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
                        {
                            TelemetryEnabled = false;
                            Telemetry.Stop();
                            PluginSettings.Instance.TelemetryEnabled = false;
                            WriteToChat("Telemetry streaming DISABLED.");
                        }
                        else
                        {
                            WriteToChat("Usage: /mm telemetry <enable|disable>");
                        }
                    }
                    else
                    {
                        WriteToChat("Usage: /mm telemetry <enable|disable>");
                    }
                    break;
                case "ws":
                    if (args.Length > 1)
                    {
                        if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
                        {
                            WebSocketEnabled = true;
                            WebSocket.Start();
                            PluginSettings.Instance.WebSocketEnabled = true;
                            WriteToChat("WS streaming ENABLED.");
                        }
                        else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
                        {
                            WebSocketEnabled = false;
                            WebSocket.Stop();
                            PluginSettings.Instance.WebSocketEnabled = false;
                            WriteToChat("WS streaming DISABLED.");
                        }
                        else
                        {
                            WriteToChat("Usage: /mm ws <enable|disable>");
                        }
                    }
                    else
                    {
                        WriteToChat("Usage: /mm ws <enable|disable>");
                    }
                    break;
                case "help":
                    WriteToChat("Mosswart Massacre Commands:");
                    WriteToChat("/mm report        - Show current stats");
                    WriteToChat("/mm loc           - Show current location");
                    WriteToChat("/mm telemetry     - Telemetry streaming enable|disable");
                    WriteToChat("/mm ws            - Websocket streaming enable|disable");
                    WriteToChat("/mm reset         - Reset all counters");
                    WriteToChat("/mm meta          - Toggle rare meta state");
                    WriteToChat("/mm http          - Local http-command server enable|disable");
                    WriteToChat("/mm remotecommand - Listen to allegiance !do/!dot enable|disable");
                    WriteToChat("/mm getmetastate  - Gets the current metastate");
                    WriteToChat("/mm nextwp        - Advance VTank to next waypoint");
                    WriteToChat("/mm decalstatus   - Check Harmony patch status (UtilityBelt version)");
                    WriteToChat("/mm decaldebug    - Enable/disable plugin message debug output + WebSocket streaming");
                    WriteToChat("/mm harmonyraw    - Show raw intercepted messages (debug output)");
                    WriteToChat("/mm testprismatic - Test Prismatic Taper detection and icon lookup");
                    WriteToChat("/mm deathstats    - Show current death tracking statistics");
                    WriteToChat("/mm testdeath     - Manual death tracking test and diagnostics");
                    WriteToChat("/mm gui           - Manually initialize/reinitialize GUI");
                    break;
                case "report":
                    TimeSpan elapsed = DateTime.Now - statsStartTime;
                    string reportMessage = $"Total Kills: {totalKills}, Kills per Hour: {killsPerHour:F2}, Elapsed Time: {elapsed:dd\\.hh\\:mm\\:ss}, Rares Found: {rareCount}, Session Deaths: {sessionDeaths}, Total Deaths: {totalDeaths}";
                    WriteToChat(reportMessage);
                    break;
                case "getmetastate":
                    string metaState = VtankControl.VtGetMetaState();
                    WriteToChat(metaState);
                    break;

                case "loc":
                    Coordinates here = Coordinates.Me;
                    var pos = Utils.GetPlayerPosition();
                    WriteToChat($"Location: {here}  (X={pos.X:F1}, Y={pos.Y:F1}, Z={pos.Z:F1})");
                    break;
                case "reset":
                    RestartStats();
                    break;
                case "meta":
                    RareMetaEnabled = !RareMetaEnabled;
                    WriteToChat($"Rare meta state is now {(RareMetaEnabled ? "ON" : "OFF")}");
                    ViewManager.SetRareMetaToggleState(RareMetaEnabled);  // <-- sync the UI
                    break;
                
                case "http":
                    if (args.Length > 1)
                    {
                        if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
                        {
                            PluginSettings.Instance.HttpServerEnabled = true;
                            HttpServerEnabled = true;
                            HttpCommandServer.Start();
                        }
                        else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
                        {
                            PluginSettings.Instance.HttpServerEnabled = false;
                            HttpServerEnabled = false;
                            HttpCommandServer.Stop();
                        }
                        else
                        {
                            WriteToChat("Usage: /mm http <enable|disable>");
                        }
                    }
                    else
                    {
                        WriteToChat("Usage: /mm http <enable|disable>");
                    }
                    break;

                case "remotecommands":
                    if (args.Length > 1)
                    {
                        if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
                        {
                            PluginSettings.Instance.RemoteCommandsEnabled = true;
                            RemoteCommandsEnabled = true;
                            WriteToChat("Remote command listening is now ENABLED.");
                        }
                        else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
                        {
                            PluginSettings.Instance.RemoteCommandsEnabled = false;
                            RemoteCommandsEnabled = false;
                            WriteToChat("Remote command listening is now DISABLED.");
                        }
                        else
                        {
                            WriteToChat("Invalid remotecommands argument. Use 'enable' or 'disable'.");
                        }
                    }
                    else
                    {
                        WriteToChat("Usage: /mm remotecommands <enable|disable>");
                    }
                    break;

                case "nextwp":
                    double result = VtankControl.VtAdvanceWaypoint();
                    if (result == 1)
                    {
                        WriteToChat("Advanced VTank to next waypoint.");
                    }
                    else
                    {
                        WriteToChat("Failed to advance VTank waypoint. Is VTank running?");
                    }
                    break;

                case "vtanktest":
                    try
                    {
                        WriteToChat("Testing VTank interface...");
                        WriteToChat($"VTank Instance: {(vTank.Instance != null ? "Found" : "NULL")}");
                        WriteToChat($"VTank Type: {vTank.Instance?.GetType()?.Name ?? "NULL"}");
                        WriteToChat($"NavCurrent: {vTank.Instance?.NavCurrent ?? -1}");
                        WriteToChat($"NavNumPoints: {vTank.Instance?.NavNumPoints ?? -1}");
                        WriteToChat($"NavType: {vTank.Instance?.NavType}");
                        WriteToChat($"MacroEnabled: {vTank.Instance?.MacroEnabled}");
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"VTank test error: {ex.Message}");
                    }
                    break;

                case "decalstatus":
                    try
                    {
                        WriteToChat("=== Harmony Patch Status (UtilityBelt Pattern) ===");
                        WriteToChat($"Patches Active: {DecalHarmonyClean.IsActive()}");
                        WriteToChat($"Messages Intercepted: {DecalHarmonyClean.GetMessagesIntercepted()}");
                        WriteToChat($"Debug Streaming: {AggressiveChatStreamingEnabled}");
                        WriteToChat($"WebSocket Streaming: {(AggressiveChatStreamingEnabled && WebSocketEnabled ? "ACTIVE" : "INACTIVE")}");
                        
                        // Test Harmony availability
                        WriteToChat("=== Harmony Version Status ===");
                        try
                        {
                            var harmonyTest = Harmony.HarmonyInstance.Create("test.version.check");
                            WriteToChat($"[OK] Harmony Available (ID: {harmonyTest.Id})");
                            
                            // Check Harmony assembly version
                            var harmonyAssembly = typeof(Harmony.HarmonyInstance).Assembly;
                            WriteToChat($"[OK] Harmony Version: {harmonyAssembly.GetName().Version}");
                            WriteToChat($"[OK] Harmony Location: {harmonyAssembly.Location}");
                        }
                        catch (Exception harmonyEx)
                        {
                            WriteToChat($"[FAIL] Harmony Test Failed: {harmonyEx.Message}");
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"Status check error: {ex.Message}");
                    }
                    break;

                case "decaldebug":
                    if (args.Length > 1)
                    {
                        if (args[1].Equals("enable", StringComparison.OrdinalIgnoreCase))
                        {
                            AggressiveChatStreamingEnabled = true;
                            WriteToChat("[OK] DECAL debug streaming ENABLED - will show captured messages + stream via WebSocket");
                        }
                        else if (args[1].Equals("disable", StringComparison.OrdinalIgnoreCase))
                        {
                            AggressiveChatStreamingEnabled = false;
                            WriteToChat("[FAIL] DECAL debug streaming DISABLED - WebSocket streaming also disabled");
                        }
                        else
                        {
                            WriteToChat("Usage: /mm decaldebug <enable|disable>");
                        }
                    }
                    else
                    {
                        WriteToChat("Usage: /mm decaldebug <enable|disable>");
                    }
                    break;


                case "harmonyraw":
                    try
                    {
                        WriteToChat("=== Raw Harmony Interception Log ===");
                        var debugEntries = DecalHarmonyClean.GetDebugLog();
                        if (debugEntries.Length == 0)
                        {
                            WriteToChat("No debug entries found. Enable debug streaming first: /mm decaldebug enable");
                        }
                        else
                        {
                            WriteToChat($"Last {debugEntries.Length} intercepted messages:");
                            foreach (var entry in debugEntries.Skip(Math.Max(0, debugEntries.Length - 10)))
                            {
                                WriteToChat($"  {entry}");
                            }
                            if (debugEntries.Length > 10)
                            {
                                WriteToChat($"... ({debugEntries.Length - 10} more entries)");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"Debug log error: {ex.Message}");
                    }
                    break;

                case "initgui":
                case "gui":
                    try
                    {
                        WriteToChat("Attempting to manually initialize GUI...");
                        ViewManager.ViewDestroy(); // Clean up any existing view
                        ViewManager.ViewInit();     // Reinitialize
                        WriteToChat("GUI initialization attempt completed.");
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"GUI initialization error: {ex.Message}");
                    }
                    break;

                case "testprismatic":
                    try
                    {
                        WriteToChat("=== FULL INVENTORY DUMP ===");
                        var worldFilter = CoreManager.Current.WorldFilter;
                        var playerInv = CoreManager.Current.CharacterFilter.Id;
                        
                        WriteToChat("Listing ALL items in your main inventory:");
                        int itemNum = 1;
                        
                        foreach (WorldObject item in worldFilter.GetByContainer(playerInv))
                        {
                            if (!string.IsNullOrEmpty(item.Name))
                            {
                                int stackCount = item.Values(LongValueKey.StackCount, 0);
                                WriteToChat($"{itemNum:D2}: '{item.Name}' (count: {stackCount}, icon: 0x{item.Icon:X}, class: {item.ObjectClass})");
                                itemNum++;
                                
                                // Highlight anything that might be a taper
                                string nameLower = item.Name.ToLower();
                                if (nameLower.Contains("taper") || nameLower.Contains("prismatic") || 
                                    nameLower.Contains("prism") || nameLower.Contains("component"))
                                {
                                    WriteToChat($"    *** POSSIBLE MATCH: '{item.Name}' ***");
                                }
                            }
                        }
                        
                        WriteToChat($"=== Total items listed: {itemNum - 1} ===");
                        
                        // Now test our utility functions on the found Prismatic Taper
                        WriteToChat("=== Testing Utility Functions on Prismatic Taper ===");
                        var foundItem = Utils.FindItemByName("Prismatic Taper");
                        if (foundItem != null)
                        {
                            WriteToChat($"SUCCESS! Found: '{foundItem.Name}'");
                            WriteToChat($"Utils.GetItemStackSize: {Utils.GetItemStackSize("Prismatic Taper")}");
                            WriteToChat($"Utils.GetItemIcon: 0x{Utils.GetItemIcon("Prismatic Taper"):X}");
                            WriteToChat($"Utils.GetItemDisplayIcon: 0x{Utils.GetItemDisplayIcon("Prismatic Taper"):X}");
                            WriteToChat("=== TELEMETRY WILL NOW WORK! ===");
                        }
                        else
                        {
                            WriteToChat("ERROR: Still can't find Prismatic Taper with utility functions!");
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"Search error: {ex.Message}");
                    }
                    break;

                case "deathstats":
                    try
                    {
                        WriteToChat("=== Death Tracking Statistics ===");
                        WriteToChat($"Session Deaths: {sessionDeaths}");
                        WriteToChat($"Total Deaths: {totalDeaths}");
                        
                        // Get current character death count to verify sync
                        int currentCharDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
                        WriteToChat($"Character Property NumDeaths: {currentCharDeaths}");
                        
                        if (currentCharDeaths != totalDeaths)
                        {
                            WriteToChat($"[WARNING] Death count sync issue detected!");
                            WriteToChat($"Updating totalDeaths from {totalDeaths} to {currentCharDeaths}");
                            totalDeaths = currentCharDeaths;
                        }
                        
                        WriteToChat("Death tracking is active and will increment on character death.");
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"Death stats error: {ex.Message}");
                    }
                    break;

                case "testdeath":
                    try
                    {
                        WriteToChat("=== Manual Death Test ===");
                        WriteToChat($"Current sessionDeaths variable: {sessionDeaths}");
                        WriteToChat($"Current totalDeaths variable: {totalDeaths}");
                        
                        // Read directly from character property
                        int currentCharDeaths = CoreManager.Current.CharacterFilter.GetCharProperty((int)IntValueKey.NumDeaths);
                        WriteToChat($"Character Property NumDeaths (43): {currentCharDeaths}");
                        
                        // Manually increment session deaths for testing
                        sessionDeaths++;
                        WriteToChat($"Manually incremented sessionDeaths to: {sessionDeaths}");
                        WriteToChat("Note: This doesn't simulate a real death, just tests the tracking variables.");
                        
                        // Check if death event is properly subscribed
                        WriteToChat($"Death event subscription check:");
                        var deathEvent = typeof(Decal.Adapter.Wrappers.CharacterFilter).GetEvent("Death");
                        WriteToChat($"Death event exists: {deathEvent != null}");
                    }
                    catch (Exception ex)
                    {
                        WriteToChat($"Test death error: {ex.Message}");
                    }
                    break;

                case "finditem":
                    if (args.Length > 1)
                    {
                        string itemName = string.Join(" ", args, 1, args.Length - 1).Trim('"');
                        WriteToChat($"=== Searching for: '{itemName}' ===");
                        
                        var foundItem = Utils.FindItemByName(itemName);
                        if (foundItem != null)
                        {
                            WriteToChat($"FOUND: '{foundItem.Name}'");
                            WriteToChat($"Count: {foundItem.Values(LongValueKey.StackCount, 0)}");
                            WriteToChat($"Icon: 0x{foundItem.Icon:X}");
                            WriteToChat($"Display Icon: 0x{(foundItem.Icon + 0x6000000):X}");
                            WriteToChat($"Object Class: {foundItem.ObjectClass}");
                        }
                        else
                        {
                            WriteToChat($"NOT FOUND: '{itemName}'");
                            WriteToChat("Make sure the name is exactly as it appears in-game.");
                        }
                    }
                    else
                    {
                        WriteToChat("Usage: /mm finditem \"Item Name\"");
                        WriteToChat("Example: /mm finditem \"Prismatic Taper\"");
                    }
                    break;

                default:
                    WriteToChat($"Unknown /mm command: {subCommand}. Try /mm help");
                    break;
            }
        }


    }
}

    
