using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using System.Linq;
using AsbCloudWebApi.SignalR;
using Microsoft.AspNetCore.SignalR;

namespace AsbCloudWebApi.Controllers;

/// <summary>
/// Редактор кустов для админки
/// </summary>
[Route("api/admin/[controller]")]
[ApiController]
[Authorize]
public class ReduceSamplingController: ControllerBase
{
    private readonly IReduceSamplingService service;
    private readonly IHubContext<TelemetryHub> telemetryHubContext;
    private const string sirnalRGroupName = "ReduceSampling";
    private const string sirnalRMethodOnProgress = "OnProgress";

    public ReduceSamplingController(
        IReduceSamplingService service,
        IHubContext<TelemetryHub> telemetryHubContext )
    {
        this.service = service;
        this.telemetryHubContext = telemetryHubContext;
    }

    /// <summary>
    /// Получить все задания. Задания удаляются минимум через 10 сек после выполнения, возможно позднее.
    /// </summary>
    /// <param name="idTelemetry"></param>
    /// <returns></returns>
    [HttpGet]
    public virtual ActionResult<IEnumerable<JobDto>> GetAll(int idTelemetry)
    {
        var result = service.GetJobs();
        if (result.Any())
            return Ok(result);
        else
            return NoContent();
    }

    /// <summary>
    /// Получить состояние определенной задачи
    /// </summary>
    /// <param name="idTelemetry"></param>
    /// <returns></returns>
    [HttpGet("{idTelemetry}")]
    public virtual ActionResult<JobDto> GetOrDefault(int idTelemetry)
    {
        var result = service.GetOrDefaultState(idTelemetry);
        return Ok(result);
    }

    /// <summary>
    /// Создать задачу прореживанию архива и добавить её в очередь на выполнение.
    /// Если задача есть в очереди, она же и возвращается, но подписка не происходит.
    /// </summary>
    [HttpPost]
    [Permission]
    public virtual ActionResult<JobDto> Enqueue(int idTelemetry)
    {
        void onProgress(JobDto job) =>
            Task.Run(async () =>
                await telemetryHubContext.Clients.Group(sirnalRGroupName)
                  .SendAsync(sirnalRMethodOnProgress, job));

        service.TryEnqueueRediceSamplingJob(idTelemetry, onProgress, out JobDto job);
        return Ok(job);
    }
}