using FluentValidation;

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

using Monitoring.Common;
using Monitoring.Controllers;
using Monitoring.Features.Reports.Contracts;
using Monitoring.Models;

namespace Monitoring.Features.Reports;
/// <summary>
/// Контроллер для работы с отчётами.
/// </summary>
[Route("api/reports")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Roles = Roles.Watcher)]
public class ReportsController(
	ReportRepository reportRepository
) : BaseController
{
	[HttpGet(Name = "GetReportList")]
	[ProducesResponseType<TableDataResponseModel<GetReportsResponseItem>>(StatusCodes.Status200OK)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> GetList(
		[FromQuery] GetReportListRequest request,
		IValidator<GetReportListRequest> validator,
		CancellationToken cancellationToken)
	{
		var validationResult = await validator.ValidateAsync(request, cancellationToken);
		if (!validationResult.IsValid)
		{
			return BadRequest(validationResult.Errors);
		}

		var result = await reportRepository.GetList(UserId, request, cancellationToken);
		return result.IsSuccess ? Ok(result.Value) : BadRequest(result.Error);
	}

	[HttpGet("{id:guid}", Name = "GetReport")]
	[ProducesResponseType<GetReportResponse>(StatusCodes.Status200OK)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> Get(
		Guid id,
		CancellationToken cancellationToken)
	{
		var result = await reportRepository.Get(id, UserId, cancellationToken);
		return result.IsSuccess ? Ok(result.Value) : BadRequest(result.Error);
	}

	[HttpPost(Name = "CreateReport")]
	[ProducesResponseType<CreateReportResponse>(StatusCodes.Status200OK)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> CreateReport(CreateReportRequest request, CancellationToken cancellationToken)
	{
		var result = await reportRepository.Create(request, UserId, cancellationToken);
		return result.IsSuccess ? Ok(result.Value) : BadRequest(result.Error);
	}

	[HttpDelete("{id:guid}", Name = "DeleteReport")]
	[ProducesResponseType(StatusCodes.Status204NoContent)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> Delete(Guid id, CancellationToken cancellationToken)
	{
		var result = await reportRepository.Delete(id, UserId, cancellationToken);
		return result.IsSuccess ? NoContent() : BadRequest(result.Error);
	}

	[HttpDelete(Name = "DeleteAllReports")]
	[ProducesResponseType(StatusCodes.Status204NoContent)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> DeleteAll(CancellationToken cancellationToken)
	{
		var result = await reportRepository.DeleteAll(UserId, cancellationToken);
		return result.IsSuccess ? NoContent() : BadRequest(result.Error);
	}
}