using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb;
using AsbCloudDb.Model;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace AsbCloudInfrastructure.Repository;


public class EventRepository : IEventRepository
{
    private readonly IAsbCloudDbContext db;
    private readonly IMemoryCache memoryCache;
    private readonly ITelemetryService telemetryService;

    public EventRepository(IAsbCloudDbContext db, IMemoryCache memoryCache, ITelemetryService telemetryService)
    {
        this.db = db;
        this.memoryCache = memoryCache;
        this.telemetryService = telemetryService;
    }

    public async Task<IEnumerable<TelemetryEventDto>> GetAsync(TelemetryEventRequest request, CancellationToken token)
    {
        var allEvents = await memoryCache.GetOrCreateBasicAsync(db.Set<TelemetryEvent>(), token);
        var events = allEvents.Where(e => request.IdsTelemetries.Contains(e.IdTelemetry));

        if (request.IdsCategories?.Any() == true)
            events = events.Where(e => request.IdsCategories.Contains(e.IdCategory));

        if (!string.IsNullOrEmpty(request.SearchString))
            events = events.Where(e => e.MessageTemplate.Contains(request.SearchString, StringComparison.OrdinalIgnoreCase));

        var dtos = events.Select(e =>
        {
            var dto = new TelemetryEventDto();
            dto.Id = e.IdEvent;
            dto.IdCategory = e.IdCategory;
            dto.MessageTemplate = e.MessageTemplate;
            return dto;
        });

        return dtos;
    }

    public async Task UpsertAsync(string uid, IEnumerable<EventDto> dtos,
        CancellationToken token = default)
    {
        if (!dtos.Any())
            return;

        var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid);

        var entities = dtos.Select(dto => new TelemetryEvent
        {
            IdEvent = dto.Id,
            IdTelemetry = telemetry.Id,
            IdCategory = dto.IdCategory,
            MessageTemplate = dto.Message
        });
        await db.Database.ExecInsertOrUpdateAsync(db.TelemetryEvents, entities, token);
        memoryCache.DropBasic<TelemetryEvent>();
    }
}