using AutoMapper;
using DigitalData.Core.DTO;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.GroupOfUser;
using DigitalData.UserManager.Domain.Entities;
using DigitalData.UserManager.Infrastructure.Contracts;

namespace DigitalData.UserManager.Application.Services
{
    public class GroupOfUserService : BaseService<IGroupOfUserRepository, GroupOfUserCreateDto, GroupOfUserReadDto, GroupOfUserUpdateDto, GroupOfUser>, IGroupOfUserService
    {
        public GroupOfUserService(IGroupOfUserRepository repository, IMapper mapper) : base(repository, mapper)
        {
        }

        public async Task<Result> DeleteAsyncByGroupUserId(int groupId, int userId)
        {
            var mous = await _repository.ReadByGroupUserIdAsync(groupId, userId);

            foreach (var mou in mous)
            {
                await _repository.DeleteAsync(mou);
            }

            return Result.Success();
        }

        public async Task<DataResult<IEnumerable<GroupOfUserReadDto>>> ReadAllAsyncWith(bool user, bool group)
        {
            IEnumerable<GroupOfUser> entities;

            if(user && group)
            {
                entities = await _repository.ReadAllAsyncWithGroupAndUser();
            }
            else if (user)
            {
                entities = await _repository.ReadAllAsyncWithUser();
            }
            else if (group)
            {
                entities = await _repository.ReadAllAsyncWithGroup();
            }
            else
            {
                entities = await _repository.ReadAllAsync();
            }

            var gouReadDtos = _mapper.Map<IEnumerable<GroupOfUserReadDto>>(entities);
            return Result.Success(gouReadDtos);
        }
        
        public async Task<Result> HasGroup(string username, string groupname, bool caseSensitive = true)
        {
            var gous = await _repository.ReadAllAsyncWithGroupAndUser();

            if(caseSensitive)
                gous = gous.Where(gous => gous.User?.Username == username && gous.Group?.Name == groupname);
            else
                gous = gous.Where(gous => gous.User?.Username.ToLower() == username.ToLower() && gous.Group?.Name?.ToLower() == groupname.ToLower());

            return gous.Any() ? Result.Success() : Result.Fail();
        }

        public async Task<DataResult<IEnumerable<GroupOfUserReadDto>>> ReadByUsernameAsync(string username)
        {
            var groups = await _repository.ReadByUsernameAsync(username);
            var groupDtos = _mapper.Map<IEnumerable<GroupOfUserReadDto>>(groups);
            return Result.Success(groupDtos);
        }
    }
}