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