

namespace Hims.Infrastructure.Services
{
    using Dapper;
    using Hims.Domain.Repositories.UnitOfWork;
    using Hims.Domain.Services;
    using Hims.Shared.UserModels.InPatientsView;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    public class InPatientsViewServices : IInPatientsViewService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;
        /// <inheritdoc cref="IWorkingHourService" />
        public InPatientsViewServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        public async Task<IEnumerable<FetchBedsModel>> FetchBeds(PayloadBedsModel model)
        {
            var query = $@"SELECT
							r.""RoomName"",
							w.""WardName"",
							f.""FloorName""
						FROM
							""Room"" r 
							JOIN ""Ward"" w ON w.""WardId"" = r.""WardId""
							LEFT JOIN ""Floor"" f ON f.""FloorId"" = w.""FloorId""
                            WHERE f.""LocationId"" = {model.LocationId}";
            return await this.unitOfWork.Current.QueryAsync<FetchBedsModel>(query);
        }

        public async Task<IEnumerable<FetchModel>> FetchAsync(PayloadModel model)
        {
            var bedIds = new List<int>();
            if(model.IsNurse)
            {
                var subQuery = $@"select b.""BedId"" from ""NurseShiftMap"" n
                                    JOIN ""NurseShiftBedMap"" b on b.""NurseShiftMapId"" = n.""NurseShiftMapId""
                                    WHERE ('{new DateTime(DateTime.Now.Date.Year, DateTime.Now.Date.Month, DateTime.Now.Date.Day, 0, 0, 0):yyyy-MM-dd}'::DATE BETWEEN to_char(n.""FromDate"", 'YYYY-MM-DD' )::DATE AND to_char(n.""ToDate"", 'YYYY-MM-DD' )::DATE) 
                                    AND n.""NurseAccountId"" = {model.AccountId} ";
                bedIds = (await this.unitOfWork.Current.QueryAsync<int>(subQuery)).ToList();
            }

            var where = $@" AND 1 = 1";

            if(!string.IsNullOrEmpty(model.FloorName))
            {
                where += $@" AND f.""FloorName"" = '{model.FloorName}' ";
            }
            if (!string.IsNullOrEmpty(model.WardName))
            {
                where += $@" AND w.""WardName"" = '{model.WardName}' ";
            }
            if (!string.IsNullOrEmpty(model.RoomName))
            {
                where += $@" AND r.""RoomName"" = '{model.RoomName}' ";
            }

            if(model.IsNurse)
            {
                where += $@" AND b.""BedId"" IN ({(bedIds.Count > 0 ? string.Join(",", bedIds) : "-1")}) ";
            }

            if (model.LocationId > 0)
            {
                where += $@" AND a.""LocationId"" = {model.LocationId} ";
            }

            if (!string.IsNullOrEmpty(model.UMRNo))
            {
                where += $@" AND p.""UMRNo"" = '{model.UMRNo}' ";
            }
            var query = $@"select one.*, two.*, three.*, a.""AdmissionId"", a.""AdmissionDate"", p.""FullName"", p.""Age"", p .""Gender"",ob.""NurseAssessment"" 
                            ,b.""BedNumber"",r.""RoomName"",w.""WardName"",f.""FloorName"",a.""LocationId"" from ""Admission"" a
                            JOIN ""Patient"" p on p.""PatientId"" = a.""PatientId""
                            left join ""Discharge"" ds on (ds.""AdmissionId""=A.""AdmissionId"" and ds.""Active""=true)
                            LEFT JOIN ""Bed"" b on b.""BedId"" = a.""BedId""
                            LEFT JOIN ""Room"" r on r.""RoomId"" = b.""RoomId""
                            LEFT JOIN ""Ward"" w on w.""WardId"" = r.""WardId""
                            LEFT JOIN ""Floor"" f on f.""FloorId"" = w.""FloorId""
                            left join ""ObEncounter"" ob on ob.""AdmissionId""=a.""AdmissionId""
                            LEFT JOIN LATERAL (
	                            SELECT COUNT(M.""ProgressReportMedicationId"") OVER() AS ""MedicationsCount""
	                            FROM
		                            ""ProgressReportMedication"" M
		                            JOIN ""ProgressReport"" r on r.""ProgressReportId"" = M.""ProgressReportId""
		                            WHERE r.""AdmissionId"" = a.""AdmissionId"" LIMIT 1
                            ) one on true
                            LEFT JOIN LATERAL (
	                            SELECT COUNT(M.""ProgressReportNoteId"") OVER() AS ""NotesCount""
	                            FROM
		                            ""ProgressReportNote"" M
		                            JOIN ""ProgressReport"" r on r.""ProgressReportId"" = m.""ProgressReportId""
		                            WHERE r.""AdmissionId"" = a.""AdmissionId"" LIMIT 1
                            ) two on true
                            LEFT JOIN LATERAL (
	                            SELECT COUNT(M.""ProgressReportVitalsId"") OVER() AS ""VitalsCount""
	                            FROM
		                            ""ProgressReportVitals"" M
		                            JOIN ""ProgressReport"" r on r.""ProgressReportId"" = m.""ProgressReportId""
		                            WHERE r.""AdmissionId"" = a.""AdmissionId"" LIMIT 1
                            ) three on true
                            WHERE a.""Active"" IS TRUE 
                            AND ds.""DischargeId"" IS NULL
                            {where}";               
            return await this.unitOfWork.Current.QueryAsync<FetchModel>(query);
        }
    }
}
