using Dapper;
using Hims.Domain.Entities;
using Hims.Domain.Repositories.UnitOfWork;
using Hims.Domain.Services;
using Hims.Shared.EntityModels;
using Hims.Shared.UserModels;
using Hims.Shared.UserModels.Filters;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Hims.Infrastructure.Services
{
    public class EncountersLogServices : IEncountersLogService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <summary>
        /// Initializes a new instance of the <see cref="EncountersLogServices"/> class.
        /// </summary>
        /// <param name="unitOfWork">
        /// The unit of work.
        /// </param>
        public EncountersLogServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public Task<IEnumerable<EncountersLogModel>> FetchAsync(EncountersLogModel model)
        {
            var where = $@" WHERE 1 = 1 ";

            if (model.EncounterTypeId != 0)
            {
                where += $@" AND log.""EncounterTypeId"" = '{model.EncounterTypeId}'";
            }
            if (model.AccountId != null)
            {
                where += $@" AND log.""AccountId"" = '{model.AccountId}'";
            }

            if (!string.IsNullOrEmpty(model.Section))
            {
                where += $@" AND log.""Section"" ILIKE '%{model.Section}%'";
            }

            if (!string.IsNullOrEmpty(model.FromDate) && !string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" AND (""LogDate"" at time zone 'UTC' at time zone 'Asia/Kolkata')::DATE >= '{model.FromDate}'::DATE";
                where += $@" AND (""LogDate"" at time zone 'UTC' at time zone 'Asia/Kolkata')::DATE <= '{model.ToDate}'::DATE";
            }

          

            var query = $@"SELECT COUNT(*) OVER() AS ""TotalItems"", log.*, acc.""FullName"", rl.""RoleName"",rl.""RoleId"" , ET.""EncounterName"" as EncounterTypeName FROM ""EncountersLog"" log
                        LEFT JOIN ""Account"" acc ON acc.""AccountId"" = log.""AccountId"" AND acc.""Active"" IS TRUE
                        LEFT JOIN ""Role"" rl ON rl.""RoleId"" = acc.""RoleId"" AND rl.""Active"" IS TRUE
                        LEFT JOIN ""EncounterType"" ET ON ET.""EncounterTypeId"" =  log.""EncounterTypeId""
                        {where} Order by log.""EncounterLogId"" DESC";

            if (model.PageIndex <= 0)
            {
                return this.unitOfWork.Current.QueryAsync<EncountersLogModel>(query);
            }

            model.PageIndex -= 1;
            query += " LIMIT " + model.PageSize + " offset " + (model.PageIndex * model.PageSize);
            return this.unitOfWork.Current.QueryAsync<EncountersLogModel>(query);
        }

        /// <inheritdoc />
        public Task LogAsync(EncountersLogModel model)
        {


            var encountersLog = new EncountersLog
            {
                LogDate = DateTime.UtcNow,
                AccountId = model.AccountId,
                LogFrom = model.LogFrom,
                EncounterTypeId = model.EncounterTypeId,
                LogDescription = model.LogDescription,
                LocationId = model.LocationId,
                Section=model.Section,

            };

            return this.unitOfWork.EncountersLogs.InsertAsync(encountersLog);
        }


       public async Task<PatientModel> GetPatientDetails(int appointmentId)
        {
            var Query = $@"select  * From ""Patient"" PT Join ""Appointment"" APT on APT.""PatientId"" = PT.""PatientId"" where APT.""AppointmentId"" = {appointmentId}";

            return await this.unitOfWork.Current.QueryFirstOrDefaultAsync<PatientModel>(Query);
        }

    }
}