using System;
using System.Drawing;
using System.Linq;
using System.Timers;
using VirindiViewService.Controls;

namespace MosswartMassacre.Views
{
    /// <summary>
    /// VVS-based tabbed main view - direct VirindiViewService integration.
    /// Replaces wrapper-based TabbedMainView with modern VVS controls.
    /// </summary>
    internal class VVSTabbedMainView : VVSBaseView
    {
        private static VVSTabbedMainView instance;
        
        #region Main Tab Controls
        private HudStaticText lblTotalKills;
        private HudStaticText lblKillsPer5Min;
        private HudStaticText lblKillsPerHour;
        private HudStaticText lblElapsedTime;
        private HudStaticText lblRareCount;
        private HudStaticText lblAutoLootRare;
        private HudStaticText lblStatus;
        private HudStaticText lblWebSocketStatus;
        private HudButton btnCheckUpdate;
        private HudButton btnInstallUpdate;
        private HudStaticText lblUpdateStatus;
        #endregion
        
        #region Settings Tab Controls
        private HudCheckBox chkRareMetaEnabled;
        private HudCheckBox chkWebSocketEnabled;
        private HudCheckBox chkAutoUpdateEnabled;
        private HudCheckBox chkVitalSharingEnabled;
        private HudButton btnVitalSharingOverlay;
        private HudCheckBox chkVerboseLogging;
        private HudTextBox txtCharTag;
        private HudTextBox txtVTankPath;
        #endregion
        
        #region Statistics Tab Controls
        private HudStaticText lblDetailedKillsValue;
        private HudStaticText lblBestHourValue;
        private HudStaticText lblAverageKillsValue;
        private HudStaticText lblRareStatsValue;
        private HudStaticText lblRareRateValue;
        private HudStaticText lblSessionTimeValue;
        private HudStaticText lblLastKillValue;
        private HudButton btnResetStats;
        #endregion
        
        #region Navigation Tab Controls (Basic)
        private HudCheckBox chkNavVisualizationEnabled;
        private HudCombo cmbNavFiles;
        private HudButton btnRefreshNavFiles;
        private HudStaticText lblNavStatus;
        private HudButton btnLoadRoute;
        private HudButton btnClearRoute;
        #endregion
        
        #region Flag Tracker Tab Controls
        private HudButton btnOpenFlagTracker;
        // lblFlagTrackerStatus removed - not present in XML
        #endregion

        #region Chest Looter Tab Controls
        private HudTextBox txtChestName;
        private HudTextBox txtKeyName;
        private HudButton btnSetChest;
        private HudButton btnSetKey;
        private HudButton btnStartLooter;
        private HudButton btnStopLooter;
        private HudCheckBox chkEnableChests;
        private HudStaticText lblLooterStatus;
        #endregion

        #region Metas Tab Controls
        private HudStaticText lblMetasPath;
        private HudButton btnRefreshMetasList;
        private HudButton btnCheckMetasUpdates;
        private HudButton btnDownloadOutdatedMetas;
        private HudTextBox txtMetasSearch;
        private HudButton btnClearMetasSearch;
        private HudList lstMetasFiles;
        private HudCombo cmbMetaSelection;
        private HudButton btnDownloadSelectedMeta;
        private HudStaticText lblMetasLastCheck;
        private HudStaticText lblMetasStatus;
        private string _metasSearchText = string.Empty;
        #endregion

        #region Statistics Tracking
        private double bestHourlyKills = 0;
        private DateTime sessionStartTime;
        #endregion

        public VVSTabbedMainView(PluginCore core) : base(core)
        {
            instance = this;
            sessionStartTime = DateTime.Now;
        }

        #region Static Interface Methods
        public static void ViewInit()
        {
            try
            {
                // Check if VVS is available
                try
                {
                    var testParser = new VirindiViewService.XMLParsers.Decal3XMLParser();
                }
                catch (Exception vvsEx)
                {
                    PluginCore.WriteToChat("[ERROR] VVS not available: " + vvsEx.Message);
                    return;
                }
                
                if (instance == null)
                {
                    instance = new VVSTabbedMainView(null);
                }
                
                instance.InitializeView();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat("Error initializing VVS tabbed view: " + ex.Message);
                PluginCore.WriteToChat("Stack trace: " + ex.StackTrace);
            }
        }

