using System;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services.Notifications;
using AsbCloudWebApi.SignalR.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace AsbCloudWebApi.Controllers;

/// <summary>
/// Уведомления
/// </summary>
[ApiController]
[Authorize]
[Route("api/[controller]")]
[Obsolete("Это тестовый контроллер, его нельзя использовать на фронте.")]
public class NotificationController : ControllerBase
{
   private readonly NotificationService notificationService;
   private readonly INotificationRepository notificationRepository;
   private readonly NotificationPublisher notificationPublisher;

   public NotificationController(NotificationService notificationService,
      INotificationRepository notificationRepository,
      NotificationPublisher notificationPublisher)
   {
      this.notificationService = notificationService;
      this.notificationRepository = notificationRepository;
      this.notificationPublisher = notificationPublisher;
   }

   /// <summary>
   /// Отправка уведомления
   /// </summary>
   /// <param name="request">Параметры запроса</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpPost]
   public async Task<IActionResult> SendAsync(NotifyRequest request, CancellationToken cancellationToken)
   {
      await notificationService.NotifyAsync(request, cancellationToken);

      return Ok();
   }

   /// <summary>
   /// Обновление уведомления
   /// </summary>
   /// <param name="idNotification">Id уведомления</param>
   /// <param name="isRead">Прочитано ли уведомление</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpPut]
   public async Task<IActionResult> UpdateAsync([Required] int idNotification,
      [Required] bool isRead,
      CancellationToken cancellationToken)
   {
      var idUser = User.GetUserId();

      if (!idUser.HasValue)
         return Forbid();
      
      await notificationService.UpdateAsync(idNotification,
         isRead,
         cancellationToken);

      await notificationPublisher.PublishCountUnreadAsync(idUser.Value, cancellationToken);
      
      return Ok();
   }

   /// <summary>
   /// Получение уведомления по Id
   /// </summary>
   /// <param name="idNotification">Id уведомления</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpGet("{idNotification}")]
   [ProducesResponseType(typeof(NotificationDto), (int)System.Net.HttpStatusCode.OK)]
    [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
    public async Task<IActionResult> GetAsync([Required] int idNotification,
      CancellationToken cancellationToken)
   {
      var notification = await notificationRepository.GetOrDefaultAsync(idNotification, cancellationToken);
      if (notification is null)
            return this.ValidationBadRequest(nameof(idNotification), "Уведомление не найдено");

        return Ok(notification);
   }

   /// <summary>
   /// Получение списка уведомлений
   /// </summary>
   /// <param name="request">Параметры запроса</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpGet]
   [ProducesResponseType(typeof(PaginationContainer<NotificationDto>), (int)System.Net.HttpStatusCode.OK)]
   public async Task<IActionResult> GetListAsync([FromQuery] NotificationRequest request,
      CancellationToken cancellationToken)
   {
      int? idUser = User.GetUserId();

      if (!idUser.HasValue)
         return Forbid();

      var result = await notificationRepository.GetNotificationsAsync(idUser.Value,
         request,
         cancellationToken);

      return Ok(result);
   }

   /// <summary>
   /// Удаление уведомления
   /// </summary>
   /// <param name="idNotification">Id уведомления</param>
   /// <param name="cancellationToken"></param>
   /// <returns></returns>
   [HttpDelete("{idNotification}")]
   public async Task<IActionResult> DeleteAsync([Required] int idNotification,
      CancellationToken cancellationToken)
   {
      await notificationRepository.DeleteAsync(idNotification,
         cancellationToken);

      return Ok();
   }

   /// <summary>
    /// Удаление уведомлений
    /// </summary>
    /// <param name="request">Параметры запроса</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [HttpDelete]
   public async Task<IActionResult> DeleteAsync(NotificationDeleteRequest request,
      CancellationToken cancellationToken)
   {
      await notificationRepository.DeleteAsync(request, cancellationToken);

      return Ok();
   }
}