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

namespace AsbCloudWebApi.Controllers.SAUB
{
    /// <summary>
    /// Инфо о передающих телеметрию устройствах
    /// </summary>
    [Route("api/telemetry")]
    [ApiController]
    public class TelemetryController : ControllerBase
    {
        private readonly ITelemetryService telemetryService;
        private readonly IMessageService messageService;
        private readonly IEventService eventService;
        private readonly ITelemetryUserService telemetryUserService;
        private readonly IHubContext<TelemetryHub> telemetryHubContext;

        public TelemetryController(
            ITelemetryService telemetryService,
            IMessageService messageService,
            IEventService eventService,
            ITelemetryUserService telemetryUserService,
            IHubContext<TelemetryHub> telemetryHubContext)
        {
            this.telemetryService = telemetryService;
            this.messageService = messageService;
            this.eventService = eventService;
            this.telemetryUserService = telemetryUserService;
            this.telemetryHubContext = telemetryHubContext;
        }

        /// <summary>
        /// Принимает общую информацию по скважине
        /// </summary>
        /// <param name="uid">Уникальный идентификатор отправителя</param>
        /// <param name="info">Информация об отправителе</param>
        /// <param name="token">Токен отмены задачи</param>
        /// <returns></returns>
        [HttpPost("{uid}/info")]
        public async Task<IActionResult> PostInfoAsync(string uid, [FromBody] TelemetryInfoDto info,
            CancellationToken token)
        {
            await telemetryService.UpdateInfoAsync(uid, info, token).ConfigureAwait(false);
            return Ok();
        }

        /// <summary>
        /// Принимает список новых сообщений от телеметрии
        /// </summary>
        /// <param name="uid">Уникальный идентификатор отправителя</param>
        /// <param name="dtos">сообщения</param>
        /// <param name="token">Токен для отмены задачи</param>
        /// <returns></returns>
        [HttpPost("{uid}/message")]
        public async Task<IActionResult> PostMessagesAsync(string uid, [FromBody] IEnumerable<TelemetryMessageDto> dtos,
            CancellationToken token)
        {
            var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
            await messageService.InsertAsync(uid, dtos, token).ConfigureAwait(false);

            if (dtos.Any())
                await Task.Run(() => telemetryHubContext.Clients.Group($"well_{idWell}")
                .SendAsync("ReceiveMessages", dtos), token).ConfigureAwait(false);

            return Ok();
        }

        /// <summary>
        /// Принимает справочник событий
        /// </summary>
        /// <param name="uid">Уникальный идентификатор отправителя</param>
        /// <param name="events">справочник событий</param>
        /// <param name="token">Токен для отмены задачи</param>
        /// <returns></returns>
        [HttpPost("{uid}/event")]
        public async Task<IActionResult> PostEventsAsync(string uid, [FromBody] List<EventDto> events,
            CancellationToken token)
        {
            await eventService.UpsertAsync(uid, events, token)
                .ConfigureAwait(false);
            return Ok();
        }

        /// <summary>
        /// Принимает справочник пользователей телеметрии
        /// </summary>
        /// <param name="uid">Уникальный идентификатор отправителя</param>
        /// <param name="users">справочник пользователей телеметрии</param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost("{uid}/user")]
        public async Task<IActionResult> PostUsersAsync(string uid, [FromBody] List<TelemetryUserDto> users,
            CancellationToken token)
        {
            await telemetryUserService.UpsertAsync(uid, users, token);
            return Ok();
        }
    }
}