using UIShare.GlobalVariable;
using Logger;
using Prism.Ioc;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using UIShare.ViewModelBase;

namespace TestingModule.ViewModels
{
    public class LogAreaViewModel : NavigateViewModelBase, IDisposable
    {
        // 日志集合
        private ObservableCollection<LogItem> _logs = new();

        public ObservableCollection<LogItem> Logs
        {
            get => _logs;
            set => SetProperty(ref _logs, value);
        }

        public ICommand ClearLogCommand { get; set; }

        private readonly ScopedContext _scopedContext;
        private readonly GlobalInfo _globalInfo;

        /// <summary>UI 线程定时器，每 100ms 批量从 LogBuffer 出队并刷新</summary>
        private readonly DispatcherTimer _flushTimer;

        public LogAreaViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            ClearLogCommand = new DelegateCommand(ClearLog);
            _scopedContext = containerProvider.Resolve<ScopedContext>();
            _globalInfo = containerProvider.Resolve<GlobalInfo>();

            // UI 线程定时器：每 100ms 从 ScopedContext.LogBuffer 批量出队并 Add
            _flushTimer = new DispatcherTimer(DispatcherPriority.Normal, System.Windows.Application.Current.Dispatcher)
            {
                Interval = TimeSpan.FromMilliseconds(100)
            };
            _flushTimer.Tick += FlushLogBuffer;
            _flushTimer.Start();
        }

        /// <summary>
        /// 定时批量刷新日志：一次性出队并 Add，WPF 对连续 Add 做合并渲染
        /// </summary>
        private void FlushLogBuffer(object? sender, EventArgs e)
        {
            if (_scopedContext.LogBuffer.IsEmpty || Logs == null) return;

            var batch = new List<(string Message, Brush Color, int Depth)>();
            while (_scopedContext.LogBuffer.TryDequeue(out var item))
            {
                batch.Add(item);
            }

            // 批量 Add，WPF 会对连续 Add 做合并渲染，只触发一次 layout/render pass
            foreach (var item in batch)
            {
                Logs.Add(new LogItem(item.Message, item.Color, item.Depth));
            }
        }

        private void ClearLog()
        {
            // 清空缓冲区，防止定时器下次还把旧数据刷出来
            while (_scopedContext.LogBuffer.TryDequeue(out _)) { }
            Logs?.Clear();
        }

        /// <summary>
        /// 完善后的资源释放方法
        /// </summary>
        public void Dispose()
        {
            try
            {
                // 停止定时器
                _flushTimer.Stop();
                _flushTimer.Tick -= FlushLogBuffer;

                // 最后一次刷新缓冲区中的剩余日志
                FlushLogBuffer(null, EventArgs.Empty);

                if (Logs != null)
                {
                    Logs.Clear();
                    Logs = null!;
                }
            }
            catch (Exception ex)
            {
                Logger.LoggerHelper.ErrorWithNotify(
                    _scopedContext != null ? _globalInfo.CurrentScope : "",
                    $"释放日志组件（LogAreaViewModel）资源失败: {ex.Message}");
            }
        }
    }

    // 日志条目类
    public class LogItem
    {
        public string Message { get; set; }
        public Brush Color { get; set; } = Brushes.Black;
        public int Depth { get; set; }

        public LogItem(string message, Brush color, int depth = 0)
        {
            Message = new string(' ', depth * 20) + message;
            Color = color;
            Depth = depth;
        }
    }
}
