using AsbCloudApp.Data;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.SAUB;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace AsbCloudWebApi.Tests.ServicesTests
{
    public class TelemetryDataSaubServiceTest
    {
        private readonly Mock<ITelemetryTracker> telemetryTracker;
        private readonly Mock<ITimezoneService> timezoneService;
        private readonly SimpleTimezoneDto timezone;
        private readonly AsbCloudDbContext context;
        private readonly TelemetryService telemetryService;
        private readonly TelemetryUserService telemetryUserService;
        private readonly TelemetryDataCache<TelemetryDataSaubDto> telemetryDataSaubCache;
        private readonly DateTime drillingStartDate;
        private readonly string uuid;
        public TelemetryDataSaubServiceTest()
        {
            timezone = new() { Hours = 7 };
            drillingStartDate = new DateTime(2022, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
            uuid = drillingStartDate.ToString("yyyyMMdd_HHmmssfff");

            AsbCloudInfrastructure.DependencyInjection.MapsterSetup();

            telemetryTracker = new Mock<ITelemetryTracker>();
            timezoneService = new Mock<ITimezoneService>();
            timezoneService.Setup(s => s.GetByCoordinatesAsync(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<CancellationToken>()))
                .Returns(Task.FromResult(timezone));
            timezoneService.Setup(s => s.GetByCoordinates(It.IsAny<double>(), It.IsAny<double>()))
                .Returns(timezone);

            context = TestHelpter.MakeRealTestContext();
            telemetryService = new TelemetryService(context, telemetryTracker.Object, timezoneService.Object);
            telemetryUserService = new TelemetryUserService(context, telemetryService, TestHelpter.MemoryCache);
            telemetryDataSaubCache = TelemetryDataCache<TelemetryDataSaubDto>.GetInstance<TelemetryDataSaub>(context, out Task _);
            var info = new TelemetryInfoDto
            {
                TimeZoneOffsetTotalHours = timezone.Hours,
                DrillingStartDate = drillingStartDate,
            };
            telemetryService.UpdateInfoAsync(uuid, info, CancellationToken.None).Wait();

        }
        ~TelemetryDataSaubServiceTest()
        {
            var ts = context.Telemetries.Where(t => t.RemoteUid == uuid);
            context.Telemetries.RemoveRange(ts);
            context.SaveChanges();
            context?.Dispose();
        }

        [Fact]
        public async Task UpdateDataAsync()
        {
            // Arrange
            var telemetryDataSaubService = new TelemetryDataSaubService(context, telemetryService, telemetryUserService, telemetryDataSaubCache);

            var now = DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(timezone.Hours)).DateTime;
            var tuser = "Завулон";
            var newData = new List<TelemetryDataSaubDto>
            {
                new TelemetryDataSaubDto{
                    DateTime = now,
                    AxialLoad = 1,
                    MseState = 1,
                    User = tuser,
                }
            };

            // act
            var affected = await telemetryDataSaubService.UpdateDataAsync(uuid, newData, CancellationToken.None);

            // assert
            Assert.Equal(1, affected);
        }
    }
}