using AsbCloudApp.Services;
using AsbCloudApp.Data;
using AsbCloudDb.Model;
using System;
using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using AsbSaubReport;

namespace AsbCloudInfrastructure.Services
{
    public class ReportService : IReportService
    {
        private readonly IAsbCloudDbContext db;
        private readonly IConfiguration configuration;
        private readonly ITelemetryService telemetryService;
        private readonly IBackgroundQueue queue;

        public ReportService(IAsbCloudDbContext db, IConfiguration configuration, ITelemetryService telemetryService, IBackgroundQueue queue)
        {
            this.db = db;
            this.configuration = configuration;
            this.telemetryService = telemetryService;
            this.queue = queue;
            RootPath = "reports";
        }

        public string RootPath { get ; private set; }

        public int CreateReport(int wellId, int stepSeconds, int format, DateTime begin, 
            DateTime end, Action<float , string , int> progressHandler)
        {
            var newReportId = queue.EnqueueTask((id) =>
            {
                var optionsBuilder = new DbContextOptionsBuilder<AsbCloudDbContext>();
                optionsBuilder.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));

                using (var context = new AsbCloudDbContext(optionsBuilder.Options))
                {
                    var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format, context);
                    generator.OnProgress += (s,e) => progressHandler.Invoke(e.progress, e.operation, id);
                    generator.Make();
                }
            });
            return newReportId;
        }

        public int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format)
        {
            var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format, (AsbCloudDbContext)db);

            return generator.GetPagesCount();
        }

        public DatesRangeDto GetReportsDatesRange(int wellId)
        {
            var telemetry = telemetryService.GetTelemetryByWellId(wellId);

            if (telemetry is null)
                return null;

            var (From, To) = db.GetDatesRange<Report>(telemetry.Id);

            return new DatesRangeDto { From = From, To = To };
        }

        private IReportGenerator GetReportGenerator(int wellId, DateTime begin, DateTime end, int stepSeconds, int format, AsbCloudDbContext context)
        {
            var dataSource = new ReportDataSourcePgCloud(context, wellId);
            var generator = new PdfGenerator(dataSource)
            {
                ReportDirectory = Path.Combine(RootPath, $"{wellId}"),
                Begin = begin,
                End = end,
                Step = TimeSpan.FromSeconds(stepSeconds),
                WithCharts = true,
                WithEvents = true
            };

            switch(format)
            {
                case 0:
                    return generator;
                case 1:
                    return generator;
                default:
                    return generator;
            }
        }
    }
}