using System;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using Knot.Contracts.Admin.Abstractions;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs;
using Knot.Modules.Admin.Application.Admin.DTOs;
using MediatR;

namespace Knot.Modules.Admin.Application.Admin.Commands;

public record UpdateSettingsCommand(SystemSettingsDto Settings) : ICommand<SystemSettingsDto>;

internal sealed class UpdateSettingsCommandHandler : ICommandHandler<UpdateSettingsCommand, SystemSettingsDto>
{
    private readonly ISettingsService _settingsService;
    private readonly IMediator _mediator;

    public UpdateSettingsCommandHandler(ISettingsService settingsService, IMediator mediator)
    {
        _settingsService = settingsService;
        _mediator = mediator;
    }

    public async Task<Result<SystemSettingsDto>> Handle(UpdateSettingsCommand request, CancellationToken cancellationToken)
    {
        // Если федерация включена, но ключи еще не сгенерированы — создаем их
        if (request.Settings.Federation.Enabled &&
            (string.IsNullOrEmpty(request.Settings.Federation.PrivateKey) ||
             string.IsNullOrEmpty(request.Settings.Federation.PublicKey)))
        {
            using var rsa = RSA.Create(2048);

            // Экспорт в формате PKCS#8 (Private) и PKCS#1 (Public) в Base64 PEM-строки
            request.Settings.Federation.PrivateKey = Convert.ToBase64String(rsa.ExportPkcs8PrivateKey());
            request.Settings.Federation.PublicKey = Convert.ToBase64String(rsa.ExportRSAPublicKey());
        }

        await _settingsService.UpdateSettingsAsync(request.Settings, cancellationToken);

        // Уведомляем другие модули (в т.ч. Федерацию) через Доменное Событие
        await _mediator.Publish(new Knot.Modules.Admin.Domain.Events.SystemSettingsUpdatedDomainEvent(request.Settings), cancellationToken);

        return Result.Success(request.Settings);
    }
}


