using Berufsschule_HAM.Services;
using Microsoft.AspNetCore.Mvc;
using Novell.Directory.Ldap;
using Berufsschule_HAM.Models;
using Berufsschule_HAM.Helpers;
using Microsoft.AspNetCore.Authorization;

[Authorize]
[Route("[controller]")]
public class SettingsController : Controller
{
    private readonly LdapService _ldap;
    private readonly ILogger<UsersController> _logger;

    public SettingsController(LdapService ldap, ILogger<UsersController> logger)
    {
        _ldap = ldap;
        _logger = logger;
    }

    [HttpGet("User")]
    public async Task<IActionResult> UserAsync()
    {
        try
        {
            var userID = User.Identity?.Name ?? throw new Exception("No name specified");
            UserSettingsModel userSettingsModel = new()
            {
                userModel = await _ldap.GetUserByUidAsync(userID)
            };
            return View(userSettingsModel);
        } catch (Exception ex)
        {
            _logger.LogWarning("An exception happened when trying to show user settings view: {ex.Message} - {ex.StackTrace}", [ex.Message, ex.StackTrace]);
            return Redirect("/Home/Logout");
        }
    }

    [HttpPut("User")]
    public async Task<UserUpdateResponseModel> UpdateUserAsync([FromBody]UserUpdateRequestModel userUpdateRequestModel)
    {
        if (userUpdateRequestModel is null)
        {
            return new() {Success = false, ErrorMessage = "userUpdateRequestModel is null"};
        }
        try
        {
            var userID = User.Identity?.Name ?? throw new Exception("No name specified");
            bool anyUpdated = false;
            if (userUpdateRequestModel.Password is not null && userUpdateRequestModel.Password.Length > 0)
            {
                await _ldap.UpdateUser(userID, "userPassword", await UsersHelper.HashPassword(_ldap, userUpdateRequestModel.Password));
                anyUpdated = true;
            }
            if (userUpdateRequestModel.Image is not null && userUpdateRequestModel.Image.Length > 0)
            {
                await _ldap.UpdateUser(userID, "jpegPhoto", userUpdateRequestModel.Image);
                anyUpdated = true;
            }
            if (anyUpdated)
            {
                return new() {Success = true};
            }
            else
            {
                return new() {Success = false, ErrorMessage = "Nothing was updated"};
            }
        } catch (Exception ex)
        {
            _logger.LogWarning("An exception happened when trying to update a user: {ex.Message} - {ex.StackTrace}", [ex.Message, ex.StackTrace]);
            return new() {Success = false, ErrorMessage = ex.Message};
        }
    }


    [Authorize(Roles = "CanManageSettings")]
    [HttpGet("Admin")]
    public async Task<IActionResult> AdminAsync()
    {
        AdminSettingsModel adminSettingsModel = await _ldap.GetAdminSettingsModelAsync();
        return View(adminSettingsModel);
    }

    [Authorize]
    [HttpGet("Presets")]
    public async Task<Dictionary<string, Preset>> PresetsAsync()
    {
        AdminSettingsModel adminSettingsModel = await _ldap.GetAdminSettingsModelAsync();
        return adminSettingsModel.Presets;
    }

    [Authorize(Roles = "CanManageSettings")]
    [HttpPut("Admin")]
    public async Task<AdminUpdateResponseModel> UpdateAdminAsync([FromBody]AdminUpdateRequestModel adminSettingsRequestModel)
    {
        if (adminSettingsRequestModel is null)
        {
            _logger.LogWarning("adminUpdateRequestModel is null");
            return new() {
                Success = false,
                ErrorMessage = "adminUpdateRequestModel is null"
            };
        }
        AdminSettingsModel currentSettingsModel = await _ldap.GetAdminSettingsModelAsync();
        await _ldap.SetAdminSettingsModelAsync(adminSettingsRequestModel.AdminSettingsModel);
        if (adminSettingsRequestModel.AdminSettingsModel.UserImagePreloadType != UserImagePreloadType.None)
        {
            IEnumerable<UserModel> users = await _ldap.ListUsersAsync();
            Task _ = ImageHelper.PreloadUsers(users, adminSettingsRequestModel.AdminSettingsModel.UserImagePreloadType);
        }
        return new() {
            Success = true
        };
    }

    [Authorize(Roles = "CanManageSettings")]
    [HttpPost("ClearUserImageCache")]
    public bool ClearUserImageCache()
    {
        ImageHelper.ImageCache = [];
        return true;
    }
    [Authorize(Roles = "CanManageSettings")]
    [HttpPost("UserImageCacheSize")]
    public string UserImageCacheSize()
    {
        return ImageHelper.ToHumanReadableSize(ImageHelper.GetImageCacheSize());
    }
}