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);
        }
    }
}