using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using OmsorgCore.Api.Contracts;
using OmsorgCore.Api.Security;
using OmsorgCore.Application.Abstractions;
using OmsorgCore.Domain.Enums;
using OmsorgCore.Email;

namespace OmsorgCore.Api.Controllers;

/// <summary>
/// Debug-/Admin-Funktion, um den konfigurierten Mail-Versand zu testen (siehe omsorgapp Debug-Seite).
/// Sendet nur eine Testmail über den registrierten IEmailSender, mit vom Admin editierbarem Betreff/Text
/// (vorbefüllt aus der echten Passwort-Reset-Vorlage) - SMTP-Zugangsdaten selbst verlassen den Server
/// dabei zu keinem Zeitpunkt.
/// </summary>
[ApiController]
[Authorize]
[Route("api/admin/email")]
public class AdminEmailController : ControllerBase
{
    private readonly IEmailSender _emailSender;
    private readonly EmailOptions _emailOptions;
    private readonly ILogger<AdminEmailController> _logger;

    public AdminEmailController(IEmailSender emailSender, IOptions<EmailOptions> emailOptions, ILogger<AdminEmailController> logger)
    {
        _emailSender = emailSender;
        _emailOptions = emailOptions.Value;
        _logger = logger;
    }

    [HttpGet("password-reset-template")]
    [RequirePermission(ModuleType.UserManagement, PermissionAction.View)]
    public ActionResult<PasswordResetTemplateResponse> GetPasswordResetTemplate()
    {
        var template = _emailOptions.PasswordResetTemplate;
        return Ok(new PasswordResetTemplateResponse(template.Subject, template.BodyTemplate));
    }

    [HttpPost("test-send")]
    [RequirePermission(ModuleType.UserManagement, PermissionAction.Edit)]
    public async Task<IActionResult> TestSend(SendTestEmailRequest request, CancellationToken cancellationToken)
    {
        if (string.IsNullOrWhiteSpace(request.ToAddress))
        {
            return BadRequest(new { error = "to_address_required" });
        }

        var template = _emailOptions.PasswordResetTemplate;
        var subject = string.IsNullOrWhiteSpace(request.Subject) ? template.Subject : request.Subject;
        var body = string.IsNullOrWhiteSpace(request.Body) ? template.BodyTemplate : request.Body;

        // Testmail nutzt echte Platzhalter-Ersetzung (mit Beispiel-Werten), damit sie genau zeigt,
        // was ein Nutzer im echten Reset-Flow bekommen würde.
        var values = new Dictionary<string, string>
        {
            ["RESET_PIN"] = "123456",
            ["RESET_PIN_EXPIRY_MINUTES"] = _emailOptions.PinExpiryMinutes.ToString()
        };
        subject = EmailTemplateRenderer.Render(subject, values);
        body = EmailTemplateRenderer.Render(body, values);

        try
        {
            await _emailSender.SendAsync(new EmailMessage(request.ToAddress, subject, body), cancellationToken);
        }
        catch (Exception ex)
        {
            // Admin-only (RequirePermission oben) - die Exception-Message darf hier raus, sie enthält
            // keine SMTP-Zugangsdaten (nur MailKit-Fehlertext wie "Authentication failed"/"Connection
            // refused") und ist genau das, was zum Debuggen der Email:*-Konfiguration gebraucht wird.
            _logger.LogError(ex, "Test-Mail konnte nicht gesendet werden an {ToAddress}", request.ToAddress);
            return StatusCode(StatusCodes.Status502BadGateway, new { error = "send_failed", message = ex.Message });
        }

        return NoContent();
    }
}
