using Insight.Infrastructure.Entities;
using Insight.Infrastructure.Models;
using Insight.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;

namespace Insight.Api.Controllers
{
    [ApiController, Route("api/inventory")]
    public class InventoryController : ControllerBase
    {
        private readonly InventoryService _inventoryService;
        private readonly ILogger<InventoryController> _logger;

        public InventoryController(InventoryService inventoryService, ILogger<InventoryController> logger)
        {
            _inventoryService = inventoryService;
            _logger = logger;
        }

        [HttpGet, Authorize]
        public async Task<IActionResult> Get([FromQuery] HostApplicationEntity request, [FromQuery] PagedDataRequest meta, CancellationToken cancellationToken)
        {
            try
            {
                var filter = Builders<HostApplicationEntity>.Filter.Empty;

                if (request.Id is not null)
                    filter &= Builders<HostApplicationEntity>.Filter.Eq(p => p.Id, request.Id);

                if (request.Host is not null)
                    filter &= Builders<HostApplicationEntity>.Filter.Eq(p => p.Host, request.Host);

                if (request.Name is not null)
                    filter &= Builders<HostApplicationEntity>.Filter.Regex(p => p.Name, new BsonRegularExpression(new Regex(request.Name, RegexOptions.IgnoreCase)));

                var result = await _inventoryService.GetAsync(
                    filter: filter,
                    offset: meta.Offset,
                    limit: meta.Limit,
                    request: Request,
                    response: Response,
                    cancellationToken: cancellationToken).ConfigureAwait(false);

                return Ok(result);
            }
            catch (UnauthorizedAccessException ex)
            {
                return Unauthorized(ex.ToString());
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        public class ApplicationRequest
        {
            [JsonPropertyName("id")]
            public string? Id { get; set; }

            [JsonPropertyName("host")]
            public string? Host { get; set; }

            [JsonPropertyName("name")]
            public string? Name { get; set; }
        }
    }
}