namespace Hims.Api.Controllers
{
    using System;
    using System.Threading.Tasks;

    using Domain.Services;
    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 Shared.UserModels;
    using Shared.UserModels.Inventory;
    using Shared.UserModels.OperationTheater;

    using Utilities;

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

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

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


        /// <inheritdoc />
        public IssueController
        (
           IIssueService issueService,
           IInventoryLogService inventoryLogServices,
           IPharmacyLogService pharmacyLogService
         )
        {
            this.issueService = issueService;
            this.inventoryLogServices = inventoryLogServices;
            this.pharmacyLogService = pharmacyLogService;
        }

        /// <summary>
        /// Approves the ot indents asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("approve-ot-indent")]
        public async Task<ActionResult> ApproveOTIndentsAsync([FromBody] OTIssueModel model)
        {
            model = (OTIssueModel)EmptyFilter.Handler(model);
            if (model.Products.Count == 0) { return this.BadRequest("Invalid parameters received."); }
            var response = await this.issueService.ApproveOTIndents(model);
            return this.Success(response);
        }

        /// <summary>
        /// Approves the pharmacy indents asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("approve-pharmacy-indent")]
        public async Task<ActionResult> ApprovePharmacyIndentsAsync([FromBody] OTIssueModel model)
        {
            model = (OTIssueModel)EmptyFilter.Handler(model);
            if (model.Products.Count == 0) { return this.BadRequest("Invalid parameters received."); }
            var response = await this.issueService.ApprovePharmacyIndents(model);

            if (response > 0)
            {
                try
                {
                    var iLogs = new PharmacyLogModel
                    {
                        AccountId = model.CreatedBy,
                        PharmacyLogTypeId = (int)PharmacyLogTypes.Pharmacy_Issue,
                        LogFrom = model.RoleId,
                        LogDate = DateTime.UtcNow.AddMinutes(330),
                        LogDescription = $@"{model.CreatedByName} has approved the <b>Pharmacy</b> Indent <br>"
                    };
                    await this.pharmacyLogService.LogAsync(iLogs);
                }
                catch (Exception)
                {
                    //logs
                }
            }

            return this.Success(response);
        }

        /// <summary>
        /// Approves the inventory indents asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("approve-inventory-indent")]
        public async Task<ActionResult> ApproveInventoryIndentsAsync([FromBody] OTIssueModel model)
        {
            model = (OTIssueModel)EmptyFilter.Handler(model);
            if (model.Products.Count == 0) { return this.BadRequest("Invalid parameters received."); }
            var response = await this.issueService.ApproveInventoryIndents(model);

            if (response > 0)
            {
                try
                {
                    var iLogs = new InventoryLogModel
                    {
                        AccountId = model.CreatedBy,
                        InventoryLogTypeId = (int)InventoryLogTypes.Issue,
                        LogFrom = model.RoleId,
                        LogDate = DateTime.UtcNow.AddMinutes(330),
                        LogDescription = $@"{model.CreatedByName} has approved the <b>Pharmacy</b> Indent <br>"
                    };
                    await this.inventoryLogServices.LogAsync(iLogs);
                }
                catch (Exception)
                {
                    //logs
                }
            }

            return this.Success(response);
        }

        /// <summary>
        /// Fetches the data for acknowledgment.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-acknowledgment-data")]
        public async Task<ActionResult> FetchDataForAcknowledgment([FromBody] PharmacyIssuedStockHeaderModel model)
        {
            model ??= new PharmacyIssuedStockHeaderModel();
            var response = await this.issueService.FetchDataForIssuedStockAcknowledgment(model);
            return this.Success(response);
        }

        /// <summary>
        /// Accepts for acknowledgment asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("accept-acknowledgment-data")]
        public async Task<ActionResult> AcceptForAcknowledgmentAsync([FromBody] PharmacyIssuedStockHeaderModel model)
        {
            model = (PharmacyIssuedStockHeaderModel)EmptyFilter.Handler(model);
            var response = await this.issueService.AcknowledeReceivedProductsAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches the inventory acknowledgment data asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-inventory-acknowledgment-data")]
        public async Task<ActionResult> FetchInventoryAcknowledgmentDataAsync([FromBody] InventoryIssuedStockHeaderModel model)
        {
            model ??= new InventoryIssuedStockHeaderModel();
            var response = await this.issueService.FetchDataForInventoryIssuedStockAcknowledgmentAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Accepts the inventory acknowledgment data asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("accept-inventory-acknowledgment-data")]
        public async Task<ActionResult> AcceptInventoryAcknowledgmentDataAsync([FromBody] InventoryIssuedStockHeaderModel model)
        {
            model = (InventoryIssuedStockHeaderModel)EmptyFilter.Handler(model);
            var response = await this.issueService.AcknowledeReceivedProductsInventoryAsync(model);
            return this.Success(response);
        }

        /// <summary>
        /// Adds the stocks to retail by GRN asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("move-stock-to-retail-store")]
        public async Task<ActionResult> AddStocksToRetailByGRNAsync([FromBody] PharmacyPurchaseBill model)
        {
            model = (PharmacyPurchaseBill)EmptyFilter.Handler(model);
            var response = await this.issueService.AddStocksToRetailViaPurchaseBillAsync(model);
            return response > 0 ? this.Success(response) : this.BadRequest("Unable to transfer record.Please transfer via Ident.");
        }
    }
}
