using Microsoft.Extensions.Logging;
using Microsoft.JSInterop;
using SyncfusionSchedulerDeleteBug.Business.Events;
using SyncfusionSchedulerDeleteBug.Business.Interfaces;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SyncfusionSchedulerDeleteBug.Blazor.Server
{
    public sealed class TimeZoneService
    {
        private readonly IJSRuntime _jsRuntime;
        private readonly ILogger<TimeZoneService> _logger;

        private TimeSpan? _userOffset;
        private int _offsetInMinutes;

        public TimeZoneService(IJSRuntime jsRuntime, ILogger<TimeZoneService> logger)
        {
            _jsRuntime = jsRuntime;
            _logger = logger;
        }

        public async ValueTask<DateTimeOffset> GetLocalDateTime()
        {
            await getUserOffset();

            return DateTimeOffset.UtcNow.ToOffset(_userOffset.Value);
        }

        public async ValueTask<TimeSpan?> GetUserOffset()
        {
            await getUserOffset();

            if (_userOffset.HasValue)
                return _userOffset.Value;
            else
                return null;
        }

        private async Task getUserOffset()
        {
            if (!_userOffset.HasValue)
            {
                try
                {
                    _offsetInMinutes = await _jsRuntime.InvokeAsync<int>("blazorGetTimezoneOffset");
                    _userOffset = TimeSpan.FromMinutes(-_offsetInMinutes);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Unable to read user offset due to an error");
                }
            }                
        }

        public async Task ApplyOffset(IHoldOffsetDates list)
        {
            if (list is null)
                return;

            TimeSpan? offset = await GetUserOffset();

            if (offset.HasValue)
            {
                try
                {
                    list.ApplyUserOffset(_userOffset.Value);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Unable to apply user offset due to an error");
                }
            }
        }
    }
}
