using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using AxCopilot.Models;

namespace AxCopilot.Services;

internal static class UsageStatisticsService
{
	private static readonly string _statsDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "stats");

	private static DailyUsageStats _today = new DailyUsageStats();

	private static bool _initialized;

	private static readonly object _lock = new object();

	private const int RetentionDays = 30;

	public static void RecordLauncherOpen()
	{
		EnsureInitialized();
		lock (_lock)
		{
			_today.LauncherOpens++;
		}
		SaveTodayAsync();
	}

	public static void RecordCommandUsage(string commandKey)
	{
		if (!string.IsNullOrWhiteSpace(commandKey))
		{
			EnsureInitialized();
			lock (_lock)
			{
				_today.CommandUsage.TryGetValue(commandKey, out var value);
				_today.CommandUsage[commandKey] = value + 1;
			}
			SaveTodayAsync();
		}
	}

	public static void AddActiveSeconds(int seconds)
	{
		if (seconds > 0)
		{
			EnsureInitialized();
			lock (_lock)
			{
				_today.ActiveSeconds += seconds;
			}
			SaveTodayAsync();
		}
	}

	public static int GetTodayActiveSeconds()
	{
		EnsureInitialized();
		lock (_lock)
		{
			return _today.ActiveSeconds;
		}
	}

	public static void RecordChat(string tab)
	{
		if (string.IsNullOrWhiteSpace(tab))
		{
			tab = "Chat";
		}
		EnsureInitialized();
		lock (_lock)
		{
			_today.ChatCounts.TryGetValue(tab, out var value);
			_today.ChatCounts[tab] = value + 1;
		}
		SaveTodayAsync();
	}

	public static void RecordTokens(int promptTokens, int completionTokens)
	{
		if (promptTokens > 0 || completionTokens > 0)
		{
			EnsureInitialized();
			lock (_lock)
			{
				_today.PromptTokens += promptTokens;
				_today.CompletionTokens += completionTokens;
				_today.TotalTokens += promptTokens + completionTokens;
			}
			SaveTodayAsync();
		}
	}

	public static List<DailyUsageStats> GetStats(int days = 30)
	{
		EnsureInitialized();
		List<DailyUsageStats> list = new List<DailyUsageStats>();
		DateTime today = DateTime.Today;
		for (int num = days - 1; num >= 0; num--)
		{
			string text = today.AddDays(-num).ToString("yyyy-MM-dd");
			if (text == _today.Date)
			{
				DailyUsageStats item;
				lock (_lock)
				{
					item = CloneToday();
				}
				list.Add(item);
			}
			else
			{
				string filePath = GetFilePath(text);
				if (File.Exists(filePath))
				{
					try
					{
						string json = File.ReadAllText(filePath);
						DailyUsageStats dailyUsageStats = JsonSerializer.Deserialize<DailyUsageStats>(json);
						if (dailyUsageStats != null)
						{
							list.Add(dailyUsageStats);
						}
						else
						{
							list.Add(new DailyUsageStats
							{
								Date = text
							});
						}
					}
					catch
					{
						list.Add(new DailyUsageStats
						{
							Date = text
						});
					}
				}
				else
				{
					list.Add(new DailyUsageStats
					{
						Date = text
					});
				}
			}
		}
		return list;
	}

	private static void EnsureInitialized()
	{
		if (_initialized)
		{
			return;
		}
		lock (_lock)
		{
			if (_initialized)
			{
				return;
			}
			try
			{
				Directory.CreateDirectory(_statsDir);
				string text = DateTime.Today.ToString("yyyy-MM-dd");
				string filePath = GetFilePath(text);
				if (File.Exists(filePath))
				{
					string json = File.ReadAllText(filePath);
					DailyUsageStats dailyUsageStats = JsonSerializer.Deserialize<DailyUsageStats>(json);
					_today = dailyUsageStats ?? new DailyUsageStats
					{
						Date = text
					};
				}
				else
				{
					_today = new DailyUsageStats
					{
						Date = text
					};
				}
				PurgeOldFiles();
			}
			catch (Exception ex)
			{
				LogService.Warn("통계 서비스 초기화 실패: " + ex.Message);
				_today = new DailyUsageStats
				{
					Date = DateTime.Today.ToString("yyyy-MM-dd")
				};
			}
			_initialized = true;
		}
	}

	private static void PurgeOldFiles()
	{
		try
		{
			DateTime dateTime = DateTime.Today.AddDays(-30.0);
			string[] files = Directory.GetFiles(_statsDir, "????-??-??.json");
			foreach (string path in files)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
				if (DateTime.TryParse(fileNameWithoutExtension, out var result) && result < dateTime)
				{
					File.Delete(path);
				}
			}
		}
		catch (Exception ex)
		{
			LogService.Warn("통계 파일 정리 실패: " + ex.Message);
		}
	}

	private static async Task SaveTodayAsync()
	{
		try
		{
			DailyUsageStats snapshot;
			lock (_lock)
			{
				snapshot = CloneToday();
			}
			string path = GetFilePath(snapshot.Date);
			string json = JsonSerializer.Serialize(snapshot, new JsonSerializerOptions
			{
				WriteIndented = false
			});
			await File.WriteAllTextAsync(path, json);
		}
		catch (Exception ex)
		{
			Exception ex2 = ex;
			LogService.Warn("통계 저장 실패: " + ex2.Message);
		}
	}

	private static DailyUsageStats CloneToday()
	{
		return new DailyUsageStats
		{
			Date = _today.Date,
			LauncherOpens = _today.LauncherOpens,
			ActiveSeconds = _today.ActiveSeconds,
			CommandUsage = new Dictionary<string, int>(_today.CommandUsage),
			ChatCounts = new Dictionary<string, int>(_today.ChatCounts),
			TotalTokens = _today.TotalTokens,
			PromptTokens = _today.PromptTokens,
			CompletionTokens = _today.CompletionTokens
		};
	}

	private static string GetFilePath(string dateStr)
	{
		return Path.Combine(_statsDir, dateStr + ".json");
	}
}
