using System;
using System.Timers;
using System.Windows.Threading;
using AxCopilot.Models;
using AxCopilot.Views;
using Microsoft.Win32;

namespace AxCopilot.Services;

public sealed class WorktimeReminderService : IDisposable
{
	private readonly SettingsService _settings;

	private readonly Dispatcher _dispatcher;

	private readonly object _lock = new object();

	private DateTime _sessionStart;

	private TimeSpan _todayTotal;

	private DateTime _lastDate;

	private DateTime _lastShownAt;

	private Timer? _periodicTimer;

	private volatile bool _disposed;

	public WorktimeReminderService(SettingsService settings, Dispatcher dispatcher)
	{
		_settings = settings;
		_dispatcher = dispatcher;
		_sessionStart = DateTime.Now;
		_lastDate = DateTime.Today;
		_lastShownAt = DateTime.MinValue;
		try
		{
			int todayActiveSeconds = UsageStatisticsService.GetTodayActiveSeconds();
			if (todayActiveSeconds > 0)
			{
				_todayTotal = TimeSpan.FromSeconds(todayActiveSeconds);
				LogService.Info($"이전 세션 누적 시간 복원: {_todayTotal}");
			}
		}
		catch (Exception ex)
		{
			LogService.Warn("이전 세션 시간 복원 실패: " + ex.Message);
		}
		SystemEvents.SessionSwitch += OnSessionSwitch;
		LogService.Info("WorktimeReminderService 초기화 완료.");
		ReminderSettings reminder = _settings.Settings.Reminder;
		if (!reminder.Enabled)
		{
			return;
		}
		_dispatcher.BeginInvoke((Delegate)(Action)delegate
		{
			if (!_disposed)
			{
				ShowPopup();
			}
		}, (DispatcherPriority)2, Array.Empty<object>());
		StartPeriodicTimer();
	}

	private void OnSessionSwitch(object sender, SessionSwitchEventArgs e)
	{
		if (_disposed)
		{
			return;
		}
		LogService.Info($"SessionSwitch 이벤트: {e.Reason}");
		lock (_lock)
		{
			switch (e.Reason)
			{
			case SessionSwitchReason.SessionLock:
				AccumulateSession();
				StopPeriodicTimer();
				LogService.Info($"세션 잠금. 누적 시간: {_todayTotal}");
				break;
			case SessionSwitchReason.SessionLogon:
			case SessionSwitchReason.SessionUnlock:
			{
				ResetForNewDayIfNeeded();
				_sessionStart = DateTime.Now;
				ReminderSettings reminder = _settings.Settings.Reminder;
				if (!reminder.Enabled)
				{
					LogService.Info("알림 비활성화 상태. 팝업 생략.");
					break;
				}
				int num = Math.Max(1, reminder.IntervalMinutes);
				double totalMinutes = (DateTime.Now - _lastShownAt).TotalMinutes;
				LogService.Info($"알림 간격 확인: 경과={totalMinutes:F1}분, 설정={num}분");
				if (totalMinutes >= (double)num)
				{
					ShowPopup();
				}
				StartPeriodicTimer();
				break;
			}
			case SessionSwitchReason.SessionLogoff:
				break;
			}
		}
	}

	private void AccumulateSession()
	{
		ResetForNewDayIfNeeded();
		_todayTotal += DateTime.Now - _sessionStart;
		_sessionStart = DateTime.Now;
	}

	private void ResetForNewDayIfNeeded()
	{
		if (DateTime.Today == _lastDate)
		{
			return;
		}
		DateTime today = DateTime.Today;
		_sessionStart = today;
		_lastDate = DateTime.Today;
		_lastShownAt = DateTime.MinValue;
		try
		{
			int todayActiveSeconds = UsageStatisticsService.GetTodayActiveSeconds();
			_todayTotal = ((todayActiveSeconds > 0) ? TimeSpan.FromSeconds(todayActiveSeconds) : TimeSpan.Zero);
		}
		catch
		{
			_todayTotal = TimeSpan.Zero;
		}
	}

	public TimeSpan GetTodayUsage()
	{
		lock (_lock)
		{
			ResetForNewDayIfNeeded();
			return _todayTotal + (DateTime.Now - _sessionStart);
		}
	}

	private void StartPeriodicTimer()
	{
		StopPeriodicTimer();
		int num = Math.Max(1, _settings.Settings.Reminder.IntervalMinutes);
		_periodicTimer = new Timer(num * 60000);
		_periodicTimer.Elapsed += OnPeriodicTimerElapsed;
		_periodicTimer.AutoReset = true;
		_periodicTimer.Start();
		LogService.Info($"격려 알림 주기 타이머 시작: {num}분 간격");
	}

	private void StopPeriodicTimer()
	{
		if (_periodicTimer != null)
		{
			_periodicTimer.Elapsed -= OnPeriodicTimerElapsed;
			_periodicTimer.Stop();
			_periodicTimer.Dispose();
			_periodicTimer = null;
		}
	}

	private void OnPeriodicTimerElapsed(object? sender, ElapsedEventArgs e)
	{
		if (_disposed)
		{
			return;
		}
		ReminderSettings reminder = _settings.Settings.Reminder;
		if (!reminder.Enabled)
		{
			StopPeriodicTimer();
			return;
		}
		lock (_lock)
		{
			ResetForNewDayIfNeeded();
			ShowPopup();
		}
	}

	public void RestartTimer()
	{
		ReminderSettings reminder = _settings.Settings.Reminder;
		if (reminder.Enabled)
		{
			StartPeriodicTimer();
		}
		else
		{
			StopPeriodicTimer();
		}
	}

	private void ShowPopup()
	{
		_lastShownAt = DateTime.Now;
		TimeSpan usage = GetTodayUsage();
		var (text, author) = QuoteService.GetRandom(_settings?.Settings.Reminder.EnabledCategories);
		_dispatcher.BeginInvoke((Delegate)(Action)delegate
		{
			if (_disposed)
			{
				return;
			}
			try
			{
				if (_settings != null)
				{
					ReminderPopupWindow reminderPopupWindow = new ReminderPopupWindow(text, author, usage, _settings);
					reminderPopupWindow.Show();
				}
			}
			catch (Exception ex)
			{
				LogService.Warn("알림 팝업 표시 실패: " + ex.Message);
			}
		}, (DispatcherPriority)9, Array.Empty<object>());
	}

	public void Dispose()
	{
		if (!_disposed)
		{
			_disposed = true;
			StopPeriodicTimer();
			SystemEvents.SessionSwitch -= OnSessionSwitch;
		}
	}
}
