namespace Hims.Api.Controllers
{
    using DocumentFormat.OpenXml.Drawing;
    using Domain.Services;
    using Hims.Api.Models;
    using Hims.Domain.Entities;
    using Hims.Shared.Library.Enums;
    using Hims.Shared.UserModels.Pharmacy;
    using Hims.Shared.UserModels.Scan.ScanMachine;
    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/scan-machine")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class ScanMachineController : BaseController
    {
        /// <summary>
        /// The scan machine service.
        /// </summary>
        public readonly IScanMachineService scanMachineService;

        /// <summary>
        /// The scan service.
        /// </summary>
        private readonly IScanLogService scanLogService;
        /// <inheritdoc />
        public ScanMachineController(IScanMachineService scanMachineService, IScanLogService scanLogService)
        {
            this.scanMachineService = scanMachineService;
            this.scanLogService = scanLogService;
        }

        /// <summary>
        /// Modifies the ware house asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-scan-machine")]
        public async Task<ActionResult> ModifyMachineAsync([FromBody] ScanMachineInsertModel model, [FromHeader] LocationHeader header)
        {
            model = (ScanMachineInsertModel)EmptyFilter.Handler(model);
            //model.LocationId = int.Parse(header.LocationId);
            var response = model.ScanMachineMasterId == 0 ? await this.scanMachineService.AddAsync(model) : await this.scanMachineService.UpdateAsync(model);

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

            if (response > 0)
            {
                var scanLogModel = new ScanLogModel
                {
                    AccountId = model.CreatedBy,
                    ScanLogTypeId = (int)ScanLogTypes.ScanMachineMaster,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LocationId = Convert.ToInt32(header.LocationId),
                    LogDescription = $" {model.ModifiedByName} has {(model.ScanMachineMasterId == 0 ? "Added" : "Updated")} Scan Machine : <b>{model.MachineName}</b> Successfully.",
                };
                await this.scanLogService.LogAsync(scanLogModel);
            }
            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-scan-machine")]
        public async Task<ActionResult> FetchScanMachineAsync([FromBody] ScanMachineFetchModel model)
        {
            model ??= new ScanMachineFetchModel();
            //if(model.LocationId == null)
            //{
            //    model.LocationId = int.Parse(header.LocationId);
            //}
            var response = await this.scanMachineService.FetchAllScanMachineTests(model);
            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-import-machine")]
        public async Task<ActionResult> FetchImportMachineAsync([FromBody] ScanMachineFetchModel model, [FromHeader] LocationHeader header)
        {
            model ??= new ScanMachineFetchModel();
            model.LocationId = int.Parse(header.LocationId);
            var response = await this.scanMachineService.FetchImportMachineTests(model);
            return this.Success(response);
        }

        /// <summary>
        /// Modifies the ware house asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="header"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-import-machine")]
        public async Task<ActionResult> ModifyImportMachineAsync([FromBody] MachineImportModel model, [FromHeader] LocationHeader header)
        {
            model = (MachineImportModel)EmptyFilter.Handler(model);
            model.LocationId = int.Parse(header.LocationId);
            var response = await this.scanMachineService.ModifyImportAsync(model);

            if (response > 0)
            {
                var scanLogModel = new ScanLogModel
                {
                    AccountId = model.CreatedBy,
                    ScanLogTypeId = (int)ScanLogTypes.ScanMachineMaster,
                    LogFrom = (short)model.LoginRoleId,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LocationId = Convert.ToInt32(model.LocationId),
                    LogDescription = $" {model.ModifiedByName} has Added Scan Machine : <b>{model.MachineName}</b> Successfully.",
                };
                await this.scanLogService.LogAsync(scanLogModel);
            }
            return this.Success(response);
        }

        /// <summary>
        /// Modifies the ware house status asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-scan-machine-status")]
        public async Task<ActionResult> ModifyWareHouseStatusAsync([FromBody] ScanMachineFetchModel model, [FromHeader] LocationHeader header)
        {
            var modifiedLogDescription = "";
            model = (ScanMachineFetchModel)EmptyFilter.Handler(model);
            var response = await this.scanMachineService.ActivateOrDeactivateMachine(model);
            if (response > 0)
            {
                modifiedLogDescription = $" {model.ModifiedByName}</b> has {(model.Active == true ? "Activated" : "Deactivated")} Scan Machine : <b>{model.MachineName}</b> successfully.";
            }
            else if (response == -2)
            {
                modifiedLogDescription = $" {model.ModifiedByName}</b> has tried to Deactivate the Scan Machine : <b>{model.MachineName}</b> - This machine cannot be deativated as there are scan appointments booked for future days.";
            }
            var scanLogModel = new ScanLogModel
            {
                AccountId = model.CreatedBy,
                ScanLogTypeId = (int)ScanLogTypes.ScanMachineMaster,
                LogFrom = (short)model.LoginRoleId,
                LogDate = DateTime.UtcNow.AddMinutes(330),
                LocationId = Convert.ToInt32(header.LocationId),
                LogDescription = modifiedLogDescription,
            };
            await this.scanLogService.LogAsync(scanLogModel);

            return this.Success(response);
        }
    }
}

