using Hims.Api.Utilities;
using Hims.Domain.Helpers;
using Hims.Domain.Services;
using Hims.Shared.DataFilters;
using Hims.Shared.EntityModels;
using Hims.Shared.Library;
using Hims.Shared.Library.Enums;
using Hims.Shared.UserModels;
using Hims.Shared.UserModels.Filters;
using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hims.Api.Controllers
{
    /// <summary>
    /// The internal medicine controller.
    /// </summary>
    [Authorize]
    [Route("api/ivf-encounter")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class IvfEncounterController: BaseController
    {

        /// <summary>
        /// the provider service
        /// </summary>
        private readonly IEncounterService encounterServices;



        private readonly IIvfEncounterServices ivfEncounterServices;

        /// <summary>
        /// The appointments services.
        /// </summary>
        private readonly IAppointmentService appointmentsServices;
        /// <summary>
        /// the aes helper
        /// </summary>
        private readonly IAESHelper aesHelper;

        /// <inheritdoc />
        public IvfEncounterController(
            IIvfEncounterServices ivfEncounterServices,
            IAppointmentService appointmentsServices,
             IEncounterService encounterServices,
             IAESHelper aesHelper


            )
        {
            this.ivfEncounterServices = ivfEncounterServices;
            this.appointmentsServices = appointmentsServices;
            this.encounterServices = encounterServices;
            this.aesHelper = aesHelper; ;
        }



        /// <summary>
        /// The find ivf encounter.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("add")]
        [ProducesResponseType(typeof(int), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> ModifyAsync([FromBody] IvfEncounterModifyModel model)
        {
            model = (IvfEncounterModifyModel)EmptyFilter.Handler(model);
            var ivfEncounterId = model.IvfEncounterId == 0 ? await this.ivfEncounterServices.AddAsync(model) : await this.ivfEncounterServices.UpdateAsync(model);
            switch (ivfEncounterId.Response)
            {
                case 0:
                    return this.ServerError();
                default:
                    await this.appointmentsServices.UpdateEncounterTypeAsync(model.AppointmentId,
                       (int)EncounterTypes.IvfEncounter, model.IsAdmission);
                    return this.Success(ivfEncounterId.Response);

            }
        }


        /// <summary>
        /// To find ivf encounter dashboard
        /// </summary>
        /// <param name="model" >
        /// The encounter filter model.
        /// </param>
        /// <returns>
        /// The encounter model.
        /// </returns>
        [HttpPost]
        [Route("find-dashboard")]
        [ProducesResponseType(typeof(EncounterResource), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FindDashboardAsync([FromBody] IvfEncouterFilterModel model)
        {
            model = (IvfEncouterFilterModel)EmptyFilter.Handler(model);
            var appointmentId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedAppointmentId));
            var response = await this.ivfEncounterServices.FindDashboardAsync(appointmentId, model.Type, model.IsAdmission);
            if (response != null)
            {
                response.EncryptedAppointmentId = this.aesHelper.Encode(appointmentId.ToString());
            }
            return this.Success(response);
        }
        /// <summary>
        /// The find ivf encounter.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("find")]
        [ProducesResponseType(typeof(EncounterResource), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FindAsync([FromBody] IvfEncouterFilterModel model)
        {
            model = (IvfEncouterFilterModel)EmptyFilter.Handler(model);
            var appointmentId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedAppointmentId));
            var ivfEncounter = await this.ivfEncounterServices.FindAsync(appointmentId, model.IsAdmission);
            var providerId = !string.IsNullOrEmpty(model.EncryptedProviderId)
                ? Convert.ToInt32(this.aesHelper.Decode(model.EncryptedProviderId))
                : 0;
            var patientId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedPatientId));
            var appointmentList = new List<AppointmentModel>();
            var oldAppointment = new PreviousAppointmentModel();

            if (!model.IsAdmission)
            {
                var appointments = await this.appointmentsServices.FindByPatientAsync(patientId, providerId);
                appointmentList = appointments.ToList();

                foreach (var item in appointmentList)
                {
                    item.EncryptedAppointmentId = this.aesHelper.Encode(item.AppointmentId.ToString());
                    item.EncryptedPatientId = model.EncryptedPatientId;
                    item.AppointmentTimeString = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"))
                        .Add(item.AppointmentTime).ToString("hh:mm tt");
                }
            }

            return this.Success(new { Dashboard = ivfEncounter, Appointments = appointmentList, OldAppointment = oldAppointment });
        }

        /// <summary>
        /// The find full transcript async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("find-full-transcript")]
        [ProducesResponseType(typeof(IvfEncouterFilterModel), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FindFullTrasciptAsync([FromBody] IvfEncouterFilterModel model)
        {
            model = (IvfEncouterFilterModel)EmptyFilter.Handler(model);
            var appointmentId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedAppointmentId));
            var ivfencounterfulltranscript = await this.ivfEncounterServices.FindFullTranscriptAsync(appointmentId);
            if (ivfencounterfulltranscript == null || ivfencounterfulltranscript.IvfEncounterId == 0)
            {
                return this.BadRequest("Sorry! We don't have a encounter in the system.");
            }

            return this.Success(ivfencounterfulltranscript);
        }

    }
}
