using Application.Aggregates.Users.ViewModels;
using Domain.Aggregates.Users;
using Domain.Aggregates.Users.Data;
using Mapster;
using Resources.Messages;

namespace Application.Aggregates.Users;

public class UsersApplication
    (IUserRepository userRepository)
{
    public async Task<UserViewModel> CreateAsync(CreateUserViewModel viewModel)
    {
        var user = User.Create(
            username: viewModel.Username, 
            password: viewModel.Password, 
            mobile: viewModel.Mobile);

        if (viewModel.IsActive == true)
        {
            user.Activate();
        }

        await userRepository.AddAsync(user);
        await userRepository.SaveChangesAsync();

        return user.Adapt<UserViewModel>();
    }

    public async Task<List<UserViewModel>> GetUsers()
    {
        var users =
            await userRepository.GetAllAsync();

        return users.Adapt<List<UserViewModel>>();
    }

    public async Task<UserViewModel> GetAsync(Guid userId)
    {
        var user =
            await userRepository.GetAsync(userId);

        return user.Adapt<UserViewModel>();
    }

    public async Task<UserViewModel> UpdateAsync(UpdateUserViewModel updateViewModel)
    {
        var userForUpdate =
            await userRepository.GetAsync(updateViewModel.Id);

        if (userForUpdate == null || userForUpdate.Id == Guid.Empty)
        {
            var message =
                string.Format(Errors.NotFound, Resources.DataDictionary.User);

            throw new Exception(message);
        }

        userForUpdate.Update(
            username: updateViewModel.Username, 
            password: updateViewModel.Password, 
            mobile: updateViewModel.Mobile);

        if (updateViewModel.IsActive == true)
        {
            userForUpdate.Activate();
        }
        else
        {
            userForUpdate.Deactivate();
        }

        await userRepository.SaveChangesAsync();

        return userForUpdate.Adapt<UserViewModel>();
    }

    public async Task DeleteAsync(Guid userId)
    {
        var userForUpdate =
            await userRepository.GetAsync(userId);

        if (userForUpdate == null || userForUpdate.Id == Guid.Empty)
        {
            var message =
                string.Format(Errors.NotFound, Resources.DataDictionary.User);

            throw new Exception(message);
        }

        userRepository.Remove(userForUpdate);
        await userRepository.SaveChangesAsync();
    }
}
