using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace AsbCloudWebApi.Controllers;

/// <summary>
/// Ствол скважины
/// </summary>
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class WellboreController : ControllerBase
{
	private readonly IWellboreService wellboreService;

	public WellboreController(IWellboreService wellboreService)
	{
		this.wellboreService = wellboreService;
	}
	
	/// <summary>
	/// Получение ствола скважины
	/// </summary>
	/// <param name="idWell">Id скважины</param>
	/// <param name="idSection">Id типа секции скважины</param>
	/// <param name="cancellationToken"></param>
	/// <returns></returns>

	[HttpGet("{idWell:int}/{idSection:int}")]
	[ProducesResponseType(typeof(WellboreDto), StatusCodes.Status200OK)]
	[ProducesResponseType(StatusCodes.Status204NoContent)]
	public async Task<IActionResult> GetAsync(int idWell, int idSection, CancellationToken cancellationToken)
	{
		var wellbore = await wellboreService.GetWellboreAsync(idWell, idSection, cancellationToken);

		if (wellbore is null)
			return NoContent();
		
		return Ok(wellbore);
	}

	/// <summary>
	/// Получение списка стволов скважин
	/// </summary>
	/// <param name="ids">Пары идентификаторов скважины и секции</param>
	/// <param name="skip">Опциональный параметр. Количество пропускаемых записей</param>
	/// <param name="take">Опциональный параметр. Количество получаемых записей</param>
	/// <param name="cancellationToken"></param>
	/// <returns></returns>
	[HttpGet]
	[ProducesResponseType(typeof(IEnumerable<WellboreDto>), StatusCodes.Status200OK)]
	public async Task<IActionResult> GetAllAsync([FromQuery] IEnumerable<string> ids, 
		int? skip, 
		int? take, 
		CancellationToken cancellationToken)
	{
		var request = new WellboreRequest
		{
			Ids = ids.Select(id => ParseId(id)),
			Skip = skip,
			Take = take
		};

		return Ok(await wellboreService.GetWellboresAsync(request, cancellationToken));
	}

    private static (int, int?) ParseId(string id)
	{
        var idPair = id.Split(',');
        if (!int.TryParse(idPair[0], out var idWell))
            throw new ArgumentInvalidException($"Не удалось получить Id скважины \"{idPair[0]}\"", nameof(id));

		if (idPair.Length > 1)
		{
			if (int.TryParse(idPair[1], out int idWellSectionType))
				return (idWell, idWellSectionType);
			else
                throw new ArgumentInvalidException($"Не удалось получить Id ствола \"{idPair[1]}\"", nameof(id));
        }
		return (idWell, null);
    }
}