using Dapper;
using Dapper.Contrib.Extensions;

using FabApprovalWorkerService.Models;

using System.Data;
using System.Diagnostics.CodeAnalysis;

namespace FabApprovalWorkerService.Services;

public interface IUserService {
    Task<Dictionary<string, User>> GetAllUsers();
    Task<bool> UpdateUserCertificationData([DisallowNull] ICollection<User> users);
}

public class UserService : IUserService {
    private readonly ILogger<UserService> _logger;
    private IDalService _dalService;

    public UserService(ILogger<UserService> logger, IDalService dalService) {
        _logger = logger;
        _dalService = dalService;
    }

    public async Task<Dictionary<string, User>> GetAllUsers() {
        Dictionary<string, User> users = new Dictionary<string, User>();

        try {
            _logger.LogInformation("Attempting to get all users");

            string sql = "select * from users;";

            IEnumerable<User> enumerableUsers = await _dalService.QueryAsync<User>(sql);
            users = enumerableUsers.ToDictionary(u => u.FirstName + u.LastName, u => u);

            if (!users.Any()) {
                throw new Exception("No users returned from the database");
            } else {
                _logger.LogInformation("Successfully retrieved the users");
            }

            return users;
        } catch (Exception ex) {
            _logger.LogError("An exception occurred when attempting to get all users. Exception: {ex}", ex.Message);
            return users;
        }
    }

    public async Task<bool> UpdateUserCertificationData([DisallowNull] ICollection<User> users) {
        if (users is null) throw new ArgumentNullException("users cannot be null");

        try {
            _logger.LogInformation("Attempting to update user cert data");

            bool result = await _dalService.UpdateAsync(users);

            _logger.LogInformation("User cert data updated successfully: {result}", result);

            return result;
        } catch (Exception ex) {
            _logger.LogError("An exception occurred when attempting to update user cert data. Exception: {ex}", ex.Message);
            return false;
        }
    }
}
