using SWRIS.Core;
using SWRIS.Models;
using SWRIS.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace SWRIS.Services
{
    public class HistoryCleanupService : IDisposable
    {
        private Timer _cleanupTimer;
        private readonly IRecordRepository _recordRepository;
        private bool _isRunning = false;
        private bool _disposed = false;
        private int _consecutiveFailures = 0;

        public event EventHandler<DeleteResultModel> OnCleanupCompleted;
        public event EventHandler<Exception> OnCleanupFailed;

        public bool IsRunning => _isRunning;
        public DateTime? NextScheduledTime { get; private set; }
        public DateTime? LastCleanupTime { get; private set; }
        public DeleteResultModel LastCleanupResult { get; private set; }

        public HistoryCleanupService()
        {
            _recordRepository = new RecordRepository();
            ValidateConfiguration();
        }

        public void StartScheduledCleanup()
        {
            if (_isRunning)
            {
                LogHelper.Warn("清理服务已在运行中");
                return;
            }

            try
            {
                ValidateConfiguration();

                var now = DateTime.Now;
                var scheduledTime = CalculateNextScheduledTime(now);

                var initialDelay = scheduledTime - now;

                _cleanupTimer = new Timer(
                    callback: _ => ExecuteCleanupAsync().ConfigureAwait(false),
                    state: null,
                    dueTime: initialDelay,
                    period: TimeSpan.FromHours(24)
                );

                _isRunning = true;
                NextScheduledTime = scheduledTime;
                _consecutiveFailures = 0;

                LogHelper.Info($"计划清理已启动。下次执行: {scheduledTime:yyyy-MM-dd HH:mm:ss}");
            }
            catch (Exception ex)
            {
                LogHelper.Error($"启动计划任务失败: {ex.Message}");
                _isRunning = false;
                OnCleanupFailed?.Invoke(this, ex);

                // 延迟重试
                Task.Delay(TimeSpan.FromMinutes(5)).ContinueWith(_ => RetryStartup());
            }
        }

        private DateTime CalculateNextScheduledTime(DateTime now)
        {
            var timeSpan = App.Config.CleanScheduledTime;
            var scheduledTime = new DateTime(now.Year, now.Month, now.Day,
                timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);

            if (now > scheduledTime)
            {
                scheduledTime = scheduledTime.AddDays(1);
            }

            return scheduledTime;
        }

        private void RetryStartup(int retryCount = 0)
        {
            if (retryCount >= 3)
            {
                LogHelper.Error("启动重试次数超过限制，请检查系统配置");
                return;
            }

            LogHelper.Info($"尝试重新启动清理服务 (重试 {retryCount + 1}/3)");
            StartScheduledCleanup();
        }

        private async Task ExecuteCleanupAsync()
        {
            try
            {
                LastCleanupTime = DateTime.Now;
                LogHelper.Info($"开始执行计划清理任务 ({LastCleanupTime:yyyy-MM-dd HH:mm:ss})");

                var result = await Task.Run(() =>
                    CleanupHistoryOlderThanDays(App.Config.DataSaveDays));

                // 更新下一次执行时间
                NextScheduledTime = CalculateNextScheduledTime(DateTime.Now);

                // 重置连续失败计数
                _consecutiveFailures = 0;

                // 在UI线程更新结果
                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    LastCleanupResult = result;

                    if (result.IsSuccess)
                    {
                        LogHelper.Info($"{result.Message} (执行时间: {result.OperationTime:HH:mm:ss})");
                        LogHelper.Info($"删除记录: {result.DeletedRecords} 条, 删除文件: {result.DeletedFiles} 个");
                    }
                    else
                    {
                        LogHelper.Warn($"清理任务完成但有警告: {result.Message}");
                    }

                    OnCleanupCompleted?.Invoke(this, result);
                });
            }
            catch (Exception ex)
            {
                _consecutiveFailures++;
                LogHelper.Error($"清理执行失败 (失败次数: {_consecutiveFailures}): {ex.Message}", ex);

                // 连续失败告警
                if (_consecutiveFailures >= 3)
                {
                    LogHelper.Warn("连续清理失败次数过多，请检查系统状态");
                }

                OnCleanupFailed?.Invoke(this, ex);
            }
        }

        public DeleteResultModel CleanupHistoryOlderThanDays(int days)
        {
            var result = new DeleteResultModel
            {
                OperationTime = DateTime.Now,
                DataSaveDays = days
            };
            try
            {
                if (days <= 0)
                {
                    throw new ArgumentException("数据保存天数必须大于0", nameof(days));
                }

                var endTime = DateTime.Today.AddDays(-days);
                LogHelper.Info($"开始清理 {endTime:yyyy-MM-dd} 之前的历史数据");

                var (effect, filePaths) = _recordRepository.DeleteRecords(endTime);
                result.DeletedRecords = effect;
                result.DeletedFiles = DeleteAssociatedFiles(filePaths);
                result.IsSuccess = true;
                result.Message = $"清理完成，删除了 {result.DeletedRecords} 条记录和 {result.DeletedFiles} 个文件。";

                LogHelper.Info($"数据库记录清理: {result.DeletedRecords} 条");
                LogHelper.Info($"关联文件清理: {result.DeletedFiles} 个");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = $"清理过程中发生错误: {ex.Message}";
                LogHelper.Error($"Cleanup Error: {ex}", ex);
            }

            return result;
        }

        private int DeleteAssociatedFiles(List<string> filePaths)
        {
            int deletedCount = 0;
            int errorCount = 0;

            if (filePaths == null || filePaths.Count == 0)
            {
                return 0;
            }

            LogHelper.Info($"开始清理 {filePaths.Count} 个关联文件");

            foreach (var filePath in filePaths)
            {
                try
                {
                    if (File.Exists(filePath))
                    {
                        File.Delete(filePath);
                        deletedCount++;
                    }
                    else
                    {
                        LogHelper.Warn($"文件不存在: {filePath}");
                    }
                }
                catch (Exception ex)
                {
                    errorCount++;
                    LogHelper.Error($"删除文件失败 {filePath}: {ex.Message}");
                }
            }

            if (errorCount > 0)
            {
                LogHelper.Warn($"{errorCount} 个文件删除失败");
            }

            return deletedCount;
        }

        public void StopScheduledCleanup()
        {
            _cleanupTimer?.Change(Timeout.Infinite, Timeout.Infinite);
            _isRunning = false;
            NextScheduledTime = null;
            LogHelper.Info("计划清理已停止");
        }

        public void TriggerManualCleanup()
        {
            LogHelper.Info("手动触发清理任务");
            ExecuteCleanupAsync().ConfigureAwait(false);
        }

        private void ValidateConfiguration()
        {
            if (App.Config?.CleanScheduledTime == null)
            {
                throw new InvalidOperationException("清理计划时间未配置");
            }

            if (App.Config.DataSaveDays <= 0)
            {
                throw new InvalidOperationException("数据保存天数必须大于0");
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    StopScheduledCleanup();
                    _cleanupTimer?.Dispose();
                    _cleanupTimer = null;
                }
                _disposed = true;
            }
        }

        ~HistoryCleanupService()
        {
            Dispose(false);
        }
    }
}