using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using VirindiViewService.Controls;

namespace MosswartMassacre.Views
{
    /// <summary>
    /// Dedicated Flag Tracker window with comprehensive character tracking
    /// Ported from UBS Lua flagtracker with full functionality preservation
    /// </summary>
    internal class FlagTrackerView : VVSBaseView
    {
        private static FlagTrackerView instance;
        
        #region Tab Control References
        private HudTabView mainTabView;
        
        // Augmentations Tab
        private HudList lstAugmentations;
        private HudButton btnRefreshAugs;
        
        // Luminance Tab
        private HudList lstLuminanceAuras;
        private HudButton btnRefreshLum;
        
        // Recalls Tab
        private HudList lstRecallSpells;
        private HudButton btnRefreshRecalls;
        
        
        // Cantrips Tab
        private HudList lstCantrips;
        private HudButton btnRefreshCantrips;
        
        // Quests Tab
        private HudList lstQuests;
        private HudButton btnRefreshQuests;
        
        #endregion

        #region Data Management
        private FlagTrackerData data;
        private System.Timers.Timer questUpdateTimer;
        #endregion

        public FlagTrackerView(PluginCore core) : base(core)
        {
            try
            {
                instance = this;
                data = new FlagTrackerData();
                
                // Initialize quest update timer for real-time countdown
                questUpdateTimer = new System.Timers.Timer(5000); // Update every 5 seconds
                questUpdateTimer.Elapsed += OnQuestTimerUpdate;
                questUpdateTimer.AutoReset = true;
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[MossyTracker] Failed to initialize: {ex.Message}");
            }
        }

