using Hims.Api.Models;
using Hims.Api.Utilities;
using Hims.Domain.Services;
using Hims.Shared.DataFilters;
using Hims.Shared.EntityModels;
using Hims.Shared.Library.Enums;
using Hims.Shared.UserModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hims.Api.Controllers
{
    /// <inheritdoc />
    [Authorize]
    [Route("api/sessiontype")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class SessionTypeController : BaseController
    {
        /// <summary>
        /// The coupon services.
        /// </summary>
        private readonly ISessionTypeService sessionTypeService;

        /// <summary>
        /// The audit log services.
        /// </summary>
        private readonly IAuditLogService auditLogServices;

        /// <inheritdoc />
        public SessionTypeController(ISessionTypeService sessionTypeService, IAuditLogService auditLogServices)
        {
            this.sessionTypeService = sessionTypeService;
            this.auditLogServices = auditLogServices;
        }

        /// <summary>
        /// Fetches the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch")]
        [ProducesResponseType(typeof(List<SessionTypeModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchAsync([FromBody] SessionTypeModel model)
        {
            model = (SessionTypeModel)EmptyFilter.Handler(model);
            //model.LocationId = Convert.ToInt32(header.LocationId);
            var result = await this.sessionTypeService.FetchAsync(model);
            return result == null ? this.ServerError() : this.Success(result);
        }

        /// <summary>
        /// Adds the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header">The header.</param>
        /// <returns></returns>
       // [HttpPost]
       // [Route("modify")]
       // [ProducesResponseType(typeof(string), 200)]
       // [ProducesResponseType(409)]
       // [ProducesResponseType(500)]
       // public async Task<ActionResult> AddAsync([FromBody] SessionTypeModel model, [FromHeader] LocationHeader header)
       //{
       //     model = (SessionTypeModel)EmptyFilter.Handler(model);
       //     var response = await this.sessionTypeService.ModifyAsync(model);
            
       //     //switch (response)
       //     //{

       //     //    case -1:
       //     //        return this.Conflict("Given SessionType has already been exists with us.");
       //     //    case 0:
       //     //        return this.ServerError();
       //     //}
       //     if (response>0)
       //     {
       //         var auditLogModel = new AuditLogModel
       //         {
       //             AccountId = model.CreatedBy,
       //             LogTypeId = (int)LogTypes.SessionType,
       //             LogFrom = (int)AccountType.Administrator,
       //             LogDate = DateTime.Now,
       //             LogDescription = $" { model.CreatedByName } has {(model.SessionTypeId > 0 ? "Updated" : "Added ")} SessionType - {model.Name} on { DateTime.Now }",
       //             LocationId = Convert.ToInt32(header.LocationId)
       //         };
       //         await this.auditLogServices.LogAsync(auditLogModel);
       //     }

       //     return this.Success(response);
       // }
        [HttpPost]
        [Route("add")]
        public async Task<ActionResult> InsertAsync([FromBody] SessionTypeModel model, [FromHeader] LocationHeader header)
        {
            model = (SessionTypeModel)EmptyFilter.Handler(model);
            var response = await this.sessionTypeService.InsertAsync(model);
            
                if (response > 0)
                {
                    var auditLog = new AuditLogModel
                    {
                        AccountId = model.CreatedBy,
                        LogTypeId = (int)LogTypes.SessionType,
                        LogDate = DateTime.Now,
                        LogFrom = (int)AccountType.Administrator,
                        LogDescription = $"{model.CreatedByName} has added <b>Session Type</b> of <strong>{model.Name}</strong> successfully.",
                        LocationId = Convert.ToInt32(header.LocationId)
                    };
                    await this.auditLogServices.LogAsync(auditLog);
                }
           
            return this.Success(response);
        }

        [HttpPost]
        [Route("update")]
        public async Task<ActionResult> UpdateAsync([FromBody] SessionTypeModel model, [FromHeader] LocationHeader header)
        {
            model = (SessionTypeModel)EmptyFilter.Handler(model);
            var response = await this.sessionTypeService.UpdateAsync(model);
            
   
                if (response > 0)
                {
                    var auditLog = new AuditLogModel
                    {
                        AccountId = model.CreatedBy,
                        LogTypeId = (int)LogTypes.SessionType,
                        LogDate = DateTime.Now,
                        LogFrom = (int)AccountType.Administrator,
                        LogDescription = $"<b>{model.CreatedByName}</b> has updated <b>SessionType</b> of <strong>{model.Name}</strong> successfully.",
                        LocationId = Convert.ToInt32(header.LocationId)
                    };
                    await this.auditLogServices.LogAsync(auditLog);
                }
            
         
            return this.Success(response);
        }


        /// <summary>
        /// Deletes the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header">The header.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("delete")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> DeleteAsync([FromBody] SessionTypeModel model, [FromHeader] LocationHeader header)
        {
            try
            {
                model = (SessionTypeModel)EmptyFilter.Handler(model);
                var response = await this.sessionTypeService.DeleteAsync(model);
                if (response == 0)
                {
                    return this.ServerError();
                }
                else if (response > 0)
                {
                    var auditLogModel = new AuditLogModel
                    {
                        AccountId = model.ModifiedBy,
                        LogTypeId = (int)LogTypes.SessionType,
                        LogFrom = (int)AccountType.Administrator,
                        LogDate = DateTime.UtcNow.AddMinutes(330),
                        LogDescription = $"<b> { model.ModifiedByName }</b> has Deleted SessionType - <b> {model.Name}</b> on { DateTime.Now }",
                        LocationId = Convert.ToInt32(header.LocationId)
                    };
                    await this.auditLogServices.LogAsync(auditLogModel);
                }
                

                return this.Success("Room has been deleted successfully.");
            }
            catch (NpgsqlException exception)
            {
                if (exception.Message.Contains("violates foreign key constraint"))
                {
                    return this.Conflict("SessionType can't be deleted. Please contact Administrator.");
                }

                return this.ServerError();
            }
        }

        /// <summary>
        /// Modifies the session type status asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header">The header.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-status")]
        public async Task<ActionResult> ModifySessionTypeStatusAsync([FromBody] SessionTypeModel model, [FromHeader] LocationHeader header)
        {
            model = (SessionTypeModel)EmptyFilter.Handler(model);
            var response = await this.sessionTypeService.ModifyStatusAsync(model);
            if (response > 0)
            {
                var auditLogModel = new AuditLogModel
                {
                    AccountId = model.ModifiedBy,
                    LogTypeId = (int)LogTypes.SessionType,
                    LogFrom = (int)AccountType.Administrator,
                    LogDate = DateTime.Now,
                    LogDescription = $@"<b>{model.ModifiedByName}</b> has  <b> {((bool)model.Active ? "Activated" : "Deactivated")}</b> the <b> {model.Name}</b>  successfully",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLogModel);
            }
            return this.Success(response);
        }

        /// <summary>
        /// Fetches all session types.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("fetch-session-types")]
        public async Task<ActionResult> FetchAllSessionTypes()
        {
            return this.Success(await this.sessionTypeService.FetchAllSessionTypes());
        }
    }
}
