using C4IT.DataHistoryProvider;
using C4IT.FASD.Base;
using C4IT.Logging;
using F4SDwebService;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using static C4IT.Logging.cLogManager;

namespace FasdWebService.Controllers
{
    [RoutePrefix("api/TicketOverview")]
    public class TicketOverviewController : ApiController
    {
        private static bool IsTicketOverviewEnabled()
        {
            return WebApiApplication.Collector?.GetGlobalConfig()?.TicketConfiguration?.ShowOverview == true;
        }

        [HttpGet]
        [Route("GetCounts")]
        public async Task<IHttpActionResult> GetCounts(string scope = "personal", string keys = "")
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            var requestInfo = new cF4sdWebRequestInfo("TicketOverview.GetCounts", scope ?? string.Empty, cAuthentication.GetUserInfo(ActionContext));
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }

            var apiError = 0;
            try
            {
                if (!IsTicketOverviewEnabled())
                {
                    return Ok(new TicketOverviewCountsResult());
                }

                var collector = WebApiApplication.Collector?.M42WpmCollector;
                if (collector == null)
                {
                    return Ok(new TicketOverviewCountsResult());
                }

                var useRoleScope = string.Equals(scope, "role", StringComparison.OrdinalIgnoreCase);
                var normalizedKeys = (keys ?? string.Empty)
                    .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(k => k.Trim())
                    .Where(k => !string.IsNullOrWhiteSpace(k))
                    .Distinct(StringComparer.OrdinalIgnoreCase)
                    .ToList();

                var counts = await collector.GetTicketOverviewCountsAsync(normalizedKeys, useRoleScope, requestInfo, 1, CancellationToken.None);
                return Ok(new TicketOverviewCountsResult
                {
                    Counts = counts,
                    Capabilities = new TicketOverviewCapabilities
                    {
                        TicketAndServiceRequestsEnabled = collector.TicketAndServiceRequestsEnabled
                    }
                });
            }
            catch (Exception E)
            {
                apiError = E.HResult;
                LogException(E);
            }
            finally
            {
                if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
                if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
                if (CM != null) LogMethodEnd(CM);
            }

            return Ok(new TicketOverviewCountsResult());
        }

        [HttpGet]
        [Route("GetRelations")]
        public async Task<IHttpActionResult> GetRelations(string key, string scope = "personal", int count = 0)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            var requestInfo = new cF4sdWebRequestInfo("TicketOverview.GetRelations", key ?? string.Empty, cAuthentication.GetUserInfo(ActionContext));
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }

            var apiError = 0;
            try
            {
                if (!IsTicketOverviewEnabled())
                {
                    return Ok(new List<cF4sdApiSearchResultRelation>());
                }

                var collector = WebApiApplication.Collector?.M42WpmCollector;
                if (collector == null)
                {
                    return Ok(new List<cF4sdApiSearchResultRelation>());
                }

                var useRoleScope = string.Equals(scope, "role", StringComparison.OrdinalIgnoreCase);
                var relations = await collector.GetTicketOverviewRelationsAsync(key, useRoleScope, Math.Max(0, count), requestInfo, 1, CancellationToken.None);
                return Ok(relations ?? new List<cF4sdApiSearchResultRelation>());
            }
            catch (Exception E)
            {
                apiError = E.HResult;
                LogException(E);
            }
            finally
            {
                if (WebApiApplication.Debug_apiTiming) WebApiApplication.SaveApiTimingEntry(requestInfo.requestName, requestInfo.id, requestInfo.created, apiError);
                if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
                if (CM != null) LogMethodEnd(CM);
            }

            return Ok(new List<cF4sdApiSearchResultRelation>());
        }
    }

    public class TicketOverviewCountsResult
    {
        [JsonProperty("counts")]
        public Dictionary<string, int> Counts { get; set; } = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

        [JsonProperty("capabilities")]
        public TicketOverviewCapabilities Capabilities { get; set; } = new TicketOverviewCapabilities();
    }

    public class TicketOverviewCapabilities
    {
        [JsonProperty("ticketAndServiceRequestsEnabled")]
        public bool TicketAndServiceRequestsEnabled { get; set; } = true;
    }
}
