namespace MyOffice.Data.Repositories.Account;

using Microsoft.EntityFrameworkCore;
using Models.Accounts;
using MyOffice.Data.Repositories;

public class AccountRepository : AppRepository<Account>, IAccountRepository
{
	public List<Account> GetAll(Guid userId)
	{
		return _context.Accounts!
			.Include(x => x.CurrencyGlobal)
			.Include(x => x.Categories)!
			.ThenInclude(x => x.Category)
			.Include(x => x.AccessRights)!
			.ThenInclude(x => x.User)
			.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
			.ToList();
	}

	public List<Account> GetByCategory(Guid userId, Guid categoryId)
	{
		return _context.Accounts!
			.Include(x => x.CurrencyGlobal)
			.Include(x => x.Categories)!
			.ThenInclude(x => x.Category)
			.Include(x => x.AccessRights)!
			.ThenInclude(x => x.User)
			.Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId))
			.ToList();
	}

	public List<AccountDetailed> GetByCategoryDetailed(Guid userId, Guid categoryId)
	{
		return _context.Accounts!
			.Include(x => x.CurrencyGlobal)
			.Include(x => x.Categories)!
			.ThenInclude(x => x.Category)
			.Include(x => x.AccessRights)!
			.ThenInclude(x => x.User)
			.Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId))
			.Select(x => new AccountDetailed
			{
				Account = x,
				TotalPlus = x.Motions!.Sum(m => m.AmountPlus),
				TotalMinus = x.Motions!.Sum(m => m.AmountMinus),
			})
			.ToList();
	}

	public AccountDetailed? GetByIdDetailed(Guid userId, Guid id)
	{
		return _context.Accounts!
			.Include(x => x.CurrencyGlobal)
			.Include(x => x.Categories)!
			.ThenInclude(x => x.Category)
			.Include(x => x.AccessRights)!
			.ThenInclude(x => x.User)
			.Where(x => x.Id == id && x.AccessRights!.Any(a => a.UserId == userId))
			.Select(x => new AccountDetailed
			{
				Account = x,
				TotalPlus = x.Motions!.Sum(m => m.AmountPlus),
				TotalMinus = x.Motions!.Sum(m => m.AmountMinus),
			})
			.FirstOrDefault();
	}

	public bool Add(Account account)
	{
		return AddBase(account) > 0;
	}

	public Account? Get(Guid userId, Guid id)
	{
		return _context.Accounts!
			.Include(x => x.Categories)!
			.ThenInclude(x => x.Category)
			.Include(x => x.AccessRights)!
			.ThenInclude(x => x.User)
			.FirstOrDefault(x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId));
	}

	public bool Update(Account account)
	{
		return UpdateBase(account) > 0;
	}

	public bool Remove(Account account)
	{
		return RemoveBase(account) > 0;
	}

	public List<Account> FindAccounts(Guid userId, string term)
	{
		return _context.Accounts
			.Where(x => x.AccessRights.Any(a => a.UserId == userId))
			.Where(x => x.Name.Contains(term))
			.ToList();
	}
}