using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Knot.Contracts.Settings.Domain;
using Knot.Modules.Federation.Application.Abstractions;
using Knot.Modules.Federation.Application.Federation.Services;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs;

namespace Knot.Modules.Federation.Application.Federation.Events;

/// <summary>
/// Обработчик события обновления настроек.
/// Уведомляет все удаленные серверы о смене способностей (Capabilities).
/// </summary>
public sealed class SystemSettingsUpdatedDomainEventHandler : INotificationHandler<SystemSettingsUpdatedDomainEvent>
{
    private readonly ISettingsService _settingsService;
    private readonly IFederationGateway _gateway;
    private readonly FederationPacketService _packetService;

    public SystemSettingsUpdatedDomainEventHandler(
        ISettingsService settingsService, 
        IFederationGateway gateway, 
        FederationPacketService packetService)
    {
        _settingsService = settingsService;
        _gateway = gateway;
        _packetService = packetService;
    }

    public async Task Handle(SystemSettingsUpdatedDomainEvent notification, CancellationToken cancellationToken)
    {
        var settings = await _settingsService.GetSettingsAsync(cancellationToken);
        if (!settings.Federation.Enabled) return;

        // Наши новые способности
        var ourCapabilities = new RemoteCapabilities
        {
            AllowMedia = settings.Messages.AllowMedia,
            AllowPolls = settings.Messages.AllowPolls,
            AllowVoiceMessages = settings.Messages.AllowVoiceMessages,
            AllowVideoCalls = settings.WebRtc.EnableVideoCalls,
            AllowScreenSharing = settings.WebRtc.EnableScreenSharing
        };

        // Собираем метаданные для синхронизации
        var metadata = new FederationMetadata(
            Guid.Empty, // Системный чат
            Guid.Empty, // Системный пользователь
            "SYSTEM",
            "sync_capabilities",
            DateTime.UtcNow
        );

        // Рассылка по всем доменам из белого списка (Fan-out)
        foreach (var domainConfig in settings.Federation.AllowedDomains.Where(d => d.IsEnabled))
        {
            // Упаковываем Capabilities в JSON для передачи в payload
            var payload = System.Text.Json.JsonSerializer.Serialize(ourCapabilities);
            
            var packetResult = await _packetService.PreparePacketAsync(payload, metadata, domainConfig.Domain, cancellationToken);
            
            if (packetResult.IsSuccess)
            {
                await _gateway.SendPacketAsync(packetResult.Value, domainConfig.Domain, cancellationToken);
            }
        }
    }
}


