using System.Collections.Generic;

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

    /// <inheritdoc />
    [Authorize]
    [Route("api/progress-report-vitals")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class ProgressReportVitalsController : BaseController
    {
        /// <summary>
        /// The progress report vitals services.
        /// </summary>
        private readonly IProgressReportVitalsService service;

        /// <summary>
        /// the provider service
        /// </summary>
        private readonly IPatientService patientServices;

        /// <summary>
        /// the audit service
        /// </summary>
        private readonly IAuditLogService auditLogServices;

        /// <summary>
        /// the provider service
        /// </summary>
        private readonly IProviderService providerServices;

        /// <inheritdoc />
        public ProgressReportVitalsController(IProgressReportVitalsService service, IAuditLogService auditLogService, IPatientService patientServices, IProviderService providerServices)
        {
            this.service = service;
            this.auditLogServices = auditLogService; 
            this.patientServices = patientServices;
            this.providerServices = providerServices;
        }

        /// <summary>
        /// Fetches the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch")]
        public async Task<ActionResult> FetchAsync([FromBody] FilterModel model)
        {
            try
            {
                var response = await this.service.FetchAsync(model);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception e)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = e.Message
                });
            }
        }

        /// <summary>
        /// Fetches the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("insert")]
        public async Task<ActionResult> InsertAsync([FromBody] InsertModel model, [FromHeader] LocationHeader header)
        {
            try
            {
                var patientFullName = await this.patientServices.FindPatientByAdmissionId(model.AdmissionId);
                var providerName = await this.providerServices.FindProviderByAdmissionId(model.AdmissionId);
                var response = await this.service.InsertAsync(model);
                
                var auditLogModel = new AuditLogModel
                {
                    AccountId = model.CreatedBy,
                    LogTypeId = (int)LogTypes.ProgressReport,
                    LogFrom = (int)AccountType.Administrator,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $" {model.ModifiedByName} has added Progress report Vitals for Patient {patientFullName} on {DateTime.UtcNow.AddMinutes(330)} Prescribed by Doctor {providerName}.",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLogModel);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            
            catch (Exception e)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = e.Message
                });
            }
        }

        /// <summary>
        /// Fetches the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("update")]
        public async Task<ActionResult> UpdateAsync([FromBody] UpdateModel model,[FromHeader] LocationHeader header)
        {
            try
            {
                var response = await this.service.UpdateAsync(model);
                var patientFullName = await this.patientServices.FindPatientByAdmissionId(model.AdmissionId);
                var providerName = await this.providerServices.FindProviderByAdmissionId(model.AdmissionId);
                var auditLogModel = new AuditLogModel
                {
                    AccountId = model.ModifiedBy,
                    LogTypeId = (int)LogTypes.ProgressReport,
                    LogFrom = (int)AccountType.Administrator,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $" {model.ModifiedByName} has Updated Progress report Vitals for Patient {patientFullName} on {DateTime.UtcNow.AddMinutes(330)} Prescribed by Doctor {providerName}.",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLogModel);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception e)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = e.Message
                });
            }
        }

        /// <summary>
        /// Fetches the asynchronous.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("delete")]
        public async Task<ActionResult> DeleteAsync([FromBody] DeleteModel model, [FromHeader] LocationHeader header)
        {
            try
            {
                var response = await this.service.DeleteAsync(model);
                var patientFullName = await this.patientServices.FindPatientByAdmissionId(model.AdmissionId);
                var providerName = await this.providerServices.FindProviderByAdmissionId(model.AdmissionId);
                var auditLogModel = new AuditLogModel
                {
                    AccountId = model.ModifiedBy,
                    LogTypeId = (int)LogTypes.ProgressReport,
                    LogFrom = (int)AccountType.Administrator,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $" {model.ModifiedByName} has Deleted Progress report Vitals for Patient {patientFullName} on {DateTime.UtcNow.AddMinutes(330)} Prescribed by Doctor {providerName}.",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLogModel);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception e)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = e.Message
                });
            }
        }

        /// <summary>
        /// Fetches the vital type asynchronous.
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-vital-type")]
        public async Task<ActionResult> FetchVisitTypesAsync()
        {
            try
            {
                var response = await this.service.FetchVitalTypeAsync().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>
        /// Fetches the unit type asynchronous.
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-unit-type")]
        public async Task<ActionResult> FetchUnitTypesAsync()
        {
            try
            {
                var response = await this.service.FetchUnitTypeAsync().ConfigureAwait(false);
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Success,
                    Data = response
                });
            }
            catch (Exception ex)
            {
                return Ok(new GenericResponse
                {
                    Status = GenericStatus.Error,
                    Message = ex.Message
                });
            }
        }

    }
}