namespace Hims.Api.Filters
{
    using System;
    using System.Net;
    using System.Collections.Generic;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Newtonsoft.Json;
    using Microsoft.AspNetCore.Http;
    using Hims.Domain.Services;
    using Hims.Domain.Configurations;
    using Hims.Api.Senders;
    using Hims.Shared.EntityModels;

    /// <inheritdoc />
    /// <summary>
    /// The exception filter.
    /// </summary>
    public class ExceptionFilter : IExceptionFilter
    {
        /// <summary>
        /// The exception log services.
        /// </summary>
        private readonly IExceptionLogService exceptionLogServices;

        /// <summary>
        /// The email sender.
        /// </summary>
        private readonly IEmailSender emailSender;

        /// <summary>
        /// The running environment.
        /// </summary>
        private readonly IRunningEnvironment runningEnvironment;

        /// <summary>
        /// The exception filter.
        /// </summary>
        /// <param name="exceptionLogServices">
        ///  The exception log services.
        /// </param>
        /// <param name="emailSender">
        ///  The email sender.
        /// </param>
        /// <param>
        /// <param name="runningEnvironment">
        ///  The running environment.
        /// </param>
        public ExceptionFilter(IExceptionLogService exceptionLogServices, IEmailSender emailSender, IRunningEnvironment runningEnvironment)
        {
            this.exceptionLogServices = exceptionLogServices;
            this.emailSender = emailSender;
            this.runningEnvironment = runningEnvironment;
        }

        /// <inheritdoc />
        public async void OnException(ExceptionContext context)
        {
            var logFrom = context.ActionDescriptor.DisplayName;
            var logRoute = context.ActionDescriptor.AttributeRouteInfo.Template;
            var errorMessage = context.Exception.InnerException != null ? context.Exception.InnerException.Message : context.Exception.Message;
            var errorDescription = JsonConvert.SerializeObject(context.Exception.StackTrace);
            this.exceptionLogServices.Invoke(logFrom, logRoute, errorMessage, errorDescription);
            const HttpStatusCode status = HttpStatusCode.InternalServerError;
            context.ExceptionHandled = true;
            var response = context.HttpContext.Response;
            response.StatusCode = (int)status;
            response.ContentType = "application/json";
            await response.WriteAsync(context.Exception.StackTrace);

            if (this.runningEnvironment.CurrentEnvironment != "Local")
            {
                var userList = new List<AccountModel> { };

                if (this.runningEnvironment.CurrentEnvironment == "Production")
                {
                    userList.Add(new AccountModel { Email = "puday@sujainfo.net", FullName = "Uday" });
                    userList.Add(new AccountModel { Email = "vikas@docassistant.net", FullName = "Vikas Kuchimanchi" });
                }
                else
                {
                    userList.Add(new AccountModel { Email = "kjaishree@sujainfo.net", FullName = "Jaishree" });
                    userList.Add(new AccountModel { Email = "psravani@sujainfo.net", FullName = "Sravani" });
                }

                var errorMessageWithEnvironment = $@" Exception occur in {this.runningEnvironment.CurrentEnvironment} : {Environment.NewLine} {errorMessage}";
                await this.emailSender.SendExceptionLogEmailToSupport(userList, logFrom, errorMessageWithEnvironment);
            }
        }
    }
}
