using System.Buffers.Text;
using Hims.Shared.EntityModels;
using Hims.Api.Utilities;
using Microsoft.AspNetCore.Mvc;
using Hims.Domain.Services;
using Hims.Api.Models;
using Hims.Shared.DataFilters;
using Hims.Shared.Library.Enums;
using Hims.Shared.UserModels;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Hims.Domain.Repositories.UnitOfWork;
using Dapper;
using Hims.Domain.Entities;
using Hims.Domain.Helpers;

namespace Hims.Api.Controllers
{ 
    /// <summary>
   /// The Physiotherapy Encounter Controller
   /// </summary>
    [Route("api/physiotherapy-encounter")]
    public class PhysiotherapyEncounterController : BaseController
    {
        /// <summary>
        /// The Physiotherapy Encounter Service
        /// </summary>
        private readonly IPhysiotherapyEncounterService service;
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;
        /// <summary>
        /// the aes helper
        /// </summary>
        private readonly IAESHelper aesHelper;
        /// <summary>
        /// The encounters log service
        /// </summary>

        private readonly IEncountersLogService encountersLogService;

        /// <inheritdoc />
        public PhysiotherapyEncounterController(IPhysiotherapyEncounterService service , IUnitOfWork unitOfWork, IAESHelper aesHelper, IEncountersLogService encountersLogService)
        {
            this.service = service;
            this.unitOfWork = unitOfWork;
            this.aesHelper = aesHelper;
            this.encountersLogService = encountersLogService;
        }

        /// <summary>
        /// The Add Physiotherapy Encounter.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("add")]
        [ProducesResponseType(typeof(int), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> AddPhysiotherapyEncounter([FromBody] PhysiotherapyEncounterModel model , [FromHeader] LocationHeader location)
        {
            var appointmentId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedAppointmentId));
            model.AppointmentId = appointmentId;
            model = (PhysiotherapyEncounterModel)EmptyFilter.Handler(model);
            var response =  await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(*) FROM ""PhysiotherapyEncounter"" WHERE ""AppointmentId"" = {model.AppointmentId}");
            var data=response > 0? await service.UpdatePhysiotherapyEncounter(model): await service.AddPhysiotherapyEncounter(model);

           PatientModel patient = new PatientModel();
           patient = await this.encountersLogService.GetPatientDetails(appointmentId);
            var EncountersLog = new EncountersLogModel
            {
                AccountId = model.ModifiedBy,
                EncounterTypeId = 7,
                LogFrom = (short)model.LoginRoleId,
                LogDate = DateTime.UtcNow.AddMinutes(330),
                Section = Convert.ToString(model.Type),
                LogDescription = $"{model.CreatedByName}  {(response > 0 ? "Updated" : "Added")} the <b>Physiotherapy</b> encounter of section <b>{model.Type}</b> for {patient.FullName} [{patient.UMRNo}] on {DateTime.UtcNow.AddMinutes(330).ToString("dd/MM/yyyy, hh:mm tt")}",
                LocationId = Convert.ToInt32(location.LocationId)
            };

            await this.encountersLogService.LogAsync(EncountersLog);
            return Ok(data);
        }

        /// <summary>
        /// The Get All Physiotherapy Encounter.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("fetch")]
        [ProducesResponseType(typeof(IEnumerable<PhysiotherapyEncounterModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> GetAllPhysiotherapyEncounter([FromBody]  PhysiotherapyEncounterModel model)
        {
            var appointmentId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedAppointmentId));
            model.AppointmentId = appointmentId;
            model = (PhysiotherapyEncounterModel)EmptyFilter.Handler(model);
            var result = await service.GetAllPhysiotherapyEncounter(model);
            if(result == null)
            {
                result = new PhysiotherapyEncounterModel();
                result.AppointmentId = appointmentId;
            }
            return Ok(result);
        }

    }
}
