using AyCode.Core.Enums;
using AyCode.Core.Helpers;
using AyCode.Core.Loggers;
using AyCode.Entities;
using AyCode.Entities.LogItems;
using Microsoft.AspNetCore.SignalR.Client;

namespace AyCode.Services.Loggers
{
    public class AcSignaRClientLogItemWriter : AcLogItemWriterBase<AcLogItemClient>, IAcLogWriterClientBase
    {
        private readonly HubConnection _hubConnection;

        public AcSignaRClientLogItemWriter(string fullHubName, AppType appType = AppType.Web, LogLevel logLevel = LogLevel.Detail, string? categoryName = null) : base(appType, logLevel, categoryName)
        {
            _hubConnection = new HubConnectionBuilder()
                .WithUrl(fullHubName)
                //.WithAutomaticReconnect()
                //.AddMessagePackProtocol(options => options.SerializerOptions = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData))
                .Build();

            _hubConnection.StartAsync().Forget();
        }

        public async Task StartConnection()
        {
            if (_hubConnection.State == HubConnectionState.Disconnected)
                await _hubConnection.StartAsync();

            if (_hubConnection.State != HubConnectionState.Connected)
                await TaskHelper.WaitToAsync(() => _hubConnection.State == HubConnectionState.Connected, 10000, 10, 25);
        }

        public async Task StopConnection()
        {
            await _hubConnection.StopAsync();
            await _hubConnection.DisposeAsync();
        }

        public override void Write(AppType appType, LogLevel logLevel, string? logText, string? callerMemberName, string? categoryName, string? errorType, string? exMessage)
            => WriteLogItem(CreateLogItem(DateTime.UtcNow, appType, Environment.CurrentManagedThreadId, logLevel, logText, callerMemberName, categoryName, errorType, exMessage));

        protected override async void WriteLogItemCallback(AcLogItemClient logItem)
        {
            //Ez fontos, mert a signalR nem küldi a DateTime.Kind-ot! A szeró oldalon kap egy utc DateTime-ot, ami a kliens lokális DateTime-ját tartalmazza! - J.
            logItem.TimeStampUtc = logItem.TimeStampUtc.ToUniversalTime();

            await StartConnection();

            if (_hubConnection.State != HubConnectionState.Connected)
                return;

            //var refreshToken = Setting.UserBasicDetails?.RefreshToken ?? Guid.NewGuid().ToString("N");
            _hubConnection.SendAsync("AddLogItem", /*refreshToken,*/ logItem).Forget();
        }
    }
}
