namespace MyOffice.DbContext;

using Data.Models.Currencies;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

public record ConnectionConfiguration(string Provider, string ConnectionString);

public class RepositoryInitializer
{
	public static void Initialize(
		IServiceCollection services,
		ConnectionConfiguration connectionString
	)
	{
		Services = services!;
		ConnectionString = connectionString;

		var db = AppDbContextFactory.Instance.CreateDbContext();
		db.Database.Migrate();
		
		Prefill(db);

		UpdateCurrentRates(db);
	}

	public static ConnectionConfiguration ConnectionString { get; internal set; } = null!;
	public static IServiceCollection Services { get; internal set; } = null!;

	private static void Prefill(AppDbContext dbContext)
	{
		// CurrencyGlobals
		var predefinedCurrencyGlobals = new List<CurrencyGlobal>()
		{
			new() { Id = CurrencyGlobalIdEnum.UAH.ToString(), DefaultQuantity = 1, Symbol = "₴", Name = "Ukrainian hryvnias" },
			new() { Id = CurrencyGlobalIdEnum.USD.ToString(), DefaultQuantity = 1, Symbol = "$", Name = "US Dollar" },
			new() { Id = CurrencyGlobalIdEnum.EUR.ToString(), DefaultQuantity = 1, Symbol = "€", Name = "Euros" },
			new() { Id = CurrencyGlobalIdEnum.GBP.ToString(), DefaultQuantity = 1, Symbol = "£", Name = "British pounds sterling" },
			new() { Id = CurrencyGlobalIdEnum.RUB.ToString(), DefaultQuantity = 10, Symbol = "₽", Name = "Russia Ruble" },
			new() { Id = CurrencyGlobalIdEnum.BTC.ToString(), DefaultQuantity = 10, Symbol = "btc", Name = "Bitcoin" },
			new() { Id = CurrencyGlobalIdEnum.ETH.ToString(), DefaultQuantity = 10, Symbol = "eth", Name = "Ethereum" },
			new() { Id = CurrencyGlobalIdEnum.TON.ToString(), DefaultQuantity = 10, Symbol = "ton", Name = "TON" },
			new() { Id = CurrencyGlobalIdEnum.OTHER.ToString(), DefaultQuantity = 1, Symbol = "", Name = "Other" },
		};

		var currencyGlobals = dbContext.CurrencyGlobals.ToList();
		foreach (var predefined in predefinedCurrencyGlobals)
		{
			if (currencyGlobals.FirstOrDefault(x => x.Id == predefined.Id) == null)
			{
				dbContext.CurrencyGlobals.Add(predefined);
			}
		}

		dbContext.SaveChanges();
	}

	/// <summary>
	/// Update all currency - set current rate
	/// </summary>
	private static void UpdateCurrentRates(AppDbContext dbContext)
	{
		var lastrates = dbContext.CurrencyRates
			.Include(x => x.Currency)
			.GroupBy(x => new
			{
				x.CurrencyId,
			}, (key, g) => g.Where(x => x.DateTime <= DateTime.UtcNow).OrderByDescending(x => x.DateTime).First())
			.ToList();

		var currencies = dbContext.Currencies.ToList();
		foreach (var currency in currencies)
		{
			var rate = lastrates.FirstOrDefault(x => x.CurrencyId == currency.Id);
			if (rate != null)
			{
				currency.CurrentRateId = rate.Id;
				dbContext.Attach(currency).State = EntityState.Modified;
			}
		}

		dbContext.SaveChanges();
	}
}