using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Threading;
using System.Web.Http;

using C4IT.FASD.Base;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using C4IT.DataHistoryProvider;

namespace F4SDwebService.Controllers
{

    public class F4SDAnalyticsDataController : ApiController
    {

        [HttpGet]
        [Route("api/F4SDAnalytics/GetF4SDAnalyticsState")]
        public IHttpActionResult GetF4SDAnalyticsState()
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            try
            {
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                    return Ok<bool>(false);

                return Ok<bool>(true);
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }

            return BadRequest();
        }

        [HttpPost]
        [Route("api/F4SDAnalytics/CreateUserSession")]
        public async Task<IHttpActionResult> CreateUserSession([FromBody] cF4SDUserSessionParameters jsonRequest)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            var requestInfo = new cF4sdWebRequestInfo("CreateUserSession", jsonRequest?.SessionId?.ToString());
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
            var apiError = 0;

            try
            {
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                    return NotFound();

                if (await WebApiApplication.Collector.CreateUserSessionAsync(jsonRequest, requestInfo, 1, CancellationToken.None))
                    return Ok();
            }
            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 BadRequest();
        }

        [HttpPost]
        [Route("api/F4SDAnalytics/CloseUserSession")]
        public async Task<IHttpActionResult> CloseUserSession([FromBody] cF4SDUserSessionParameters jsonRequest)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            var requestInfo = new cF4sdWebRequestInfo("CloseUserSession", jsonRequest?.SessionId?.ToString());
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
            var apiError = 0;

            try
            {
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                    return NotFound();
                if (await WebApiApplication.Collector.CloseUserSessionAsync(jsonRequest, requestInfo, 1 , CancellationToken.None))
                    return Ok();
            }
            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 BadRequest();
        }


        [HttpPost]
        [Route("api/F4SDAnalytics/CreateCase")]
        public async Task<IHttpActionResult> CreateCase([FromBody] cF4SDCaseParameters jsonRequest)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            var requestInfo = new cF4sdWebRequestInfo("CreateCase", jsonRequest?.SessionId?.ToString());
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
            var apiError = 0;

            try
            {
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                {
                    return NotFound();
                }
                if (await WebApiApplication.Collector.CreateCaseAsync(jsonRequest, requestInfo, 1, CancellationToken.None))
                {

                    return Ok();
                }
            }
            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 BadRequest();
        }

        [HttpPost]
        [Route("api/F4SDAnalytics/UpdateCaseState")]
        public async Task<IHttpActionResult> UpdateCaseState([FromBody] cF4SDCaseTimeParameters jsonRequest)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            var requestInfo = new cF4sdWebRequestInfo("UpdateCaseState", jsonRequest?.CaseId?.ToString());
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
            var apiError = 0;

            try
            {
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                    return NotFound();
                if (await WebApiApplication.Collector.UpdateCaseStateAsync(jsonRequest, requestInfo, 1, CancellationToken.None))
                    return Ok();

            }
            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 BadRequest();
        }

        [HttpPost]
        [Route("api/F4SDAnalytics/ReportQuickActionExecution")]
        public async Task<IHttpActionResult> ReportQuickActionExecution([FromBody] cF4SDQuickActionParameters jsonRequest)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            var requestInfo = new cF4sdWebRequestInfo("ReportQuickActionExecution", jsonRequest?.DeviceId?.ToString());
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
            var apiError = 0;

            try
            {
                if (!WebApiApplication.Collector.IsValid)
                    return NotFound();

                List<Task<bool>> taskList = new List<Task<bool>>();

                if (WebApiApplication.Collector.F4SDAnalyticsValid)
                    taskList.Add(WebApiApplication.Collector.ReportQuickActionExecutionAsync(jsonRequest, WebApiApplication.Collector.InfrastructureConfig.F4SDAnalyticsDB.Connection, requestInfo, 1, CancellationToken.None));

                await Task.WhenAll(taskList).ConfigureAwait(false);

                if (taskList.All(taskResult => taskResult.Result.Equals(true)))
                    return Ok();

                return BadRequest();
            }
            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 BadRequest();
        }

        [HttpPost]
        [Route("api/F4SDAnalytics/KeepAliveSession")]
        public IHttpActionResult KeepAliveSession([FromBody] Guid SessionId)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            try
            {
                LogEntry($"API Call KeepAliveSession: " + SessionId.ToString());
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                    return NotFound();

                if (WebApiApplication.Collector.KeepAliveSession(SessionId, CancellationToken.None))
                    return Ok();
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }

            return BadRequest();
        }

        [HttpPost]
        [Route("api/F4SDAnalytics/KeepAliveCase")]
        public async Task<IHttpActionResult> KeepAliveCase([FromBody] Guid CaseId)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            var requestInfo = new cF4sdWebRequestInfo("KeepAliveCase", CaseId.ToString());
            if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
            var apiError = 0;

            try
            {
                LogEntry($"API Call KeepAliveSession: " + CaseId.ToString());
                if (!WebApiApplication.Collector.F4SDAnalyticsValid)
                {
                    return NotFound();
                }
                if (await WebApiApplication.Collector.KeepAliveCase(CaseId, requestInfo, 1, CancellationToken.None))
                    return Ok();
            }
            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 BadRequest();
        }

    }
}
