using MesaFabApproval.API.Services;
using MesaFabApproval.Shared.Models;
using MesaFabApproval.Shared.Services;

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;

namespace MesaFabApproval.API.Controllers;

[ApiController]
[Authorize]
public class CustomerController : ControllerBase {
    private readonly ILogger<CustomerController> _logger;
    private readonly IMonInWorkerClient _monInClient;
    private readonly IMemoryCache _cache;
    private readonly ICustomerService _customerService;

    public CustomerController(ILogger<CustomerController> logger, IMonInWorkerClient monInClient, IMemoryCache cache, ICustomerService customerService) {
        _logger = logger ?? throw new ArgumentNullException("ILogger not injected");
        _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected");
        _cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
        _customerService = customerService ?? throw new ArgumentNullException("ICustomerService");
    }

    [HttpGet]
    [Route("customer/all")]
    public async Task<IActionResult> GetAllCustomerNames() {
        DateTime start = DateTime.Now;
        bool isInternalError = false;
        string errorMessage = "";

        try {
            _logger.LogInformation("Attempting to get all customer names");

            IEnumerable<string> customerNames = await _customerService.GetCustomerNames();

            return Ok(customerNames);
        } catch (Exception ex) {
            isInternalError = true;
            errorMessage = $"Cannot get user by LoginID, because {ex.Message}";
            return Problem(errorMessage);
        } finally {
            string metricName = "GetAllCustomerNames";
            DateTime end = DateTime.Now;
            double millisecondsDiff = (end - start).TotalMilliseconds;
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);

            if (isInternalError) {
                _logger.LogError(errorMessage);
                _monInClient.PostStatus(metricName, StatusValue.Critical);
            } else {
                _monInClient.PostStatus(metricName, StatusValue.Ok);
            }
        }
    }
}