using System;
using System.Linq;
using System.Timers;

namespace MosswartMassacre
{
    /// <summary>
    /// Streams high-priority quest timer data via WebSocket on a 30-second interval.
    /// </summary>
    internal class QuestStreamingService
    {
        private readonly IPluginLogger _logger;
        private Timer _timer;

        internal QuestStreamingService(IPluginLogger logger)
        {
            _logger = logger;
        }

        internal void Start()
        {
            _timer = new Timer(Constants.QuestStreamingIntervalMs);
            _timer.Elapsed += OnTimerElapsed;
            _timer.AutoReset = true;
            _timer.Start();
        }

        internal void Stop()
        {
            if (_timer != null)
            {
                _timer.Stop();
                _timer.Elapsed -= OnTimerElapsed;
                _timer.Dispose();
                _timer = null;
            }
        }

        internal bool IsRunning => _timer != null && _timer.Enabled;

        private void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                if (PluginSettings.Instance?.VerboseLogging == true)
                {
                    _logger?.Log("[QUEST-STREAM] Timer fired, checking conditions...");
                }

                if (!PluginCore.WebSocketEnabled)
                {
                    if (PluginSettings.Instance?.VerboseLogging == true)
                    {
                        _logger?.Log("[QUEST-STREAM] WebSocket not enabled, skipping");
                    }
                    return;
                }

                var questManager = PluginCore.questManager;
                if (questManager?.QuestList == null || questManager.QuestList.Count == 0)
                {
                    if (PluginSettings.Instance?.VerboseLogging == true)
                    {
                        _logger?.Log($"[QUEST-STREAM] No quest data available (null: {questManager?.QuestList == null}, count: {questManager?.QuestList?.Count ?? 0})");
                    }
                    return;
                }

                var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

                var priorityQuests = questManager.QuestList
                    .Where(q => IsHighPriorityQuest(q.Id))
                    .GroupBy(q => q.Id)
                    .Select(g => g.First())
                    .ToList();

                if (PluginSettings.Instance?.VerboseLogging == true)
                {
                    _logger?.Log($"[QUEST-STREAM] Found {priorityQuests.Count} priority quests to stream");
                }

                foreach (var quest in priorityQuests)
                {
                    try
                    {
                        string questName = questManager.GetFriendlyQuestName(quest.Id);
                        long timeRemaining = quest.ExpireTime - currentTime;
                        string countdown = FormatCountdown(timeRemaining);

                        if (PluginSettings.Instance?.VerboseLogging == true)
                        {
                            _logger?.Log($"[QUEST-STREAM] Sending: {questName} - {countdown}");
                        }

                        System.Threading.Tasks.Task.Run(() => WebSocket.SendQuestDataAsync(questName, countdown));
                    }
                    catch (Exception ex)
                    {
                        _logger?.Log($"[QUEST-STREAM] Error streaming quest {quest.Id}: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger?.Log($"[QUEST-STREAM] Error in timer handler: {ex.Message}");
            }
        }

        internal static bool IsHighPriorityQuest(string questId)
        {
            return questId == "stipendtimer_0812" ||
                   questId == "augmentationblankgemacquired" ||
                   questId == "insatiableeaterjaw";
        }

        internal static 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";
        }
    }
}
