namespace Hims.Api.Controllers
{
    using Domain.Services;
    using Hims.Api.Models;
    using Hims.Shared.Library.Enums;
    using Hims.Shared.UserModels.Pharmacy;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Shared.DataFilters;
    using Shared.EntityModels;
    using System;
    using System.Threading.Tasks;
    using Utilities;

    /// <summary>
    /// The pharmacy ware house controller.
    /// </summary>
    [Authorize]
    [Route("api/pharmacy-ware-house")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class PharmacyWareHouseController : BaseController
    {
        /// <summary>
        /// The pharmacy ware house service
        /// </summary>
        private readonly IPharmacyWareHouseService pharmacyWareHouseService;

        /// <summary>
        /// The pharmacy service.
        /// </summary>
        private readonly IPharmacyLogService pharmacyLogService;

        /// <inheritdoc />
        public PharmacyWareHouseController(IPharmacyWareHouseService pharmacyWareHouseService, IPharmacyLogService pharmacyLogService)
        {
            this.pharmacyWareHouseService = pharmacyWareHouseService;
            this.pharmacyLogService = pharmacyLogService;
        }

        /// <summary>
        /// Modifies the ware house asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-ware-house")]
        public async Task<ActionResult> ModifyWareHouseAsync([FromBody] PharmacyWareHouseModel model, [FromHeader] LocationHeader header)
        {
            model = (PharmacyWareHouseModel)EmptyFilter.Handler(model);
            var response = model.PharmacyWareHouseId == 0 ? await this.pharmacyWareHouseService.InsertPharmacyWareHouse(model) : await this.pharmacyWareHouseService.UpdatePharmacyWareHouse(model);

            if (response == -2) { return this.BadRequest("The warehouse name already exists."); }

            try
            {
                var pharmacyLogModel = new PharmacyLogModel
                {
                    AccountId = model.CreatedBy,
                    PharmacyLogTypeId = (int)PharmacyLogTypes.Ware_House,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.Now,
                    LogDescription = $@"<b>{model.CreatedByName}</b> has {(model.PharmacyWareHouseId > 0 ? "updated" : "created")} the <b>{model.WareHouseName}</b>  successfully",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.pharmacyLogService.LogAsync(pharmacyLogModel);
            }
            catch (Exception)
            {
                // ignore
            }


            return this.Success(response);
        }

        /// <summary>
        /// Fetches all warehouses asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-ware-house")]
        public async Task<ActionResult> FetchAllWarehousesAsync([FromBody] PharmacyWareHouseModel model, [FromHeader] LocationHeader header)
        {
            model ??= new PharmacyWareHouseModel();
            model.LocationId = int.Parse(header.LocationId);
            var response = await this.pharmacyWareHouseService.FetchAllWarehousesAsync(model);
            return this.Success(response);
        }

        /// <summary>Fetches all warehouses with retail store counts asynchronous.</summary>
        /// <param name="model">The model.</param>
        /// <param name="header">The header.</param>
        /// <returns>
        ///   <br />
        /// </returns>
        [HttpPost]
        [Route("fetch-ware-house-with-retail-count")]
        public async Task<ActionResult> FetchAllWarehousesWithRetailStoreCountsAsync([FromBody] PharmacyWareHouseModel model, [FromHeader] LocationHeader header)
        {
            model ??= new PharmacyWareHouseModel();
            if (!model.NoLocation)
            {
                model.LocationId = int.Parse(header.LocationId);
            }
            var response = await this.pharmacyWareHouseService.FetchAllWarehousesWithRetailCountsAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Modifies the ware house status asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-warehouse-status")]
        public async Task<ActionResult> ModifyWareHouseStatusAsync([FromBody] PharmacyWareHouseModel model)
        {
            model = (PharmacyWareHouseModel)EmptyFilter.Handler(model);
            var response = await this.pharmacyWareHouseService.ActivateOrDeactivateWareHouse(model);

            try
            {
                var pharmacyLogModel = new PharmacyLogModel
                {
                    AccountId = model.CreatedBy,
                    PharmacyLogTypeId = (int)PharmacyLogTypes.Ware_House,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.Now,
                    LogDescription = $@"<b>{model.CreatedByName}</b> has {((bool)model.Active ? "Activated" : "Deactivated")} the {model.WareHouseName}  successfully"
                };
                await this.pharmacyLogService.LogAsync(pharmacyLogModel);
            }
            catch (Exception)
            {
                // ignore
            }

            return this.Success(response);
        }

        /// <summary>
        /// Fetches all ware houses with location without central asynchronous.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("get-only-warehouses")]
        public async Task<ActionResult> FetchAllWareHousesWithLocationWithoutCentralAsync()
        {
            var response = await this.pharmacyWareHouseService.GetOnlyWareHousesWithLocationAsync(string.Empty);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches all ware houses with location asynchronous.
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("get-all-warehouses")]
        public async Task<ActionResult> FetchAllWareHousesWithLocationAsync()
        {
            var response = await this.pharmacyWareHouseService.GetAllWareHousesWithLocationAsync();
            return this.Success(response);
        }

        /// <summary>
        /// Modifies the pharmacy product type asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-pharmacy-product-type")]
        public async Task<ActionResult> ModifyPharmacyProductTypeAsync([FromBody] PharmacyProductTypeModel model, [FromHeader] LocationHeader header)
        {
            model = (PharmacyProductTypeModel)EmptyFilter.Handler(model);
            var response = await this.pharmacyWareHouseService.ModifyPharmacyProductTypeAsync(model);
            if(response > 0)
            {
                var pharmacyLogModel = new PharmacyLogModel
                {
                    AccountId = model.LoginAccountId,
                    PharmacyLogTypeId = (int)PharmacyLogTypes.Product_Type,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $@"<b>{model.ModifiedByName}</b> {(model.PharmacyProductTypeId > 0 ? "updated" : "added")} the Product Type - <b>{model.TypeName}</b> on {DateTime.UtcNow.AddMinutes(330).ToString("MM/dd/yyyy, hh:mm tt")} successfully",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.pharmacyLogService.LogAsync(pharmacyLogModel);
               
            }
             return this.Success(response);
        }

        /// <summary>
        /// Fetches the pharmacy product type asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-pharmacy-product-type")]
        public async Task<ActionResult> FetchPharmacyProductTypeAsync([FromBody] PharmacyProductTypeModel model)
        {
            model ??= new PharmacyProductTypeModel();
            var response = await this.pharmacyWareHouseService.FetchPharmacyProductTypeAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Modifies the pharmacy product sub type asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-pharmacy-product-sub-type")]
        public async Task<ActionResult> ModifyPharmacyProductSubTypeAsync([FromBody] PharmacyProductSubTypeModel model, [FromHeader] LocationHeader header)
        {
            model = (PharmacyProductSubTypeModel)EmptyFilter.Handler(model);
            var response = await this.pharmacyWareHouseService.ModifyPharmacyProductSubTypeAsync(model);
            if(response> 0)
            {
                var pharmacyLogModel = new PharmacyLogModel
                {
                    AccountId = model.LoginAccountId,
                    PharmacyLogTypeId = (int)PharmacyLogTypes.Product_Sub_Type,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $@"<b>{model.ModifiedByName}</b> {(model.PharmacyProductSubTypeId > 0 ? "updated" : "added")} the ProductSubType - <b>{model.TypeName}</b> on {DateTime.UtcNow.AddMinutes(330).ToString("MM/dd/yyyy, hh:mm tt")} successfully",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.pharmacyLogService.LogAsync(pharmacyLogModel);
            }
           return this.Success(response);
        }

        /// <summary>
        /// Fetches the pharmacy product sub type asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-pharmacy-product-sub-type")]
        public async Task<ActionResult> FetchPharmacyProductSubTypeAsync([FromBody] PharmacyProductSubTypeModel model)
        {
            model ??= new PharmacyProductSubTypeModel();
            var response = await this.pharmacyWareHouseService.FetchPharmacyProductSubTypeAsync(model);
            return this.Success(response);
        }
    }
}

