namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Shared.EntityModels;

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

        /// <inheritdoc cref="IPatientEmergencyService" />
        public PatientEmergencyServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public Task<IEnumerable<PatientEmergencyModel>> FetchAsync(int patientId)
        {
            var where = $@" WHERE patemr.""Active"" IS TRUE AND patemr.""PatientId"" = {patientId}";
            var query = $@"SELECT patemr.* FROM ""PatientEmergency"" patemr {where} ORDER BY patemr.""PatientEmergencyId"" DESC";
            return this.unitOfWork.Current.QueryAsync<PatientEmergencyModel>(query);
        }

        /// <inheritdoc />
        public async Task<int> AddAsync(PatientEmergencyModel model)
        {
            var checkIf = await this.CheckEmergencyContactAsync(model.FullName, model.Relation, model.Mobile, model.PatientEmergencyId, model.PatientId);
            if (checkIf != 0)
            {
                return -1;
            }

            var patientEmergency = new PatientEmergency
            {
                FullName = model.FullName,
                Mobile = model.Mobile,
                PatientId = model.PatientId,
                Relation = model.Relation,
                Address = model.Address,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.UtcNow,
                Active = true
            };

            return await this.unitOfWork.PatientEmergencies.InsertAsync(patientEmergency);
        }

        /// <inheritdoc />
        public async Task<int> UpdateAsync(PatientEmergencyModel model)
        {
            var checkIf = await this.CheckEmergencyContactAsync(model.FullName, model.Relation, model.Mobile, model.PatientEmergencyId, model.PatientId);
            if (checkIf != 0)
            {
                return -1;
            }

            var patientEmergency = await this.unitOfWork.PatientEmergencies.FindAsync(m => m.PatientEmergencyId == model.PatientEmergencyId);
            patientEmergency.FullName = model.FullName;
            patientEmergency.Mobile = model.Mobile;
            patientEmergency.PatientId = model.PatientId;
            patientEmergency.Relation = model.Relation;
            patientEmergency.Address = model.Address;
            patientEmergency.ModifiedBy = model.ModifiedBy;
            patientEmergency.ModifiedDate = DateTime.UtcNow;

            return await this.unitOfWork.PatientEmergencies.UpdateAsync(patientEmergency);
        }

        /// <inheritdoc />
        public async Task<int> DeleteAsync(int patientEmergencyId)
        {
            var query = $@"DELETE FROM ""PatientEmergency"" WHERE ""PatientEmergencyId""= {patientEmergencyId} ";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        /// <summary>
        /// The check emergency contact if exists async.
        /// </summary>
        /// <param name="fullName">
        /// The full name.
        /// </param>
        /// <param name="relation">
        /// The relation.
        /// </param>
        /// <param name="mobile">
        /// The mobile.
        /// </param>
        /// <param name="patientEmergencyId">
        /// The patient emergency id.
        /// </param>
        /// <param name="patientId">
        /// The patient Id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        private Task<int> CheckEmergencyContactAsync(string fullName, string relation, string mobile, int patientEmergencyId, int patientId) => this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""PatientEmergencyId"") FROM ""PatientEmergency"" WHERE TRIM(LOWER(""FullName"")) = '{fullName.Trim().ToLower()}' AND TRIM(LOWER(""Relation"")) = '{relation.Trim().ToLower()}' AND TRIM(""Mobile"") = '{mobile.Trim()}' AND  ""PatientId"" = '{patientId}' AND  ""PatientEmergencyId"" <> '{patientEmergencyId}'");
    }
}