using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OmsorgCore.Api.Contracts;
using OmsorgCore.Api.Security;
using OmsorgCore.Application.Services;
using OmsorgCore.Domain.Enums;

namespace OmsorgCore.Api.Controllers;

/// <summary>
/// Admin-Konfiguration der FR-EM-3-Konfliktprüfungen bei der Mitarbeiterzuweisung: pro Prüfung
/// (Qualifikation/Abwesenheit/Arbeitszeit/Überschneidung/Vertrag) einzeln als Warning oder Error
/// einstellbar, siehe AssignmentService.CreateAsync.
/// </summary>
[ApiController]
[Authorize]
[Route("api/settings/assignment-validation")]
public class AssignmentValidationSettingsController : ControllerBase
{
    private readonly IAssignmentValidationSettingsService _service;

    public AssignmentValidationSettingsController(IAssignmentValidationSettingsService service)
    {
        _service = service;
    }

    [HttpGet]
    [RequirePermission(ModuleType.Configuration, PermissionAction.Edit)]
    public async Task<ActionResult<AssignmentValidationSettingsResponse>> Get(CancellationToken cancellationToken)
    {
        var settings = await _service.GetAsync(cancellationToken);
        return Ok(new AssignmentValidationSettingsResponse(
            settings.QualificationMode.ToString(),
            settings.AbsenceMode.ToString(),
            settings.WorkingHoursMode.ToString(),
            settings.OverlapMode.ToString(),
            settings.ContractMode.ToString()));
    }

    [HttpPut]
    [RequirePermission(ModuleType.Configuration, PermissionAction.Edit)]
    public async Task<ActionResult<AssignmentValidationSettingsResponse>> Update(
        UpdateAssignmentValidationSettingsRequest request,
        CancellationToken cancellationToken)
    {
        if (!TryParseSeverity(request.QualificationMode, out var qualificationMode) ||
            !TryParseSeverity(request.AbsenceMode, out var absenceMode) ||
            !TryParseSeverity(request.WorkingHoursMode, out var workingHoursMode) ||
            !TryParseSeverity(request.OverlapMode, out var overlapMode) ||
            !TryParseSeverity(request.ContractMode, out var contractMode))
        {
            return BadRequest(new { error = "invalid_severity", message = "Mode must be \"Warning\" or \"Error\"" });
        }

        var settings = await _service.UpdateAsync(qualificationMode, absenceMode, workingHoursMode, overlapMode, contractMode, cancellationToken);
        return Ok(new AssignmentValidationSettingsResponse(
            settings.QualificationMode.ToString(),
            settings.AbsenceMode.ToString(),
            settings.WorkingHoursMode.ToString(),
            settings.OverlapMode.ToString(),
            settings.ContractMode.ToString()));
    }

    private static bool TryParseSeverity(string value, out ValidationSeverity severity)
        => Enum.TryParse(value, ignoreCase: true, out severity);
}