        public static void ViewDestroy()
        {
            try
            {
                if (instance != null)
                {
                    instance.Dispose();
                    instance = null;
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat("Error destroying VVS tabbed view: " + ex.Message);
            }
        }
        #endregion

        #region Initialization
        private void InitializeView()
        {
            try
            {
                // Create view from working original XML layout
                CreateFromXMLResource("MosswartMassacre.ViewXML.mainViewTabbed.xml");

                if (view == null)
                {
                    PluginCore.WriteToChat("[ERROR] View creation failed - view is null!");
                    return;
                }

                // Initialize all tab controls
                InitializeMainTabControls();
                InitializeSettingsTabControls();
                InitializeStatisticsTabControls();
                InitializeNavigationTabControls();
                InitializeFlagTrackerTabControls();
                InitializeChestLooterTabControls();
                InitializeMetasTabControls();

                // Initialize the base view and set initial position
                Initialize();
                
                // Make the view visible and show in plugin bar
                if (view != null)
                {
                    view.Visible = true;
                    view.ShowInBar = true;
                    PluginCore.WriteToChat("GUI initialized successfully!");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat("Error in VVS InitializeView: " + ex.Message);
                PluginCore.WriteToChat("Stack trace: " + ex.StackTrace);
            }
        }

        private void InitializeMainTabControls()
        {
            try
            {
                // Main tab - existing functionality using VVS controls
                lblTotalKills = GetControl<HudStaticText>("lblTotalKills");
                lblKillsPer5Min = GetControl<HudStaticText>("lblKillsPer5Min");
                lblKillsPerHour = GetControl<HudStaticText>("lblKillsPerHour");
                lblElapsedTime = GetControl<HudStaticText>("lblElapsedTime");
                lblRareCount = GetControl<HudStaticText>("lblRareCount");
                lblAutoLootRare = GetControl<HudStaticText>("lblAutoLootRare");
                lblStatus = GetControl<HudStaticText>("lblStatus");
                lblWebSocketStatus = GetControl<HudStaticText>("lblWebSocketStatus");
                btnCheckUpdate = GetControl<HudButton>("btnCheckUpdate");
                btnInstallUpdate = GetControl<HudButton>("btnInstallUpdate");
                lblUpdateStatus = GetControl<HudStaticText>("lblUpdateStatus");
                
                // Hook up update button events
                if (btnCheckUpdate != null)
                    btnCheckUpdate.Hit += OnCheckUpdateClicked;
                if (btnInstallUpdate != null)
                    btnInstallUpdate.Hit += OnInstallUpdateClicked;
                
                // Update status displays immediately
                UpdateStatus();
                UpdateAutoLootRareIndicator();
                UpdateWebSocketStatus();
                RefreshUpdateStatus();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing main tab controls: {ex.Message}");
            }
        }

        private void InitializeSettingsTabControls()
        {
            try
            {
                // Settings tab controls
                chkRareMetaEnabled = GetControl<HudCheckBox>("chkRareMetaEnabled");
                chkWebSocketEnabled = GetControl<HudCheckBox>("chkWebSocketEnabled");
                chkAutoUpdateEnabled = GetControl<HudCheckBox>("chkAutoUpdateEnabled");
                chkVitalSharingEnabled = GetControl<HudCheckBox>("chkVitalSharingEnabled");
                btnVitalSharingOverlay = GetControl<HudButton>("btnVitalSharingOverlay");
                chkVerboseLogging = GetControl<HudCheckBox>("chkVerboseLogging");
                txtCharTag = GetControl<HudTextBox>("txtCharTag");
                txtVTankPath = GetControl<HudTextBox>("txtVTankPath");

                // Hook up settings events
                if (chkRareMetaEnabled != null)
                    chkRareMetaEnabled.Change += OnRareMetaSettingChanged;
                if (chkWebSocketEnabled != null)
                    chkWebSocketEnabled.Change += OnWebSocketSettingChanged;
                if (chkAutoUpdateEnabled != null)
                    chkAutoUpdateEnabled.Change += OnAutoUpdateSettingChanged;
                if (chkVitalSharingEnabled != null)
                    chkVitalSharingEnabled.Change += OnVitalSharingSettingChanged;
                if (btnVitalSharingOverlay != null)
                    btnVitalSharingOverlay.Hit += OnVitalSharingOverlayClicked;
                if (chkVerboseLogging != null)
                    chkVerboseLogging.Change += OnVerboseLoggingSettingChanged;
                if (txtCharTag != null)
                    txtCharTag.Change += OnCharTagChanged;
                if (txtVTankPath != null)
                    txtVTankPath.Change += OnVTankPathChanged;
                
                // Load current settings
                LoadCurrentSettings();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing settings tab controls: {ex.Message}");
            }
        }

        private void InitializeStatisticsTabControls()
        {
            try
            {
                // Statistics tab controls
                lblDetailedKillsValue = GetControl<HudStaticText>("lblDetailedKillsValue");
                lblBestHourValue = GetControl<HudStaticText>("lblBestHourValue");
                lblAverageKillsValue = GetControl<HudStaticText>("lblAverageKillsValue");
                lblRareStatsValue = GetControl<HudStaticText>("lblRareStatsValue");
                lblRareRateValue = GetControl<HudStaticText>("lblRareRateValue");
                lblSessionTimeValue = GetControl<HudStaticText>("lblSessionTimeValue");
                lblLastKillValue = GetControl<HudStaticText>("lblLastKillValue");
                btnResetStats = GetControl<HudButton>("btnResetStats");
                
                // Hook up statistics events
                if (btnResetStats != null)
                    btnResetStats.Hit += OnResetStatsClick;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing statistics controls: {ex.Message}");
            }
        }

        private void InitializeNavigationTabControls()
        {
            try
            {
                // Basic navigation tab controls
                chkNavVisualizationEnabled = GetControl<HudCheckBox>("chkNavVisualizationEnabled");
                cmbNavFiles = GetControl<HudCombo>("cmbNavFiles");
                btnRefreshNavFiles = GetControl<HudButton>("btnRefreshNavFiles");
                lblNavStatus = GetControl<HudStaticText>("lblNavStatus");
                btnLoadRoute = GetControl<HudButton>("btnLoadRoute");
                btnClearRoute = GetControl<HudButton>("btnClearRoute");
                
                // Hook up basic navigation events
                if (chkNavVisualizationEnabled != null)
                    chkNavVisualizationEnabled.Change += OnNavVisualizationEnabledChanged;
                if (btnRefreshNavFiles != null)
                    btnRefreshNavFiles.Hit += OnRefreshNavFilesClick;
                if (btnLoadRoute != null)
                    btnLoadRoute.Hit += OnLoadRouteClick;
                if (btnClearRoute != null)
                    btnClearRoute.Hit += OnClearRouteClick;
                
                // Initialize navigation system
                InitializeNavigationSystem();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing navigation controls: {ex.Message}");
            }
        }

        private void InitializeFlagTrackerTabControls()
        {
            try
            {
                // Flag Tracker tab controls
                btnOpenFlagTracker = GetControl<HudButton>("btnOpenFlagTracker");

                // Hook up Flag Tracker events
                if (btnOpenFlagTracker != null)
                    btnOpenFlagTracker.Hit += OnOpenFlagTrackerClick;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing flag tracker controls: {ex.Message}");
            }
        }

        private void InitializeChestLooterTabControls()
        {
            try
            {
                // Chest Looter tab controls
                txtChestName = GetControl<HudTextBox>("txtChestName");
                txtKeyName = GetControl<HudTextBox>("txtKeyName");
                btnSetChest = GetControl<HudButton>("btnSetChest");
                btnSetKey = GetControl<HudButton>("btnSetKey");
                btnStartLooter = GetControl<HudButton>("btnStartLooter");
                btnStopLooter = GetControl<HudButton>("btnStopLooter");
                chkEnableChests = GetControl<HudCheckBox>("chkEnableChests");
                lblLooterStatus = GetControl<HudStaticText>("lblLooterStatus");

                // Hook up Chest Looter events
                if (btnSetChest != null)
                    btnSetChest.Hit += OnSetChestClick;
                if (btnSetKey != null)
                    btnSetKey.Hit += OnSetKeyClick;
                if (btnStartLooter != null)
                    btnStartLooter.Hit += OnStartLooterClick;
                if (btnStopLooter != null)
                    btnStopLooter.Hit += OnStopLooterClick;
                if (chkEnableChests != null)
                    chkEnableChests.Change += OnEnableChestsChanged;

                // Load current settings
                LoadChestLooterSettings();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing chest looter controls: {ex.Message}");
            }
        }

        private void InitializeMetasTabControls()
        {
            try
            {
                lblMetasPath = GetControl<HudStaticText>("lblMetasPath");
                btnRefreshMetasList = GetControl<HudButton>("btnRefreshMetasList");
                btnCheckMetasUpdates = GetControl<HudButton>("btnCheckMetasUpdates");
                btnDownloadOutdatedMetas = GetControl<HudButton>("btnDownloadOutdatedMetas");
                txtMetasSearch = GetControl<HudTextBox>("txtMetasSearch");
                btnClearMetasSearch = GetControl<HudButton>("btnClearMetasSearch");
                lstMetasFiles = GetControl<HudList>("lstMetasFiles");
                cmbMetaSelection = GetControl<HudCombo>("cmbMetaSelection");
                btnDownloadSelectedMeta = GetControl<HudButton>("btnDownloadSelectedMeta");
                lblMetasLastCheck = GetControl<HudStaticText>("lblMetasLastCheck");
                lblMetasStatus = GetControl<HudStaticText>("lblMetasStatus");

                if (btnRefreshMetasList != null)
                    btnRefreshMetasList.Hit += OnRefreshMetasListClick;
                if (btnCheckMetasUpdates != null)
                    btnCheckMetasUpdates.Hit += OnCheckMetasUpdatesClick;
                if (btnDownloadOutdatedMetas != null)
                    btnDownloadOutdatedMetas.Hit += OnDownloadOutdatedMetasClick;
                if (txtMetasSearch != null)
                    txtMetasSearch.Change += OnMetasSearchChanged;
                if (btnClearMetasSearch != null)
                    btnClearMetasSearch.Hit += OnClearMetasSearchClick;
                if (btnDownloadSelectedMeta != null)
                    btnDownloadSelectedMeta.Hit += OnDownloadSelectedMetaClick;

                UpdateMetasPathLabel();
                UpdateMetasStatus("Status: idle");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing metas controls: {ex.Message}");
            }
        }
        #endregion

        #region Event Handlers - Settings Tab
        private void OnRareMetaSettingChanged(object sender, EventArgs e)
        {
            try
            {
                PluginSettings.Instance.RareMetaEnabled = chkRareMetaEnabled.Checked;
                PluginCore.RareMetaEnabled = chkRareMetaEnabled.Checked;
                UpdateAutoLootRareIndicator();
                PluginCore.WriteToChat($"Rare meta automation {(chkRareMetaEnabled.Checked ? "ENABLED" : "DISABLED")}.");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in rare meta setting change: {ex.Message}");
            }
        }

        private void OnWebSocketSettingChanged(object sender, EventArgs e)
        {
            try
            {
                PluginSettings.Instance.WebSocketEnabled = chkWebSocketEnabled.Checked;
                PluginCore.WebSocketEnabled = chkWebSocketEnabled.Checked;
                if (chkWebSocketEnabled.Checked)
                {
                    WebSocket.Start();
                    PluginCore.WriteToChat("WebSocket streaming ENABLED.");
                }
                else
                {
                    WebSocket.Stop();
                    PluginCore.WriteToChat("WebSocket streaming DISABLED.");
                }
                UpdateWebSocketStatus();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in WebSocket setting change: {ex.Message}");
            }
        }

        private void OnCharTagChanged(object sender, EventArgs e)
        {
            try
            {
                PluginSettings.Instance.CharTag = txtCharTag.Text;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in char tag change: {ex.Message}");
            }
        }

        private void OnAutoUpdateSettingChanged(object sender, EventArgs e)
        {
            try
            {
                PluginSettings.Instance.AutoUpdateEnabled = chkAutoUpdateEnabled.Checked;
                PluginCore.WriteToChat($"Auto updates {(chkAutoUpdateEnabled.Checked ? "ENABLED" : "DISABLED")}." );
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in auto update setting change: {ex.Message}");
            }
        }

        private void OnVitalSharingSettingChanged(object sender, EventArgs e)
        {
            try
            {
                PluginCore.SetVitalSharingEnabled(chkVitalSharingEnabled.Checked);
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in vital sharing setting change: {ex.Message}");
            }
        }

        private void OnVitalSharingOverlayClicked(object sender, EventArgs e)
        {
            try
            {
                VitalSharingOverlayView.ToggleWindow();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error opening vital sharing overlay: {ex.Message}");
            }
        }

        private void OnVerboseLoggingSettingChanged(object sender, EventArgs e)
        {
            try
            {
                PluginSettings.Instance.VerboseLogging = chkVerboseLogging.Checked;
                PluginCore.WriteToChat($"Verbose logging {(chkVerboseLogging.Checked ? "ENABLED" : "DISABLED")}.");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in verbose logging setting change: {ex.Message}");
            }
        }

        private void OnVTankPathChanged(object sender, EventArgs e)
        {
            try
            {
                PluginSettings.Instance.VTankProfilesPath = txtVTankPath.Text;
                // Refresh navigation system with new path
                if (PluginCore.navVisualization != null)
                {
                    PluginCore.navVisualization.RefreshNavFileList();
                    RefreshNavFileList();
                    UpdateNavigationStatus();
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in VTank path change: {ex.Message}");
            }
        }

        private void OnCheckUpdateClicked(object sender, EventArgs e)
        {
            try
            {
                // Run update check asynchronously
                System.Threading.Tasks.Task.Run(async () =>
                {
                    await UpdateManager.CheckForUpdateAsync();
                    // Update UI (VVS controls are thread-safe for simple property updates)
                    try
                    {
                        RefreshUpdateStatus();
                    }
                    catch (Exception ex)
                    {
                        PluginCore.WriteToChat($"Error updating UI after check: {ex.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error checking for updates: {ex.Message}");
            }
        }

        private void OnInstallUpdateClicked(object sender, EventArgs e)
        {
            try
            {
                // Check if update check was performed first
                if (UpdateManager.LastCheckTime == DateTime.MinValue)
                {
                    PluginCore.WriteToChat("[Update] Check for updates first");
                    return;
                }
                
                if (!UpdateManager.IsUpdateAvailable)
                {
                    PluginCore.WriteToChat("[Update] No update available");
                    return;
                }
                
                // Run update installation asynchronously
                System.Threading.Tasks.Task.Run(async () =>
                {
                    await UpdateManager.DownloadAndInstallUpdateAsync();
                    // Update UI (VVS controls are thread-safe for simple property updates)
                    try
                    {
                        RefreshUpdateStatus();
                    }
                    catch (Exception ex)
                    {
                        PluginCore.WriteToChat($"Error updating UI after install: {ex.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error installing update: {ex.Message}");
            }
        }

        public static void RefreshUpdateStatus()
        {
            try
            {
                if (instance?.lblUpdateStatus != null)
                {
                    if (UpdateManager.LastCheckTime == DateTime.MinValue)
                    {
                        // Not checked yet
                        instance.lblUpdateStatus.Text = "";
                    }
                    else if (UpdateManager.IsUpdateAvailable)
                    {
                        // Update available
                        instance.lblUpdateStatus.Text = "Update available";
                    }
                    else
                    {
                        // Up to date
                        instance.lblUpdateStatus.Text = "Up to date";
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing update status: {ex.Message}");
            }
        }

        public void RefreshUpdateStatusInstance()
        {
            RefreshUpdateStatus();
        }

        public static void DebugUpdateControls()
        {
            try
            {
                PluginCore.WriteToChat("=== Update UI Debug (Main Tab) ===");
                PluginCore.WriteToChat($"Instance exists: {instance != null}");
                if (instance != null)
                {
                    PluginCore.WriteToChat($"btnCheckUpdate: {instance.btnCheckUpdate != null}");
                    PluginCore.WriteToChat($"btnInstallUpdate: {instance.btnInstallUpdate != null}");
                    PluginCore.WriteToChat($"lblUpdateStatus: {instance.lblUpdateStatus != null}");
                    
                    if (instance.lblUpdateStatus != null)
                    {
                        PluginCore.WriteToChat($"Current status text: '{instance.lblUpdateStatus.Text}'");
                    }
                    
                    PluginCore.WriteToChat($"UpdateManager.LastCheckTime: {UpdateManager.LastCheckTime}");
                    PluginCore.WriteToChat($"UpdateManager.IsUpdateAvailable: {UpdateManager.IsUpdateAvailable}");
                    
                    // Try to force refresh
                    RefreshUpdateStatus();
                    PluginCore.WriteToChat("Forced refresh completed");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Debug error: {ex.Message}");
            }
        }

        private void LoadCurrentSettings()
        {
            try
            {
                if (PluginSettings.IsInitialized)
                {
                    if (chkVitalSharingEnabled != null)
                        chkVitalSharingEnabled.Checked = PluginSettings.Instance.VitalSharingEnabled;
                    if (chkVerboseLogging != null)
                        chkVerboseLogging.Checked = PluginSettings.Instance.VerboseLogging;
                    if (chkRareMetaEnabled != null)
                        chkRareMetaEnabled.Checked = PluginSettings.Instance.RareMetaEnabled;
                    if (chkWebSocketEnabled != null)
                        chkWebSocketEnabled.Checked = PluginSettings.Instance.WebSocketEnabled;
                    if (chkAutoUpdateEnabled != null)
                        chkAutoUpdateEnabled.Checked = PluginSettings.Instance.AutoUpdateEnabled;
                    if (txtCharTag != null)
                        txtCharTag.Text = PluginSettings.Instance.CharTag ?? "default";
                    if (txtVTankPath != null)
                        txtVTankPath.Text = PluginSettings.Instance.VTankProfilesPath ?? "";
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error loading settings: {ex.Message}");
            }
        }
        #endregion

        #region Event Handlers - Statistics Tab
        private void OnResetStatsClick(object sender, EventArgs e)
        {
            try
            {
                PluginCore.RestartStats();
                sessionStartTime = DateTime.Now;
                bestHourlyKills = 0;
                UpdateStatistics();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error resetting stats: {ex.Message}");
            }
        }
        #endregion

        #region Event Handlers - Metas Tab
        private void OnRefreshMetasListClick(object sender, EventArgs e)
        {
            try
            {
                UpdateMetasPathLabel();
                UpdateMetasStatus("Status: refreshing remote file list...");

                System.Threading.Tasks.Task.Run(async () =>
                {
                    try
                    {
                        var count = await MetaSyncManager.RefreshCatalogAsync();
                        PopulateMetasList();
                        PopulateMetasSelection();
                        UpdateMetasLastCheckLabel();
                        UpdateMetasStatus($"Status: loaded {count} remote files");
                    }
                    catch (Exception ex)
                    {
                        UpdateMetasStatus("Status: refresh failed");
                        PluginCore.WriteToChat($"[Metas] Refresh failed: {ex.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Refresh command failed: {ex.Message}");
            }
        }

        private void OnCheckMetasUpdatesClick(object sender, EventArgs e)
        {
            try
            {
                UpdateMetasPathLabel();
                UpdateMetasStatus("Status: checking remote updates...");

                System.Threading.Tasks.Task.Run(async () =>
                {
                    try
                    {
                        var summary = await MetaSyncManager.CheckStatusesAsync();
                        PopulateMetasList();
                        PopulateMetasSelection();
                        UpdateMetasLastCheckLabel();
                        UpdateMetasStatus($"Status: {summary.upToDate} current, {summary.needsUpdate} updates, {summary.notDownloaded} missing, {summary.errors} errors");
                    }
                    catch (Exception ex)
                    {
                        UpdateMetasStatus("Status: update check failed");
                        PluginCore.WriteToChat($"[Metas] Update check failed: {ex.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Update check command failed: {ex.Message}");
            }
        }

        private void OnDownloadOutdatedMetasClick(object sender, EventArgs e)
        {
            try
            {
                UpdateMetasStatus("Status: downloading outdated files...");

                System.Threading.Tasks.Task.Run(async () =>
                {
                    try
                    {
                        var result = await MetaSyncManager.DownloadOutdatedAsync();
                        PopulateMetasList();
                        PopulateMetasSelection();
                        UpdateMetasLastCheckLabel();
                        UpdateMetasStatus($"Status: downloaded {result.downloaded}, skipped {result.skipped}, failed {result.failed}, backups {result.backups}");
                    }
                    catch (Exception ex)
                    {
                        UpdateMetasStatus("Status: pull outdated failed");
                        PluginCore.WriteToChat($"[Metas] Pull outdated failed: {ex.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Pull outdated command failed: {ex.Message}");
            }
        }

        private void OnDownloadSelectedMetaClick(object sender, EventArgs e)
        {
            try
            {
                string selection = GetSelectedMetaRelativePath();
                if (string.IsNullOrWhiteSpace(selection))
                {
                    PluginCore.WriteToChat("[Metas] Select a file first");
                    return;
                }

                UpdateMetasStatus($"Status: downloading {selection}...");

                System.Threading.Tasks.Task.Run(async () =>
                {
                    try
                    {
                        var result = await MetaSyncManager.DownloadFileAsync(selection);
                        PopulateMetasList();
                        PopulateMetasSelection();
                        UpdateMetasLastCheckLabel();
                        UpdateMetasStatus($"Status: {result.Message}");
                    }
                    catch (Exception ex)
                    {
                        UpdateMetasStatus("Status: download failed");
                        PluginCore.WriteToChat($"[Metas] Download failed: {ex.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Download command failed: {ex.Message}");
            }
        }

        private void OnMetasSearchChanged(object sender, EventArgs e)
        {
            try
            {
                _metasSearchText = txtMetasSearch?.Text?.Trim() ?? string.Empty;
                PopulateMetasList();
                PopulateMetasSelection();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Search failed: {ex.Message}");
            }
        }

        private void OnClearMetasSearchClick(object sender, EventArgs e)
        {
            try
            {
                _metasSearchText = string.Empty;
                if (txtMetasSearch != null)
                {
                    txtMetasSearch.Text = string.Empty;
                }

                PopulateMetasList();
                PopulateMetasSelection();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Clear search failed: {ex.Message}");
            }
        }
        #endregion

        #region Event Handlers - Flag Tracker Tab
        private void OnOpenFlagTrackerClick(object sender, EventArgs e)
        {
            try
            {
                // Open the Flag Tracker window
                FlagTrackerView.OpenFlagTracker();
                PluginCore.WriteToChat("Flag Tracker window opened");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error opening Flag Tracker: {ex.Message}");
            }
        }
        #endregion

        #region Event Handlers - Chest Looter Tab

        private void OnSetChestClick(object sender, EventArgs e)
        {
            try
            {
                var core = Decal.Adapter.CoreManager.Current;
                var chest = core.WorldFilter[core.Actions.CurrentSelection];
                if (chest == null)
                {
                    PluginCore.WriteToChat("[ChestLooter] No chest selected");
                    return;
                }

                if (chest.ObjectClass != Decal.Adapter.Wrappers.ObjectClass.Container)
                {
                    PluginCore.WriteToChat("[ChestLooter] Selected object is not a container");
                    return;
                }

                txtChestName.Text = chest.Name;
                if (PluginCore.chestLooter != null)
                {
                    PluginCore.chestLooter.SetChestName(chest.Name);
                }
                PluginCore.WriteToChat($"[ChestLooter] Chest set to: {chest.Name}");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[ChestLooter] Error setting chest: {ex.Message}");
            }
        }

        private void OnSetKeyClick(object sender, EventArgs e)
        {
            try
            {
                var core = Decal.Adapter.CoreManager.Current;
                var key = core.WorldFilter[core.Actions.CurrentSelection];
                if (key == null)
                {
                    PluginCore.WriteToChat("[ChestLooter] No key selected");
                    return;
                }

                if (key.ObjectClass != Decal.Adapter.Wrappers.ObjectClass.Key)
                {
                    PluginCore.WriteToChat("[ChestLooter] Selected object is not a key");
                    return;
                }

                txtKeyName.Text = key.Name;
                if (PluginCore.chestLooter != null)
                {
                    PluginCore.chestLooter.SetKeyName(key.Name);
                }
                PluginCore.WriteToChat($"[ChestLooter] Key set to: {key.Name}");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[ChestLooter] Error setting key: {ex.Message}");
            }
        }

        private void OnStartLooterClick(object sender, EventArgs e)
        {
            try
            {
                if (PluginCore.chestLooter == null)
                {
                    PluginCore.WriteToChat("[ChestLooter] Chest looter not initialized");
                    return;
                }

                string chestName = txtChestName?.Text ?? "";
                string keyName = txtKeyName?.Text ?? "";

                if (string.IsNullOrEmpty(chestName))
                {
                    PluginCore.WriteToChat("[ChestLooter] Please set chest name first");
                    return;
                }

                if (string.IsNullOrEmpty(keyName))
                {
                    PluginCore.WriteToChat("[ChestLooter] Please set key name first");
                    return;
                }

                bool started = PluginCore.chestLooter.StartByName(chestName, keyName);
                if (started)
                {
                    UpdateLooterStatus("Starting...");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[ChestLooter] Error starting looter: {ex.Message}");
            }
        }

        private void OnStopLooterClick(object sender, EventArgs e)
        {
            try
            {
                if (PluginCore.chestLooter != null)
                {
                    PluginCore.chestLooter.Stop();
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[ChestLooter] Error stopping looter: {ex.Message}");
            }
        }

        private void OnEnableChestsChanged(object sender, EventArgs e)
        {
            try
            {
                var settings = PluginSettings.Instance;
                if (settings?.ChestLooterSettings != null && chkEnableChests != null)
                {
                    settings.ChestLooterSettings.EnableChests = chkEnableChests.Checked;
                    PluginSettings.Save();
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[ChestLooter] Error changing enable chests: {ex.Message}");
            }
        }

        private void LoadChestLooterSettings()
        {
            try
            {
                if (!PluginSettings.IsInitialized)
                {
                    return;
                }

                var settings = PluginSettings.Instance?.ChestLooterSettings;
                if (settings != null)
                {
                    if (txtChestName != null)
                        txtChestName.Text = settings.ChestName ?? "";
                    if (txtKeyName != null)
                        txtKeyName.Text = settings.KeyName ?? "";
                    if (chkEnableChests != null)
                        chkEnableChests.Checked = settings.EnableChests;
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[ChestLooter] Error loading settings: {ex.Message}");
            }
        }

        private void UpdateLooterStatus(string status)
        {
            try
            {
                if (lblLooterStatus != null)
                {
                    lblLooterStatus.Text = $"Status: {status}";
                }
            }
            catch { }
        }

        public static void UpdateChestLooterStatus(string status)
        {
            try
            {
                if (instance != null)
                {
                    instance.UpdateLooterStatus(status);
                }
            }
            catch { }
        }

        /// <summary>
        /// Update chest/key text boxes from settings (called when set via command line)
        /// </summary>
        public static void RefreshChestLooterUI()
        {
            try
            {
                if (instance == null) return;

                var settings = PluginSettings.Instance?.ChestLooterSettings;
                if (settings != null)
                {
                    if (instance.txtChestName != null)
                        instance.txtChestName.Text = settings.ChestName ?? "";
                    if (instance.txtKeyName != null)
                        instance.txtKeyName.Text = settings.KeyName ?? "";
                }
            }
            catch { }
        }

        #endregion

        #region Event Handlers - Navigation Tab
        private void OnNavVisualizationEnabledChanged(object sender, EventArgs e)
        {
            try
            {
                if (PluginCore.navVisualization != null)
                {
                    PluginCore.navVisualization.SetEnabled(chkNavVisualizationEnabled.Checked);
                    UpdateNavigationStatus();
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in nav visualization change: {ex.Message}");
            }
        }

        private void OnRefreshNavFilesClick(object sender, EventArgs e)
        {
            try
            {
                RefreshNavFileList();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing nav files: {ex.Message}");
            }
        }

        private void OnLoadRouteClick(object sender, EventArgs e)
        {
            try
            {
                // Load from dropdown selection
                string routeName = null;
                
                if (cmbNavFiles != null && cmbNavFiles.Current >= 0 && cmbNavFiles.Count > 0 && 
                    cmbNavFiles.Current < cmbNavFiles.Count)
                {
                    routeName = ((HudStaticText)cmbNavFiles[cmbNavFiles.Current]).Text;
                }
                
                if (!string.IsNullOrEmpty(routeName) && routeName != "None")
                {
                    PluginCore.navVisualization.LoadRoute(routeName);
                    UpdateNavigationStatus();
                }
                else
                {
                    PluginCore.WriteToChat("[NavViz] Please select a route from the dropdown");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[NavViz] Error loading route: {ex.Message}");
            }
        }

        private void OnClearRouteClick(object sender, EventArgs e)
        {
            try
            {
                if (PluginCore.navVisualization != null)
                {
                    PluginCore.navVisualization.LoadRoute("None");
                    // Clear dropdown selection
                    if (cmbNavFiles != null && cmbNavFiles.Count > 0)
                    {
                        cmbNavFiles.Current = 0; // Select "None" which should be at index 0
                    }
                    UpdateNavigationStatus();
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error clearing route: {ex.Message}");
            }
        }

        private void InitializeNavigationSystem()
        {
            try
            {
                RefreshNavFileList();
                UpdateNavigationStatus();
                
                // Subscribe to route changes
                if (PluginCore.navVisualization != null)
                {
                    PluginCore.navVisualization.RouteChanged += (s, e) => UpdateNavigationStatus();
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing navigation system: {ex.Message}");
            }
        }

        private void RefreshNavFileList()
        {
            try
            {
                if (PluginCore.navVisualization != null)
                {
                    PluginCore.navVisualization.RefreshNavFileList();
                    
                    // Update the basic dropdown
                    PopulateNavFileDropdown();
                        
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing nav file list: {ex.Message}");
            }
        }

        private void UpdateNavigationStatus()
        {
            try
            {
                if (lblNavStatus != null && PluginCore.navVisualization != null)
                {
                    lblNavStatus.Text = $"Status: {PluginCore.navVisualization.GetStatus()}";
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error updating navigation status: {ex.Message}");
            }
        }
        #endregion

        #region Public Update Methods (maintain compatibility with existing code)
        public static void UpdateKillStats(int totalKills, double killsPer5Min, double killsPerHour)
        {
            try
            {
                if (instance == null) return;

                if (instance.lblTotalKills != null)
                    instance.lblTotalKills.Text = $"Total Kills: {totalKills}";
                if (instance.lblKillsPer5Min != null)
                    instance.lblKillsPer5Min.Text = $"Kills per 5 Min: {killsPer5Min:F2}";
                if (instance.lblKillsPerHour != null)
                    instance.lblKillsPerHour.Text = $"Kills per Hour: {killsPerHour:F2}";
                
                // Update detailed statistics
                if (instance.lblDetailedKillsValue != null)
                    instance.lblDetailedKillsValue.Text = totalKills.ToString();
                if (instance.lblAverageKillsValue != null)
                    instance.lblAverageKillsValue.Text = $"{killsPerHour:F2} kills/hr";
                
                // Track best hourly performance
                if (killsPerHour > instance.bestHourlyKills)
                {
                    instance.bestHourlyKills = killsPerHour;
                    if (instance.lblBestHourValue != null)
                        instance.lblBestHourValue.Text = $"{instance.bestHourlyKills:F2} kills/hr";
                }
                
                // Update status displays
                instance.UpdateStatus();
                instance.UpdateAutoLootRareIndicator();
                instance.UpdateWebSocketStatus();
                instance.UpdateStatistics();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in UpdateKillStats: {ex.Message}");
            }
        }

        public static void UpdateElapsedTime(TimeSpan elapsed)
        {
            try
            {
                if (instance?.lblElapsedTime != null)
                {
                    int days = elapsed.Days;
                    int hours = elapsed.Hours;
                    int minutes = elapsed.Minutes;
                    int seconds = elapsed.Seconds;

                    if (days > 0)
                        instance.lblElapsedTime.Text = $"Time: {days}d {hours:D2}:{minutes:D2}:{seconds:D2}";
                    else
                        instance.lblElapsedTime.Text = $"Time: {hours:D2}:{minutes:D2}:{seconds:D2}";
                }
                        
                if (instance?.lblSessionTimeValue != null && instance?.lblElapsedTime != null)
                {
                    instance.lblSessionTimeValue.Text = instance.lblElapsedTime.Text.Replace("Time: ", "");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in UpdateElapsedTime: {ex.Message}");
            }
        }

        public static void UpdateRareCount(int rareCount)
        {
            try
            {
                if (instance?.lblRareCount != null)
                    instance.lblRareCount.Text = $"Rare Count: {rareCount}";
                if (instance?.lblRareStatsValue != null)
                    instance.lblRareStatsValue.Text = rareCount.ToString();
                
                // Calculate rare drop rate
                int totalKills = PluginCore.totalKills;
                if (totalKills > 0 && instance?.lblRareRateValue != null)
                {
                    double rareRate = (double)rareCount / totalKills * 100;
                    instance.lblRareRateValue.Text = $"{rareRate:F2}%";
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in UpdateRareCount: {ex.Message}");
            }
        }

        public static void SetRareMetaToggleState(bool enabled)
        {
            try
            {
                if (instance?.chkRareMetaEnabled != null)
                    instance.chkRareMetaEnabled.Checked = enabled;
                instance?.UpdateAutoLootRareIndicator();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error setting rare meta toggle state: {ex.Message}");
            }
        }

        public static void RefreshSettingsFromConfig()
        {
            try
            {
                instance?.LoadCurrentSettings();
                instance?.UpdateAutoLootRareIndicator();
                instance?.UpdateWebSocketStatus();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing settings from config: {ex.Message}");
            }
        }

        public static void RestorePosition()
        {
            instance?.RestoreWindowPosition();
            instance?.KeepWindowInBounds();
        }
        #endregion

        #region Status Update Methods
        private void UpdateStatus()
        {
            try
            {
                if (lblStatus != null)
                {
                    string metaState = VtankControl.VtGetMetaState();
                    lblStatus.Text = $"Meta State: {metaState}";
                }
            }
            catch
            {
                if (lblStatus != null)
                    lblStatus.Text = "Meta State: Unknown";
            }
        }

        private void UpdateAutoLootRareIndicator()
        {
            try
            {
                if (lblAutoLootRare != null)
                {
                    bool isEnabled = PluginSettings.IsInitialized && PluginSettings.Instance.RareMetaEnabled;
                    if (isEnabled)
                    {
                        lblAutoLootRare.Text = "Auto Loot Rare: [ON]";
                        // Try to set green color for ON status
                        try { lblAutoLootRare.TextColor = System.Drawing.Color.FromArgb(0, 128, 0); } catch { }
                    }
                    else
                    {
                        lblAutoLootRare.Text = "Auto Loot Rare: [OFF]";
                        // Try to set red color for OFF status
                        try { lblAutoLootRare.TextColor = System.Drawing.Color.FromArgb(255, 0, 0); } catch { }
                    }
                }
            }
            catch
            {
                if (lblAutoLootRare != null)
                    lblAutoLootRare.Text = "Auto Loot Rare: Unknown";
            }
        }
        
        private void UpdateWebSocketStatus()
        {
            try
            {
                if (lblWebSocketStatus != null)
                {
                    bool isConnected = PluginSettings.IsInitialized && PluginSettings.Instance.WebSocketEnabled;
                    if (isConnected)
                    {
                        lblWebSocketStatus.Text = "WebSocket: [CONNECTED]";
                        // Try to set green color for CONNECTED status
                        try { lblWebSocketStatus.TextColor = System.Drawing.Color.FromArgb(0, 128, 0); } catch { }
                    }
                    else
                    {
                        lblWebSocketStatus.Text = "WebSocket: [DISCONNECTED]";
                        // Try to set red color for DISCONNECTED status
                        try { lblWebSocketStatus.TextColor = System.Drawing.Color.FromArgb(255, 0, 0); } catch { }
                    }
                }
            }
            catch
            {
                if (lblWebSocketStatus != null)
                    lblWebSocketStatus.Text = "WebSocket: Unknown";
            }
        }

        private void UpdateStatistics()
        {
            try
            {
                // Update last kill time
                if (lblLastKillValue != null)
                {
                    if (PluginCore.lastKillTime != DateTime.MinValue)
                    {
                        TimeSpan timeSinceLastKill = DateTime.Now - PluginCore.lastKillTime;
                        if (timeSinceLastKill.TotalMinutes < 60)
                            lblLastKillValue.Text = $"{timeSinceLastKill.TotalMinutes:F0} min ago";
                        else
                            lblLastKillValue.Text = $"{timeSinceLastKill.TotalHours:F1} hr ago";
                    }
                    else
                    {
                        lblLastKillValue.Text = "Never";
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in UpdateStatistics: {ex.Message}");
            }
        }
        #endregion

        #region Helper Methods
        private void PopulateNavFileDropdown()
        {
            try
            {
                if (cmbNavFiles != null && PluginCore.navVisualization != null)
                {
                    cmbNavFiles.Clear();
                    cmbNavFiles.AddItem("None", "None");
                    
                    foreach (string navFile in PluginCore.navVisualization.AvailableNavFiles)
                    {
                        cmbNavFiles.AddItem(navFile, navFile);
                    }
                    
                    if (cmbNavFiles.Count > 0)
                        cmbNavFiles.Current = 0; // Select "None" which should be at index 0
                        
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error populating nav file dropdown: {ex.Message}");
            }
        }

        private void PopulateMetasList()
        {
            try
            {
                if (lstMetasFiles == null)
                {
                    return;
                }

                lstMetasFiles.ClearRows();
                var files = ApplyMetasSearch(MetaSyncManager.GetCachedFiles())
                    .OrderBy(f => f.Status == MetaFileSyncStatus.NotDownloaded ? 0
                               : f.Status == MetaFileSyncStatus.UpdateAvailable ? 1
                               : f.Status == MetaFileSyncStatus.Error ? 2
                               : 3)
                    .ThenBy(f => f.RelativePath, StringComparer.OrdinalIgnoreCase)
                    .ToList();

                if (files == null || files.Count == 0)
                {
                    var emptyRow = lstMetasFiles.AddRow();
                    SafeSetListText(emptyRow, 0, "-");
                    SafeSetListText(emptyRow, 1, string.IsNullOrWhiteSpace(_metasSearchText) ? "No files loaded" : "No matches");
                    SafeSetListText(emptyRow, 2, string.IsNullOrWhiteSpace(_metasSearchText) ? "Click Refresh List" : "Try a different filter");
                    return;
                }

                foreach (var file in files)
                {
                    var row = lstMetasFiles.AddRow();
                    SafeSetListText(row, 0, file.Extension?.ToUpperInvariant() ?? "");
                    SafeSetListText(row, 1, file.RelativePath ?? file.FileName ?? "");
                    SafeSetListText(row, 2, file.StatusText ?? "Unknown");

                    Color color;
                    switch (file.Status)
                    {
                        case MetaFileSyncStatus.UpToDate:
                            color = Color.FromArgb(0, 128, 0);
                            break;
                        case MetaFileSyncStatus.UpdateAvailable:
                            color = Color.FromArgb(180, 110, 0);
                            break;
                        case MetaFileSyncStatus.NotDownloaded:
                            color = Color.FromArgb(0, 70, 160);
                            break;
                        case MetaFileSyncStatus.Error:
                            color = Color.FromArgb(180, 0, 0);
                            break;
                        default:
                            color = Color.White;
                            break;
                    }

                    SafeSetListColor(row, 2, color);
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Error populating list: {ex.Message}");
            }
        }

        private void PopulateMetasSelection()
        {
            try
            {
                if (cmbMetaSelection == null)
                {
                    return;
                }

                var previouslySelected = GetSelectedMetaRelativePath();
                var files = ApplyMetasSearch(MetaSyncManager.GetCachedFiles())
                    .OrderBy(x => x.RelativePath, StringComparer.OrdinalIgnoreCase)
                    .ToList();

                cmbMetaSelection.Clear();

                foreach (var file in files)
                {
                    var label = $"[{file.Extension}] {file.RelativePath}";
                    cmbMetaSelection.AddItem(label, file.RelativePath);
                }

                if (cmbMetaSelection.Count > 0)
                {
                    var selectedIndex = 0;
                    if (!string.IsNullOrWhiteSpace(previouslySelected))
                    {
                        for (int i = 0; i < cmbMetaSelection.Count; i++)
                        {
                            var value = ((HudStaticText)cmbMetaSelection[i]).Text;
                            if (!string.IsNullOrWhiteSpace(value) && value.EndsWith(previouslySelected, StringComparison.OrdinalIgnoreCase))
                            {
                                selectedIndex = i;
                                break;
                            }
                        }
                    }

                    cmbMetaSelection.Current = selectedIndex;
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[Metas] Error populating selection: {ex.Message}");
            }
        }

        private string GetSelectedMetaRelativePath()
        {
            try
            {
                if (cmbMetaSelection == null || cmbMetaSelection.Count == 0 || cmbMetaSelection.Current < 0 || cmbMetaSelection.Current >= cmbMetaSelection.Count)
                {
                    return string.Empty;
                }

                var text = ((HudStaticText)cmbMetaSelection[cmbMetaSelection.Current]).Text ?? string.Empty;
                var closeBracket = text.IndexOf(']');
                if (closeBracket >= 0 && closeBracket + 2 < text.Length)
                {
                    return text.Substring(closeBracket + 2).Trim();
                }

                return text.Trim();
            }
            catch
            {
                return string.Empty;
            }
        }

        private void UpdateMetasPathLabel()
        {
            try
            {
                if (lblMetasPath == null)
                {
                    return;
                }

                var path = MetaSyncManager.GetResolvedVtankPath();
                if (string.IsNullOrWhiteSpace(path))
                {
                    lblMetasPath.Text = "VTank Path: unresolved";
                }
                else
                {
                    lblMetasPath.Text = $"VTank Path: {path}";
                }
            }
            catch
            {
                if (lblMetasPath != null)
                {
                    lblMetasPath.Text = "VTank Path: unresolved";
                }
            }
        }

        private void UpdateMetasLastCheckLabel()
        {
            try
            {
                if (lblMetasLastCheck == null)
                {
                    return;
                }

                var ts = MetaSyncManager.LastStatusCheckUtc != DateTime.MinValue
                    ? MetaSyncManager.LastStatusCheckUtc.ToLocalTime()
                    : MetaSyncManager.LastCatalogRefreshUtc.ToLocalTime();

                if (ts == DateTime.MinValue)
                {
                    lblMetasLastCheck.Text = "Last Check: never";
                }
                else
                {
                    lblMetasLastCheck.Text = $"Last Check: {ts:yyyy-MM-dd HH:mm:ss}";
                }
            }
            catch
            {
                if (lblMetasLastCheck != null)
                {
                    lblMetasLastCheck.Text = "Last Check: unknown";
                }
            }
        }

        private void UpdateMetasStatus(string text)
        {
            try
            {
                if (lblMetasStatus != null)
                {
                    lblMetasStatus.Text = text ?? "Status: idle";
                }
            }
            catch
            {
            }
        }

        private System.Collections.Generic.IReadOnlyList<MetaFileEntry> ApplyMetasSearch(System.Collections.Generic.IReadOnlyList<MetaFileEntry> files)
        {
            if (files == null || files.Count == 0)
            {
                return files;
            }

            var filter = _metasSearchText?.Trim();
            if (string.IsNullOrWhiteSpace(filter))
            {
                return files;
            }

            return files
                .Where(f => (!string.IsNullOrWhiteSpace(f.RelativePath) && f.RelativePath.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
                         || (!string.IsNullOrWhiteSpace(f.FileName) && f.FileName.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0))
                .ToList();
        }

        private void SafeSetListText(HudList.HudListRowAccessor row, int columnIndex, string text)
        {
            try
            {
                if (row != null && columnIndex >= 0)
                {
                    try
                    {
                        var control = row[columnIndex];
                        if (control != null)
                        {
                            ((HudStaticText)control).Text = text ?? string.Empty;
                        }
                    }
                    catch
                    {
                    }
                }
            }
            catch
            {
            }
        }

        private void SafeSetListColor(HudList.HudListRowAccessor row, int columnIndex, Color color)
        {
            try
            {
                if (row != null && columnIndex >= 0 && row[columnIndex] != null)
                {
                    ((HudStaticText)row[columnIndex]).TextColor = color;
                }
            }
            catch
            {
            }
        }
        #endregion

        #region IDisposable Override
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                try
                {
                    // Unsubscribe from events to prevent memory leaks
                    
                    // Settings tab event cleanup
                    if (chkRareMetaEnabled != null)
                        chkRareMetaEnabled.Change -= OnRareMetaSettingChanged;
                    if (chkWebSocketEnabled != null)
                        chkWebSocketEnabled.Change -= OnWebSocketSettingChanged;
                    if (chkAutoUpdateEnabled != null)
                        chkAutoUpdateEnabled.Change -= OnAutoUpdateSettingChanged;
                    if (txtCharTag != null)
                        txtCharTag.Change -= OnCharTagChanged;
                    if (txtVTankPath != null)
                        txtVTankPath.Change -= OnVTankPathChanged;
                    if (btnCheckUpdate != null)
                        btnCheckUpdate.Hit -= OnCheckUpdateClicked;
                    if (btnInstallUpdate != null)
                        btnInstallUpdate.Hit -= OnInstallUpdateClicked;
                    
                    // Statistics tab event cleanup
                    if (btnResetStats != null)
                        btnResetStats.Hit -= OnResetStatsClick;
                    
                    // Navigation tab event cleanup
                    if (chkNavVisualizationEnabled != null)
                        chkNavVisualizationEnabled.Change -= OnNavVisualizationEnabledChanged;
                    if (btnRefreshNavFiles != null)
                        btnRefreshNavFiles.Hit -= OnRefreshNavFilesClick;
                    if (btnLoadRoute != null)
                        btnLoadRoute.Hit -= OnLoadRouteClick;
                    if (btnClearRoute != null)
                        btnClearRoute.Hit -= OnClearRouteClick;

                    if (btnRefreshMetasList != null)
                        btnRefreshMetasList.Hit -= OnRefreshMetasListClick;
                    if (btnCheckMetasUpdates != null)
                        btnCheckMetasUpdates.Hit -= OnCheckMetasUpdatesClick;
                    if (btnDownloadOutdatedMetas != null)
                        btnDownloadOutdatedMetas.Hit -= OnDownloadOutdatedMetasClick;
                    if (txtMetasSearch != null)
                        txtMetasSearch.Change -= OnMetasSearchChanged;
                    if (btnClearMetasSearch != null)
                        btnClearMetasSearch.Hit -= OnClearMetasSearchClick;
                    if (btnDownloadSelectedMeta != null)
                        btnDownloadSelectedMeta.Hit -= OnDownloadSelectedMetaClick;
                    
                    // No enhanced events to clean up
                }
                catch (Exception ex)
                {
                    PluginCore.WriteToChat($"Error cleaning up VVS view events: {ex.Message}");
                }
            }

            // Call base dispose
            base.Dispose(disposing);
        }
        #endregion
    }
}
