using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace AsbCloudInfrastructure.Repository
{

    public class LimitingParameterRepository : ILimitingParameterRepository
    {
        private readonly IAsbCloudDbContext context;

        public LimitingParameterRepository(IAsbCloudDbContext context)
        { 
            this.context = context;
        }

        public async Task<IEnumerable<LimitingParameterDataDto>> GetLimitingParametersAsync(LimitingParameterRequest request, WellDto wellDto, CancellationToken token)
        {
            var timezoneOffset = wellDto.Timezone.Hours;
            var IdTelemetry = wellDto.IdTelemetry!.Value;
            return await GetLimitingParametersAsync(request, IdTelemetry, timezoneOffset, token);
        }

        public async Task<IEnumerable<LimitingParameterDataDto>> GetLimitingParametersAsync(LimitingParameterRequest request, int idTelemetry, double timezoneHours, CancellationToken token)
        {
            var timezoneSpan = TimeSpan.FromHours(timezoneHours);
            var query = BuildQuery(request, idTelemetry, timezoneHours);

            var data = (await query.ToListAsync(token))
                .Select(x => new LimitingParameterDataDto
                {
                    IdWell = request.IdWell,
                    IdTelemetry = x.IdTelemetry,
                    IdFeedRegulator = x.IdFeedRegulator,
                    DateStart = x.DateStart.ToOffset(timezoneSpan),
                    DateEnd = x.DateEnd.ToOffset(timezoneSpan),
                    DepthStart = x.DepthStart,
                    DepthEnd = x.DepthEnd
                });
            return data;
        }

        private IQueryable<LimitingParameter> BuildQuery(LimitingParameterRequest request, int idTelemetry, double timezoneHours)
        {
            var query = context.LimitingParameter
                .OrderBy(x => x.Id)
                .Where(x => x.IdTelemetry == idTelemetry)
                .AsNoTracking();

            if (request.GtDate.HasValue)
            {
                var gtDate = request.GtDate.Value.ToUniversalTime();
                query = query.Where(x => x.DateEnd >= gtDate);
            }

            if (request.LtDate.HasValue)
            {
                var ltDate = request.LtDate.Value.ToUniversalTime();
                query = query.Where(x => x.DateStart <= ltDate);
            }

            if (request.GtDepth.HasValue)
                query = query.Where(x => x.DepthEnd >= request.GtDepth.Value);

            if (request.LtDepth.HasValue)
                query = query.Where(x => x.DepthStart <= request.LtDepth.Value);

            return query;
        }
    }

}