using e_suite.Database.Core;
using e_suite.Service.Performance.Interfaces;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

namespace e_suite.Service.Performance.Repository;

public class PerformanceRepository : IPerformanceRepository
{
    private readonly IEsuiteDatabaseDbContext _esuiteDatabaseDbContext;
    private readonly IPerformanceCache _performanceCache;

    public PerformanceRepository(IEsuiteDatabaseDbContext esuiteDatabaseDbContext, IPerformanceCache performanceCache)
    {

        _esuiteDatabaseDbContext = esuiteDatabaseDbContext;
        _performanceCache = performanceCache;
    }

    public async Task<long> GetSlowPerformanceThresholdMsAsync(PerformanceCapture performanceReport)
    {
        var cacheResult = _performanceCache.GetTimeoutFromCache(performanceReport);
        if (cacheResult.HasValue)
        {
            return cacheResult.Value;
        }
        var totalTimeMSObj = await _esuiteDatabaseDbContext.PerformanceThresholds
            .Where(p => p.ControllerName == performanceReport.ControllerName &&
            p.ActionName == performanceReport.ActionName &&
            p.RequestType == performanceReport.RequestType).Select(r => new { r.TotalTimeMS })
            .Union(_esuiteDatabaseDbContext.PerformanceThresholds
                .Where(p => p.ControllerName == string.Empty &&
              p.ControllerName == string.Empty &&
              p.RequestType == string.Empty)
                .Select(r => new { r.TotalTimeMS })).FirstOrDefaultAsync();
        var res = (long)totalTimeMSObj!.TotalTimeMS;
        _performanceCache.UpdateTimeoutCache(performanceReport, res);
        return res;
    }

    public async Task DeleteLogsBefore(DateTimeOffset cutoffTime)
    {
        var oldRows = _esuiteDatabaseDbContext.PerformanceReports.Where(x => x.StartDateTime < cutoffTime);
        _esuiteDatabaseDbContext.PerformanceReports.RemoveRange(oldRows);

        await _esuiteDatabaseDbContext.NoAuditSaveChangesAsync();
    }

    public async Task SaveReportAsync(PerformanceReport performanceReport)
    {
        await _esuiteDatabaseDbContext.PerformanceReports.AddAsync(new Database.Core.Tables.Diagnostics.PerformanceReport()
        {
            Host = performanceReport.Host,
            ActionName = performanceReport.ActionName,
            ControllerName = performanceReport.ControllerName,
            RequestType = performanceReport.RequestType,
            ActionParameters = JsonConvert.SerializeObject(performanceReport.ActionParameters),
            StartDateTime = performanceReport.StartDateTime,
            Timings = JsonConvert.SerializeObject(performanceReport.Timings.Timings),
            TotalTimeMS = (int)performanceReport.Timings.TotalTimeMS
        });

        await _esuiteDatabaseDbContext.NoAuditSaveChangesAsync();
    }
}
