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

[Authorize(Roles = "CanManageLocations")]
[Route("[controller]")]
public class LocationsController : Controller
{
    private readonly LdapService _ldap;
    private readonly ILogger<LocationsController> _logger;

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

    [HttpGet("Index")]
    public async Task<IEnumerable<LocationModel>> Index()
    {
        IEnumerable<LocationModel> list = await _ldap.ListLocationsAsync();
        return list;
    }

    [HttpGet("Create")]
    public async Task<bool> Create(LocationsCreateRequestModel model)
    {
        try
        {
            LocationsDescription room = model.LocationsDescription;
            string location = StringHelpers.Slugify(room.Location + " " + room.RoomNumber + " " + room.Seat);
            LdapAttributeSet attributeSet =
            [
                new LdapAttribute("objectClass", "locality"),
                new LdapAttribute("objectClass", "top"),
                new LdapAttribute("l", location),
                new LdapAttribute("description", JsonSerializer.Serialize(room))
            ];

            await _ldap.CreateLocation(attributeSet);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError("Unable to create location: {ex.Message} - {ex.StackTrace}", [ex.Message, ex.StackTrace]);
            return false;
        }
    }

    [HttpGet("Delete")]
    public async Task<LocationsDeleteRequestModel> DeleteAsync(string cn)
    {
        if (cn is null) { return new(false); }
        try
        {
            await _ldap.DeleteLocationAsync(cn);
            return new(true);
        }
        catch (Exception ex)
        {
            return new(false, ex.Message);
        }
    }
    
    [HttpPost("Update")]
    public async Task<bool> Update(LocationsModifyRequestModel requestModel)
    {
        if (requestModel is null)
        {
            _logger.LogError("Unable to update a location because the LocationsModifyRequestModel is null");
            return false;
        }
        try
        {
            string location = requestModel.Location;
            LocationsDescription room = requestModel.Description;
            string newLocation = StringHelpers.Slugify(room.Location + " " + room.RoomNumber + " " + room.Seat); // TODO: fix DRY violation

            await _ldap.UpdateLocation(location, "description", JsonSerializer.Serialize(room));
            await _ldap.UpdateLocation(location, "l", newLocation);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError("Unable to update location: {ex.Message} - {ex.StackTrace}", [ex.Message, ex.StackTrace]);
            return false;
        }
    }
}
