namespace Hims.Infrastructure.Services
{
    using System;
    using System.Threading.Tasks;

    using Dapper;

    using Domain.Configurations;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Hims.Domain.Entities.Enums;
    using Shared.EntityModels;

    /// <inheritdoc />
    public class AppointmentLogServices : IAppointmentLogService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <summary>
        /// The amazon s 3 configuration.
        /// </summary>
        private readonly IAmazonS3Configuration amazonS3Configuration;

        /// <inheritdoc cref="IAppointmentLogService" />
        public AppointmentLogServices(IUnitOfWork unitOfWork, IAmazonS3Configuration amazonS3Configuration)
        {
            this.unitOfWork = unitOfWork;
            this.amazonS3Configuration = amazonS3Configuration;
        }

        /// <inheritdoc />
        public Task<AppointmentLogModel> FindAsync(int appointmentLogId)
        {
            var query = $@"SELECT log.*, pr.""FullName"" AS ""ProviderName"",
                                pat.""FirstName"" AS ""PatientFirstName"", pat.""LastName"" AS ""PatientLastName"", pat.""Email"" AS ""PatientEmail"", pat.""Mobile"" AS ""PatientMobile""
                                FROM ""AppointmentLog"" log
                                JOIN ""Patient"" pat ON pat.""PatientId"" = log.""PatientId"" AND pat.""Active"" IS TRUE
                                JOIN ""Provider"" pr ON pr.""ProviderId"" = log.""ProviderId"" AND pr.""Active"" IS TRUE
                                WHERE log.""AppointmentLogId""= {appointmentLogId}";
            return this.unitOfWork.Current.QueryFirstOrDefaultAsync<AppointmentLogModel>(query);
        }

        /// <inheritdoc />
        public async Task<int> AddAsync(AppointmentLogModel model)
        {
            try
            {
                var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""AppointmentLogId"") FROM ""AppointmentLog"" WHERE ""PatientId"" = '{model.PatientId}' AND ""ProviderId"" = '{model.ProviderId}' AND ""ProviderAvailabilityId"" = '{model.ProviderAvailabilityId}' AND ""AppointmentDate""::DATE = '{model.AppointmentDate:yyyy-MM-dd}'::DATE AND ""AppointmentTime"" = '{model.AppointmentTime}'");
                if (checkIf > 0)
                {
                    // return -1;
                    return await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT ""AppointmentLogId"" FROM ""AppointmentLog"" WHERE ""PatientId"" = '{model.PatientId}' AND ""ProviderId"" = '{model.ProviderId}' AND ""ProviderAvailabilityId"" = '{model.ProviderAvailabilityId}' AND ""AppointmentDate""::DATE = '{model.AppointmentDate:yyyy-MM-dd}'::DATE AND ""AppointmentTime"" = '{model.AppointmentTime}'");
                }

                var appointment = new AppointmentLog
                {
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    AppointmentDate = model.AppointmentDate,
                    AppointmentTime = model.AppointmentTime,
                    ProviderId = model.ProviderId,
                    PatientId = model.PatientId,
                    //ProviderLocationId = model.ProviderLocationId,
                    ProviderAvailabilityId = model.ProviderAvailabilityId,
                    Amount = model.Amount,
                    AppCharges = model.AppCharges,
                    Discount = model.Discount,
                    CouponId = model.CouponId == 0 ? null : model.CouponId,
                    Total = model.Total,
                    PatientType = model.PatientType,
                    VisitType = model.VisitType,
                    ChargeType = model.ChargeType,
                    AppointmentNotes = model.AppointmentNotes,
                    PatientFamilyId = model.PatientFamilyId == 0 ? null : model.PatientFamilyId,
                    Percentage = model.Percentage,
                    WalletAmount = model.WalletAmount,
                    DepartmentId = model.DepartmentId,
                    PaymentType = model.PaymentType,
                    LocationId = model.LocationId,
                    AppointmentTypeId = model.AppointmentTypeId,
                    VisitTypeId = model.VisitTypeId,
                    ChargeTypesId = model.ChargeTypesId,
                    PayTypeId = model.PayTypeId,
                    TokenNumber = model.TokenNumber,
                    SpecializationId=model.SpecializationId,
                    ReceiptTypeId=(int)ReceiptType.Cash,
                    ReceiptAreaTypeId=(int)ReceiptAreaType.Appointment,
                    ConsultationTypeId = model.ConsultationTypeId,
                    AppointmentEndTime = model.AppointmentEndTime,
                    PatientRegistrationCharges=model.PatientRegistrationCharges
                };

                return await this.unitOfWork.AppointmentLogs.InsertAsync(appointment);
            }
            catch (Exception e)
            {
                throw;
            }

        }

        /// <inheritdoc />
        public Task<int> DeleteAsync(int appointmentLogId)
        {
            var query = $@"DELETE FROM ""AppointmentLog"" WHERE ""AppointmentLogId""= {appointmentLogId}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }
    }
}