namespace MyOffice.Services.Account.Domain;

using System;
using Data.Models.Accounts;
using MyOffice.Services.Currency.Domain;
using AutoMapper;
using MyOffice.Services.Identity;
using MyOffice.Core;
using MyOffice.Services.Mapper;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)]
public class GenerateMappedDtoAttribute: Attribute
{
	public GenerateMappedDtoAttribute()
    {
    }
}

[GenerateMappedDto]
public class AccountDto : IDataModelDto<Account>
{
	#region Account properties

	public Guid Id { get; set; }
	public string CurrencyGlobalId { get; set; } = null!;
	public CurrencyGlobalDto? CurrencyGlobal { get; set; }
	public string Name { get; set; } = null!;
	public Guid OwnerId { get; set; }
	public UserDto? Owner { get; set; }

	#endregion Account properties

	#region Dto properties

	public Guid CurrencyId { get; set; }
	public CurrencyDto? Currency { get; set; }
	public string Type { get; set; } = null!;
	public List<AccountAccountCategoryDto>? Categories { get; set; }

	public bool HasMotions { get; set; }

	#endregion Dto properties

	#region Permissions

	public List<AccountAccessDto>? AccessRights { get; set; }
	public bool AllowRead { get; set; }
	public bool AllowWrite { get; set; }
	public bool AllowDelete { get; set; }
	public bool AllowManage { get; set; }

	#endregion Permissions
}

public class AccountDtoProfile : BaseProfile<Account, AccountDto>
{
	public AccountDtoProfile()
	{
		Mapping
			.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any()))
			.AfterMap<AccountDtoMappingAction>();
	}
}

public class AccountDtoMappingAction : BaseMappingAction, IMappingAction<Account, AccountDto>
{
	public AccountDtoMappingAction(IContextProvider contextProvider) : base(contextProvider) { }

	public void Process(Account source, AccountDto destination, ResolutionContext context)
	{
		var accessRight = destination.AccessRights?.FirstOrDefault(x => x.UserId == ContextProvider.UserId);
		destination.AllowRead = accessRight?.IsAllowRead ?? false;
		destination.AllowWrite = accessRight?.IsAllowWrite ?? false;
		destination.AllowManage = accessRight?.IsAllowManage ?? false;
		destination.AllowDelete = (accessRight?.IsOwner ?? false) && !destination.HasMotions;
		destination.Name = accessRight?.Name ?? destination.Name;
		destination.Type = accessRight != null ? accessRight.Type.ToString() : destination.Type;
	}
}