using System;
using Hims.Domain.Configurations;
using Hims.Shared.UserModels.Common;
using Hims.Shared.UserModels.BedManagement;
using Hims.Shared.EntityModels;
using Hims.Shared.UserModels.Filters;
using Hims.Shared.DataFilters;

namespace Hims.Api.Controllers
{
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using System.Linq;
    using Domain.Services;
    using Hims.Api.Models;
    using Hims.Domain.Helpers;
    using Hims.Shared.UserModels;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;
    using Utilities;

    /// <inheritdoc />
    [Authorize]
    [Route("api/bed-management")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class BedManagementController : BaseController
    {
        /// The admission services.
        /// </summary>
        private readonly IBedBoardListViewService bedboardListViewServices;
        /// <summary>
        /// <summary>
        /// The service
        /// </summary>
        private readonly IBedManagementService service;

        /// <summary>
        /// The amazon s 3 configuration.
        /// </summary>
        private readonly IAmazonS3Configuration amazonS3Configuration;
        /// <summary>
        /// The AES helper.
        /// </summary>
        private readonly IAESHelper aesHelper;
        /// <inheritdoc />
        public BedManagementController(IBedBoardListViewService bedboardListViewServices, IBedManagementService service, IAmazonS3Configuration amazonS3Configuration, IAESHelper aesHelper)
        {
            this.service = service;
            this.amazonS3Configuration = amazonS3Configuration;
            this.bedboardListViewServices = bedboardListViewServices;
            this.aesHelper = aesHelper;
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-wards")]
        public async Task<ActionResult> FetchWardsAsync([FromHeader] LocationHeader header)
        {
            try
            {
                var response = await this.service.FetchWardsAsync(Convert.ToInt32(header.LocationId)).ConfigureAwait(false);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-rooms")]
        public async Task<ActionResult> FetchRoomsAsync([FromBody] FilterModel model)
        {
            try
            {
                var response = await this.service.FetchRoomsAsync(model.Id).ConfigureAwait(false);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-beds")]
        public async Task<ActionResult> FetchBedsAsync([FromBody] FilterModel model)
        {
            try
            {
                var response = await this.service.FetchBedsAsync(model.Id).ConfigureAwait(false);
                foreach (var record in response)
                {
                    if (record?.ThumbnailUrl != null)
                    {
                        record.ThumbnailUrl = this.amazonS3Configuration.BucketURL + record.Guid + "/" + record.ThumbnailUrl;
                        record.Guid = null;
                    }
                }

                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost] 
        [Route("fetch-beds-availability")]
        public async Task<ActionResult> FetchBedsAvailabilityAsync([FromBody]BedManagementFilterModel model, [FromHeader] LocationHeader header)
        
        {
            try
            {
                model.LocationId=Convert.ToInt32(header.LocationId); 
                var response = await this.service.FetchBedsAvailabilityAsync(model);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }
        /// <summary>
        /// The fetch Admissions.
        /// </summary>
        /// <param name="model">
        /// The admission filter model.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The list of Admissions.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - List of Admissions.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [Route("fetch-beds-listview")]
        [ProducesResponseType(typeof(List<AdmissionModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchbedsistviewAsync([FromBody] ListViewFilterModel model, [FromHeader] LocationHeader header)
        {
            model = (ListViewFilterModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(header.LocationId);

            var listview = await this.bedboardListViewServices.FetchAsync(model);
            foreach (var item in listview.ToList())
            {
                item.EncryptedAdmissionId = this.aesHelper.Encode(item.AdmissionId.ToString());
                item.EncryptedPatientId = this.aesHelper.Encode(item.PatientId.ToString());

                if (!string.IsNullOrEmpty(item.PatientThumbnailUrl))
                {
                    item.PatientThumbnailUrl = this.amazonS3Configuration.BucketURL + item.PatientThumbnailUrl;
                }

                if (!string.IsNullOrEmpty(item.ProviderThumbnailUrl))
                {
                    item.ProviderThumbnailUrl = this.amazonS3Configuration.BucketURL + item.ProviderThumbnailUrl;
                }
            }
            return this.Success(listview);
        }
        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost] 
        [Route("find-patient-bed-details")]
        public async Task<ActionResult> FindPatientDetailsByBedIdAsync([FromBody] BedManagementFilterModel model)

        {
            try
            {
                if(model.BedId == null)
                {
                    return this.Content("Please Select Bed");
                }
                var records = await this.service.FindPatientDetailsByBedIdAsync((int)model.BedId);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = records
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }
        /// <summary>
        /// Bed Status List.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet]
        [Route("bed-status-list")]
        public async Task<ActionResult> FetchbedStausItemsAsync([FromHeader] LocationHeader header)
        {
            try
            {
                int locationId = Convert.ToInt32(header.LocationId);
                var records = await this.service.FetchBedStatusItemsAsync(locationId);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = records
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }
        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet] 
        [Route("count-available-beds")]
        public async Task<ActionResult> FetchAvailableBedsCountAsync([FromHeader] LocationHeader header)
        {
            try
            {
                int locationId = Convert.ToInt32(header.LocationId);
                var records = await this.service.FetchAvailableBedsCountAsync(locationId);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = records
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet] 
        [Route("count-booked-beds")]
        public async Task<ActionResult> FetchBookedBedsCountAsync([FromHeader] LocationHeader header)
        {
            try
            {
                int locationId = Convert.ToInt32(header.LocationId);
                var records = await this.service.FetchBookedBedsCountAsync(locationId);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = records
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet] 
        [Route("count-cleaning-beds")]
        public async Task<ActionResult> FetchUnderCleaningBedsCountAsync([FromHeader] LocationHeader header)
        {
            try
            {
                int locationId = Convert.ToInt32(header.LocationId);
                var records = await this.service.FetchUnderCleaningBedsCountAsync(locationId);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = records
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpGet] 
        [Route("count-total-beds")]
        public async Task<ActionResult> FetchTotalBedsCountAsync([FromHeader] LocationHeader header)
        {
            try
            {
                int locationId = Convert.ToInt32(header.LocationId);
                var records = await this.service.FetchTotalBedsCountAsync(locationId);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = records
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }
    }
}