namespace Hims.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    using Domain.Services;
    using Hims.Api.Models;
    using Hims.Domain.Entities;
    using Hims.Domain.Entities.Enums;
    using Hims.Shared.Library.Enums;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.UserModels;
    using Shared.UserModels.OperationTheater;
    using Shared.UserModels.PharmacyIndent;
    using Utilities;

    /// <summary>
    /// The indent controller.
    /// </summary>
    [Authorize]
    [Route("api/indent")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class IndentController : BaseController
    {
        /// <summary>
        /// The indent service.
        /// </summary>
        private readonly IIndentService indentService;

        /// <summary>
        /// The Inventory log services.
        /// </summary>
        private readonly IInventoryLogService inventoryLogServices;

        /// <summary>
        /// The general notification service.
        /// </summary>
        private readonly IGeneralNotificationService generalNotificationService;

        /// <summary>
        /// The web notification service
        /// </summary>
        private readonly IWebNotificationService webNotificationService;
        /// <inheritdoc />
        public IndentController(
            IIndentService indentService,
            IInventoryLogService inventoryLogServices,
            IGeneralNotificationService generalNotificationService,
            IWebNotificationService webNotificationService
            )
        {
            this.indentService = indentService;
            this.inventoryLogServices = inventoryLogServices;
            this.generalNotificationService = generalNotificationService;
            this.webNotificationService = webNotificationService;
        }


        /// <summary>
        /// The create indent request.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="location"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("add-request")]
        public async Task<ActionResult> CreateIndentRequest([FromBody] IndentRequestModel model, [FromHeader] LocationHeader location)
        {
            model = (IndentRequestModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(location.LocationId);
            var response = await this.indentService.CreateIndentRequestAsync(model);

            if (response > 0)
            {
                try
                {
                    var iLogs = new InventoryLogModel
                    {
                        AccountId = model.CreatedBy,
                        InventoryLogTypeId = (int)InventoryLogTypes.Indent,
                        LogFrom = (short)model.RoleId,
                        LogDate = DateTime.UtcNow.AddMinutes(330),
                        LogDescription = $@"<b>{model.CreatedByName}</b> has raised Indent for department: <b>{model.InventoryDepartmentName}</b> from <b>Inventory</b>."


                    };
                    await this.inventoryLogServices.LogAsync(iLogs);
                }
                catch (Exception e)
                {
                    //logs
                }
            }

            return response > 0 ? this.Success(response) : this.ServerError();
        }

        /// <summary>
        /// The fetch inventory indent request async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch")]
        public async Task<ActionResult> FetchInventoryIndentRequestAsync([FromBody] OTIndentModel model, [FromHeader] LocationHeader location)
        {
            model = (OTIndentModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(location.LocationId);
            var response = await this.indentService.FetchInventoryIndentAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches the inventory indent detail asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-detail")]
        public async Task<ActionResult> FetchInventoryIndentDetailAsync([FromBody] OTIndentModel model)
        {
            model = (OTIndentModel)EmptyFilter.Handler(model);
            if (model.IndentHeaderId == 0)
            {
                return this.BadRequest("Something wrong with supplied parameter.Please check..!!");
            }
            var response = await this.indentService.FetchInventoryIndentDetailAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// The delete indent request async.
        /// </summary>
        /// <param name="id">
        /// The id
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpGet]
        [Route("delete")]
        public async Task<ActionResult> DeleteIndentRequestAsync(int id)
        {
            var response = await this.indentService.DeleteIndentRequestAsync(id);
            return this.Success(response);
        }

        /// <summary>
        /// Adds the pharmacy department indent asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("add-pharmacy-department-indent")]
        public async Task<ActionResult> AddPharmacyDepartmentIndentAsync([FromBody] PharmacyDepartmentIndentHeaderModel model)
        {
            model = (PharmacyDepartmentIndentHeaderModel)EmptyFilter.Handler(model);
            var response = await this.indentService.AddPharmacyDepartmentIndentAsync(model);
            try
            {
                var roles = (await this.webNotificationService.GetAllRoles()).ToList();
                var getRolesToNotify = roles.Where(r => r.RoleName.ToLower().Contains("pharm"));
                var getAdmins = roles.Where(r => r.RoleName.ToLower().Contains("admin"));
                var finalRoleModel = new List<RoleModel>();
                finalRoleModel.AddRange(getRolesToNotify.ToList());
                finalRoleModel.AddRange(getAdmins.ToList());

                var notification = new GeneralNotificationModel
                {
                    CreatedBy = model.CreatedBy,
                    CreatedDate = model.CreatedDate,
                    IsPriority = true,
                    Message = " has created pharmacy indent",
                    ModulesMasterId = (int)ModulesMasterType.Pharmacy,
                    ReferenceId = response,
                    ForRoles = string.Join(",", finalRoleModel.Select(r => r.RoleId)),
                    WebNotificationLogTypeId = (int)WebNotificationLogType.View,
                    RedirectUrl = "app/dashboard"
                };
                await this.generalNotificationService.AddGeneralNotificationAsync(notification);
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// Fetches the pharmacy department asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-pharmacy-department-indent")]
        public async Task<ActionResult> FetchPharmacyDepartmentIndentAsync([FromBody] PharmacyDepartmentIndentHeaderModel model, [FromHeader] LocationHeader location)
        {
            model ??= new PharmacyDepartmentIndentHeaderModel() ;
            if (!string.IsNullOrEmpty(location.LocationId))
            {
                model.LocationId = Convert.ToInt32(location.LocationId);
            }
            var response = await this.indentService.FetchPharmacyDepartmentIndentAsync(model);
            return this.Success(response);
        }


        /// <summary>
        /// Fetches the pharmacy department indent detail asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-pharmacy-department-indent-detail")]
        public async Task<ActionResult> FetchPharmacyDepartmentIndentDetailAsync([FromBody] PharmacyDepartmentIndentDetailModel model)
        {
            model = (PharmacyDepartmentIndentDetailModel)EmptyFilter.Handler(model);
            var response = await this.indentService.FetchIndentDetailsAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Approves the pharmacy department indent asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("approve-pharmacy-department-indent")]
        public async Task<ActionResult> ApprovePharmacyDepartmentIndentAsync([FromBody] PharmacyDepartmentIndentHeaderModel model)
        {
            model = (PharmacyDepartmentIndentHeaderModel)EmptyFilter.Handler(model);
            var response = await this.indentService.ApprovePharmacyDepartmentIndentAsync(model);
            return this.Success(response);
        }

        
    }
}