        #region Static Interface
        public static void OpenFlagTracker()
        {
            try
            {
                if (instance == null)
                {
                    instance = new FlagTrackerView(null);
                    instance.InitializeView();
                }
                else
                {
                    // Bring existing window to front
                    if (instance.view != null)
                    {
                        instance.view.Visible = true;
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error opening Flag Tracker: {ex.Message}");
            }
        }

        public static void CloseFlagTracker()
        {
            try
            {
                if (instance != null)
                {
                    instance.Dispose();
                    instance = null;
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error closing Flag Tracker: {ex.Message}");
            }
        }

        public static bool IsOpen()
        {
            return instance != null && instance.view != null && instance.view.Visible;
        }

        public static void RefreshQuestData()
        {
            try
            {
                if (PluginCore.questManager != null)
                {
                    PluginCore.questManager.RefreshQuests();
                    
                    // If Flag Tracker window is open, also refresh the UI
                    if (instance != null)
                    {
                        instance.PopulateQuestsList();
                        
                        // Schedule another refresh in a few seconds to catch any data
                        System.Threading.Timer refreshTimer = null;
                        refreshTimer = new System.Threading.Timer(_ =>
                        {
                            try
                            {
                                if (instance != null)
                                {
                                    instance.PopulateQuestsList();
                                }
                            }
                            catch (Exception timerEx)
                            {
                                PluginCore.WriteToChat($"[MossyTracker] Delayed refresh failed: {timerEx.Message}");
                            }
                            finally
                            {
                                refreshTimer?.Dispose();
                            }
                        }, null, 4000, System.Threading.Timeout.Infinite);
                    }
                }
                else
                {
                    PluginCore.WriteToChat("[MossyTracker] Quest manager not available for refresh");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[MossyTracker] Quest refresh failed: {ex.Message}");
            }
        }
        #endregion

        #region Initialization
        private void InitializeView()
        {
            try
            {
                CreateFromXMLResource("MosswartMassacre.ViewXML.flagTracker.xml");
                
                if (view == null)
                {
                    PluginCore.WriteToChat("[MossyTracker] Failed to create view");
                    return;
                }

                InitializeTabControls();
                InitializeEventHandlers();
                Initialize();
                
                if (view != null)
                {
                    view.Visible = true;
                    view.ShowInBar = true;
                    view.Title = "Mossy Tracker";
                }

                RefreshAllData();
                
                // Start quest update timer
                if (questUpdateTimer != null)
                {
                    questUpdateTimer.Start();
                }
                
                PluginCore.WriteToChat("[MossyTracker] Initialized successfully");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[MossyTracker] Failed to initialize: {ex.Message}");
            }
        }

        private void InitializeTabControls()
        {
            try
            {
                mainTabView = GetControl<HudTabView>("mainTabView");
                lstAugmentations = GetControl<HudList>("lstAugmentations");
                btnRefreshAugs = GetControl<HudButton>("btnRefreshAugs");
                lstLuminanceAuras = GetControl<HudList>("lstLuminanceAuras");
                btnRefreshLum = GetControl<HudButton>("btnRefreshLum");
                lstRecallSpells = GetControl<HudList>("lstRecallSpells");
                btnRefreshRecalls = GetControl<HudButton>("btnRefreshRecalls");
                lstCantrips = GetControl<HudList>("lstCantrips");
                btnRefreshCantrips = GetControl<HudButton>("btnRefreshCantrips");
                lstQuests = GetControl<HudList>("lstQuests");
                btnRefreshQuests = GetControl<HudButton>("btnRefreshQuests");
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[MossyTracker] Failed to initialize controls: {ex.Message}");
            }
        }

        private void InitializeEventHandlers()
        {
            try
            {
                // Refresh button events
                if (btnRefreshAugs != null) btnRefreshAugs.Hit += OnRefreshAugmentations;
                if (btnRefreshLum != null) btnRefreshLum.Hit += OnRefreshLuminance;
                if (btnRefreshRecalls != null) btnRefreshRecalls.Hit += OnRefreshRecalls;
                if (btnRefreshCantrips != null) btnRefreshCantrips.Hit += OnRefreshCantrips;
                if (btnRefreshQuests != null) btnRefreshQuests.Hit += OnRefreshQuests;
                
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error initializing event handlers: {ex.Message}");
            }
        }
        #endregion

        #region Window Management Overrides
        protected override void View_VisibleChanged(object sender, EventArgs e)
        {
            try
            {
                // Call base implementation first
                base.View_VisibleChanged(sender, e);
                
                // If window becomes invisible and we're not already disposed, dispose it
                // This handles the X button click case
                if (view != null && !view.Visible && !_disposed)
                {
                    // Use a small delay to ensure this isn't just a temporary hide
                    System.Threading.Timer disposeTimer = null;
                    disposeTimer = new System.Threading.Timer(_ =>
                    {
                        try
                        {
                            // Double-check the window is still hidden and not disposed
                            if (view != null && !view.Visible && !_disposed)
                            {
                                Dispose();
                            }
                        }
                        catch (Exception ex)
                        {
                            PluginCore.WriteToChat($"Error in delayed disposal: {ex.Message}");
                        }
                        finally
                        {
                            disposeTimer?.Dispose();
                        }
                    }, null, 100, System.Threading.Timeout.Infinite); // 100ms delay
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error in FlagTracker VisibleChanged: {ex.Message}");
            }
        }
        #endregion

        #region Timer Event Handlers
        private void OnQuestTimerUpdate(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                // Update quest list display if quests tab is visible and we have quest data
                if (view != null && view.Visible && PluginCore.questManager?.QuestList != null && PluginCore.questManager.QuestList.Count > 0)
                {
                    // Only update the quest list to refresh countdown timers
                    PopulateQuestsList();
                }
            }
            catch (Exception)
            {
                // Silently handle timer update errors to avoid spam
            }
        }
        
        #endregion

        #region Event Handlers
        private void OnRefreshAugmentations(object sender, EventArgs e)
        {
            try
            {
                data.RefreshAugmentations();
                PopulateAugmentationsList();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing augmentations: {ex.Message}");
            }
        }

        private void OnRefreshLuminance(object sender, EventArgs e)
        {
            try
            {
                data.RefreshLuminanceAuras();
                PopulateLuminanceList();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing luminance auras: {ex.Message}");
            }
        }

        private void OnRefreshRecalls(object sender, EventArgs e)
        {
            try
            {
                data.RefreshRecallSpells();
                PopulateRecallsList();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing recall spells: {ex.Message}");
            }
        }


        private void OnRefreshCantrips(object sender, EventArgs e)
        {
            try
            {
                data.RefreshCantrips();
                PopulateCantripsList();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error refreshing cantrips: {ex.Message}");
            }
        }

        private void OnRefreshQuests(object sender, EventArgs e)
        {
            try
            {
                if (PluginCore.questManager != null)
                {
                    PluginCore.questManager.RefreshQuests();
                    PopulateQuestsList();
                    
                    // Schedule another refresh in a few seconds to catch any data
                    System.Threading.Timer refreshTimer = null;
                    refreshTimer = new System.Threading.Timer(_ =>
                    {
                        try
                        {
                            PopulateQuestsList();
                        }
                        catch (Exception timerEx)
                        {
                            PluginCore.WriteToChat($"[MossyTracker] Refresh failed: {timerEx.Message}");
                        }
                        finally
                        {
                            refreshTimer?.Dispose();
                        }
                    }, null, 4000, System.Threading.Timeout.Infinite);
                }
                else
                {
                    PluginCore.WriteToChat("[MossyTracker] Quest manager not available");
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[MossyTracker] Refresh failed: {ex.Message}");
            }
        }

        #endregion

        #region Helper Methods
        private void SafeSetListText(HudList.HudListRowAccessor row, int columnIndex, string text)
        {
            try
            {
                if (row != null && columnIndex >= 0)
                {
                    // Check if the column exists
                    try
                    {
                        var control = row[columnIndex];
                        if (control != null)
                        {
                            ((HudStaticText)control).Text = text ?? "";
                        }
                        // Column control is null - ignore silently
                    }
                    catch (IndexOutOfRangeException)
                    {
                        // Column doesn't exist - ignore silently
                    }
                }
                // Invalid parameters - ignore silently
            }
            catch
            {
                // Ignore text setting errors silently
            }
        }
        
        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 (Exception ex)
            {
                PluginCore.WriteToChat($"Error setting list color at column {columnIndex}: {ex.Message}");
            }
        }
        
        private void SafeSetListImage(HudList.HudListRowAccessor row, int columnIndex, int iconId)
        {
            try
            {
                if (row != null && columnIndex >= 0)
                {
                    try
                    {
                        var control = row[columnIndex];
                        
                        if (control != null && control is VirindiViewService.Controls.HudPictureBox)
                        {
                            var pictureBox = (VirindiViewService.Controls.HudPictureBox)control;
                            pictureBox.Image = iconId;
                        }
                    }
                    catch (IndexOutOfRangeException)
                    {
                        // Column doesn't exist - ignore silently
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error setting list image at column {columnIndex}: {ex.Message}");
            }
        }
        
        private string GetIconSymbol(string category)
        {
            switch (category)
            {
                case "Basic Recalls":
                    return "[B]"; // Basic recalls
                case "Island Recalls":
                    return "[I]"; // Island recalls
                case "Town Recalls": 
                    return "[T]"; // Town recalls
                case "Special Recalls":
                    return "[S]"; // Special recalls
                default:
                    return "[?]"; // Unknown category
            }
        }
        
        private string FormatCountdown(long seconds)
        {
            if (seconds <= 0)
                return "READY";
                
            var timeSpan = TimeSpan.FromSeconds(seconds);
            
            if (timeSpan.TotalDays >= 1)
                return $"{(int)timeSpan.TotalDays}d {timeSpan.Hours:D2}h";
            else if (timeSpan.TotalHours >= 1)
                return $"{timeSpan.Hours}h {timeSpan.Minutes:D2}m";
            else if (timeSpan.TotalMinutes >= 1)
                return $"{timeSpan.Minutes}m {timeSpan.Seconds:D2}s";
            else
                return $"{timeSpan.Seconds}s";
        }
        
        #endregion

        #region Data Population Methods
        private void RefreshAllData()
        {
            try
            {
                if (PluginCore.questManager != null)
                {
                    PluginCore.questManager.RefreshQuests();
                }
                
                if (data != null)
                {
                    try
                    {
                        data.RefreshAll();
                    }
                    catch (Exception dataEx)
                    {
                        PluginCore.WriteToChat($"[MossyTracker] Data refresh failed: {dataEx.Message}");
                    }
                }
                
                PopulateAugmentationsList();
                PopulateLuminanceList();
                PopulateRecallsList();
                PopulateCantripsList();
                PopulateQuestsList();
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"[MossyTracker] Refresh failed: {ex.Message}");
            }
        }

        private void PopulateAugmentationsList()
        {
            try
            {
                if (lstAugmentations == null) return;
                
                lstAugmentations.ClearRows();
                
                if (data?.AugmentationCategories == null)
                {
                    var row = lstAugmentations.AddRow();
                    SafeSetListText(row, 0, "No augmentation data available");
                    SafeSetListText(row, 1, "Click Refresh to load data");
                    SafeSetListText(row, 2, "");
                    SafeSetListText(row, 3, "");
                    return;
                }
                
                foreach (var category in data.AugmentationCategories)
                {
                    // Add category header
                    var headerRow = lstAugmentations.AddRow();
                    SafeSetListText(headerRow, 0, $"--- {category.Key} ---");
                    SafeSetListText(headerRow, 1, "");
                    SafeSetListText(headerRow, 2, "");
                    SafeSetListText(headerRow, 3, "");
                    
                    // Add augmentations in this category
                    foreach (var aug in category.Value)
                    {
                        var row = lstAugmentations.AddRow();
                        
                        // Augmentation name with progress indicator
                        string progressText = aug.IsMaxed ? "[MAX]" : $"[{aug.CurrentValue}/{aug.Repeatable}]";
                        SafeSetListText(row, 0, aug.Name);
                        SafeSetListText(row, 1, progressText);
                        SafeSetListText(row, 2, aug.Trainer);
                        SafeSetListText(row, 3, aug.Location);
                        
                        // Color code based on completion status
                        Color progressColor = Color.Red;
                        if (aug.IsMaxed)
                        {
                            progressColor = Color.Green;
                        }
                        else if (aug.CurrentValue > 0)
                        {
                            progressColor = Color.Yellow;
                        }
                        
                        // Apply color to progress text
                        SafeSetListColor(row, 1, progressColor);
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error populating augmentations list: {ex.Message}");
            }
        }

        private void PopulateLuminanceList()
        {
            try
            {
                if (lstLuminanceAuras == null || data?.LuminanceAuraCategories == null) return;
                
                lstLuminanceAuras.ClearRows();
                
                foreach (var category in data.LuminanceAuraCategories)
                {
                    // Add category header
                    var headerRow = lstLuminanceAuras.AddRow();
                    SafeSetListText(headerRow, 0, $"--- {category.Key} ---");
                    SafeSetListText(headerRow, 1, "");
                    SafeSetListText(headerRow, 2, "");
                    
                    // Add luminance auras in this category
                    foreach (var aura in category.Value)
                    {
                        var row = lstLuminanceAuras.AddRow();
                        
                        // Aura name
                        SafeSetListText(row, 0, aura.Name);
                        
                        // Progress (current/cap)
                        string progressText = $"{aura.CurrentValue}/{aura.Cap}";
                        SafeSetListText(row, 1, progressText);
                        
                        // Category or quest flag for Seer auras
                        string categoryText = category.Key == "Seer Auras" && !string.IsNullOrEmpty(aura.QuestFlag) 
                            ? aura.QuestFlag 
                            : category.Key;
                        SafeSetListText(row, 2, categoryText);
                        
                        // Color code based on progress
                        Color progressColor = Color.Red;
                        if (aura.CurrentValue >= aura.Cap)
                        {
                            progressColor = Color.Green;
                        }
                        else if (aura.CurrentValue > 0)
                        {
                            progressColor = Color.Yellow;
                        }
                        
                        // Apply color to progress text
                        SafeSetListColor(row, 1, progressColor);
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error populating luminance list: {ex.Message}");
            }
        }

        private void PopulateRecallsList()
        {
            try
            {
                if (lstRecallSpells == null) return;
                
                lstRecallSpells.ClearRows();
                
                if (data?.RecallSpells == null)
                {
                    var row = lstRecallSpells.AddRow();
                    SafeSetListImage(row, 0, 0x6002D14); // Default portal icon
                    SafeSetListText(row, 1, "No recall data available - Click Refresh");
                    SafeSetListText(row, 2, "Loading...");
                    return;
                }
                
                foreach (var recall in data.RecallSpells)
                {
                    var row = lstRecallSpells.AddRow();
                    
                    
                    // Column 0: Spell icon using MagTools approach
                    SafeSetListImage(row, 0, recall.IconId);
                    
                    // Column 1: Recall spell name
                    SafeSetListText(row, 1, recall.Name);
                    
                    // Column 2: Known status
                    string status = recall.IsKnown ? "Known" : "Unknown";
                    SafeSetListText(row, 2, status);
                    
                    // Color code based on known status
                    Color statusColor = recall.IsKnown ? Color.Green : Color.Red;
                    SafeSetListColor(row, 2, statusColor);
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error populating recalls list: {ex.Message}");
            }
        }


        private void PopulateCantripsList()
        {
            try
            {
                if (lstCantrips == null || data?.Cantrips == null) return;
                
                lstCantrips.ClearRows();
                
                foreach (var category in data.Cantrips)
                {
                    // Add category header
                    var headerRow = lstCantrips.AddRow();
                    SafeSetListImage(headerRow, 0, 0x6002856); // Star icon for category headers
                    SafeSetListText(headerRow, 1, $"--- {category.Key} ---");
                    SafeSetListText(headerRow, 2, "");
                    
                    // Add cantrips in this category
                    foreach (var cantrip in category.Value)
                    {
                        var row = lstCantrips.AddRow();
                        
                        // Column 0: Icon (green/red circle based on status)
                        SafeSetListImage(row, 0, cantrip.Value.ComputedIconId);
                        
                        // Column 1: Skill/Attribute name
                        SafeSetListText(row, 1, cantrip.Key);
                        
                        // Column 2: Cantrip level
                        SafeSetListText(row, 2, cantrip.Value.Value);
                        
                        // Apply color coding based on cantrip level
                        SafeSetListColor(row, 2, cantrip.Value.Color);
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error populating cantrips list: {ex.Message}");
            }
        }

        private void PopulateQuestsList()
        {
            try
            {
                if (lstQuests == null) return;
                
                lstQuests.ClearRows();
                
                // Add column headers - New order: Quest Name, Countdown, Last Solved, Cooldown, Solves
                var headerRow = lstQuests.AddRow();
                SafeSetListText(headerRow, 0, "--- Quest Name ---");
                SafeSetListText(headerRow, 1, "Countdown");
                SafeSetListText(headerRow, 2, "Last Solved");
                SafeSetListText(headerRow, 3, "Cooldown");
                SafeSetListText(headerRow, 4, "Solves");
                
                if (PluginCore.questManager?.QuestList != null && PluginCore.questManager.QuestList.Count > 0)
                {
                    var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                    
                    // Filter out maxed quests and sort by solve count (highest to lowest)
                    var visibleQuests = PluginCore.questManager.QuestList
                        .Where(q => !(q.MaxSolves > 0 && q.Solves >= q.MaxSolves)) // Hide maxed quests
                        .OrderByDescending(q => q.Solves)
                        .ThenBy(q => PluginCore.questManager.GetFriendlyQuestName(q.Id));
                    
                    foreach (var quest in visibleQuests)
                    {
                        var questRow = lstQuests.AddRow();
                        
                        // Column 0: Quest Name (friendly name only, wider)
                        string questName = PluginCore.questManager.GetFriendlyQuestName(quest.Id);
                        SafeSetListText(questRow, 0, questName);
                        
                        // Column 1: Countdown Timer
                        long timeRemaining = quest.ExpireTime - currentTime;
                        string countdownText = FormatCountdown(timeRemaining);
                        SafeSetListText(questRow, 1, countdownText);
                        
                        // Column 2: Last Solved (date) - moved from Column 3
                        SafeSetListText(questRow, 2, PluginCore.questManager.FormatTimeStamp(quest.Timestamp));
                        
                        // Column 3: Cooldown (formatted duration) - moved from Column 4
                        SafeSetListText(questRow, 3, PluginCore.questManager.FormatSeconds(quest.Delta));
                        
                        // Column 4: Solves (white text) - moved from Column 5
                        SafeSetListText(questRow, 4, quest.Solves.ToString());
                        SafeSetListColor(questRow, 4, System.Drawing.Color.White);
                        
                        // Color code the countdown based on availability
                        if (quest.ExpireTime <= currentTime)
                        {
                            SafeSetListColor(questRow, 1, System.Drawing.Color.Green); // Ready - green countdown
                        }
                        else
                        {
                            SafeSetListColor(questRow, 1, System.Drawing.Color.Yellow); // On cooldown - yellow countdown
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                PluginCore.WriteToChat($"Error populating quests list: {ex.Message}");
            }
        }
        #endregion


        #region Cleanup
        private bool _disposed = false;
        
        protected override void Dispose(bool disposing)
        {
            if (_disposed) return; // Prevent double disposal
            
            if (disposing)
            {
                try
                {
                    // Clear static instance reference if this is the current instance
                    if (instance == this)
                    {
                        instance = null;
                    }
                    
                    // Event handlers will be cleaned up by base class
                    
                    // Remove button event handlers
                    if (btnRefreshAugs != null) btnRefreshAugs.Hit -= OnRefreshAugmentations;
                    if (btnRefreshLum != null) btnRefreshLum.Hit -= OnRefreshLuminance;
                    if (btnRefreshRecalls != null) btnRefreshRecalls.Hit -= OnRefreshRecalls;
                    if (btnRefreshCantrips != null) btnRefreshCantrips.Hit -= OnRefreshCantrips;
                    if (btnRefreshQuests != null) btnRefreshQuests.Hit -= OnRefreshQuests;
                    
                    if (data != null)
                    {
                        data.Dispose();
                        data = null;
                    }
                    
                    // Stop and dispose quest update timer
                    if (questUpdateTimer != null)
                    {
                        questUpdateTimer.Stop();
                        questUpdateTimer.Elapsed -= OnQuestTimerUpdate;
                        questUpdateTimer.Dispose();
                        questUpdateTimer = null;
                    }
                    
                    _disposed = true;
                }
                catch (Exception ex)
                {
                    PluginCore.WriteToChat($"Error disposing Flag Tracker: {ex.Message}");
                }
            }
            
            base.Dispose(disposing);
        }
        #endregion
    }
}