using System;
using System.Text.RegularExpressions;
using System.Timers;

namespace MosswartMassacre
{
    /// <summary>
    /// Tracks kills, deaths, and kill rate calculations.
    /// Owns the 1-second stats update timer.
    /// </summary>
    internal class KillTracker
    {
        private readonly IPluginLogger _logger;
        private readonly Action<int, double, double> _onStatsUpdated;
        private readonly Action<TimeSpan> _onElapsedUpdated;

        private int _totalKills;
        private int _sessionDeaths;
        private int _totalDeaths;
        private double _killsPer5Min;
        private double _killsPerHour;
        private DateTime _lastKillTime = DateTime.Now;
        private DateTime _statsStartTime = DateTime.Now;
        private Timer _updateTimer;

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

        internal int TotalKills => _totalKills;
        internal double KillsPerHour => _killsPerHour;
        internal double KillsPer5Min => _killsPer5Min;
        internal int SessionDeaths => _sessionDeaths;
        internal int TotalDeaths => _totalDeaths;
        internal DateTime StatsStartTime => _statsStartTime;
        internal DateTime LastKillTime => _lastKillTime;
        internal int RareCount { get; set; }

        /// <param name="logger">Logger for chat output</param>
        /// <param name="onStatsUpdated">Callback(totalKills, killsPer5Min, killsPerHour) for UI updates</param>
        /// <param name="onElapsedUpdated">Callback(elapsed) for UI elapsed time updates</param>
        internal KillTracker(IPluginLogger logger, Action<int, double, double> onStatsUpdated, Action<TimeSpan> onElapsedUpdated)
        {
            _logger = logger;
            _onStatsUpdated = onStatsUpdated;
            _onElapsedUpdated = onElapsedUpdated;
        }

        internal void Start()
        {
            _updateTimer = new Timer(Constants.StatsUpdateIntervalMs);
            _updateTimer.Elapsed += UpdateStats;
            _updateTimer.Start();
        }

        internal void Stop()
        {
            if (_updateTimer != null)
            {
                _updateTimer.Stop();
                _updateTimer.Dispose();
                _updateTimer = null;
            }
        }

        internal bool CheckForKill(string text)
        {
            if (IsKilledByMeMessage(text))
            {
                _totalKills++;
                _lastKillTime = DateTime.Now;
                CalculateKillsPerInterval();
                _onStatsUpdated?.Invoke(_totalKills, _killsPer5Min, _killsPerHour);
                return true;
            }
            return false;
        }

        internal void OnDeath()
        {
            _sessionDeaths++;
        }

        internal void SetTotalDeaths(int totalDeaths)
        {
            _totalDeaths = totalDeaths;
        }

        internal void RestartStats()
        {
            _totalKills = 0;
            RareCount = 0;
            _sessionDeaths = 0;
            _statsStartTime = DateTime.Now;
            _killsPer5Min = 0;
            _killsPerHour = 0;

            _logger?.Log($"Stats have been reset. Session deaths: {_sessionDeaths}, Total deaths: {_totalDeaths}");
            _onStatsUpdated?.Invoke(_totalKills, _killsPer5Min, _killsPerHour);
        }

        private void UpdateStats(object sender, ElapsedEventArgs e)
        {
            try
            {
                TimeSpan elapsed = DateTime.Now - _statsStartTime;
                _onElapsedUpdated?.Invoke(elapsed);

                CalculateKillsPerInterval();
                _onStatsUpdated?.Invoke(_totalKills, _killsPer5Min, _killsPerHour);
            }
            catch (Exception ex)
            {
                _logger?.Log("Error updating stats: " + ex.Message);
            }
        }

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

            if (minutesElapsed > 0)
            {
                _killsPer5Min = (_totalKills / minutesElapsed) * 5;
                _killsPerHour = (_totalKills / minutesElapsed) * 60;
            }
        }

        private bool IsKilledByMeMessage(string text)
        {
            foreach (string pattern in KillPatterns)
            {
                if (Regex.IsMatch(text, pattern))
                    return true;
            }
            return false;
        }
    }
}
