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

    using Hims.Shared.DataFilters;
    using Hims.Shared.UserModels.Filters;
    using Hims.Shared.UserModels.Pharmacy;
    using Hims.Shared.UserModels.PharmacyRequest;

    using Shared.EntityModels;
    using Shared.UserModels;
    //ReferenceTypesServices
    /// <inheritdoc />
    public class ReferenceTypesServices : IReferenceTypesServices
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;
        /// <summary>
        /// Initializes a new instance of the <see cref="PharmacyServices"/> class.
        /// </summary>
        /// <param name="unitOfWork">
        /// The unit of work.
        /// </param>
        public ReferenceTypesServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

              
        /// <inheritdoc/>
        public async Task<int> UpdateReference(ReferenceTypeModel model)
        {
            var res = await this.unitOfWork.ReferenceTypes.FindAsync(m => m.PatientReferredById == model.PatientReferredById);            
            res.Name = model.Name;
            res.ModifiedBy = model.CreatedBy;
            res.ModifiedDate = DateTime.Now;            

            return await this.unitOfWork.ReferenceTypes.UpdateAsync(res);
        }
      
        /// <inheritdoc/>
        public  Task<int> DeleteReferences(ReferenceTypeModel model)
        {
            var query = $@"DELETE FROM ""PatientReferredBy"" WHERE ""PatientReferredById""= {model.PatientReferredById}";
            return this.unitOfWork.Current.ExecuteAsync(query);           
            
        }   
        
        /// <inheritdoc/>
        public async Task<int> AddReference(ReferenceTypeModel model)
        {
            //var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""PatientReferredBy"" where ""PatientReferredById"" = {model.PatientReferredById} and lower(""name"") = '{model.Name.ToLower()}'");
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""PatientReferredBy"" where lower(""Name"") = '{model.Name.ToLower()}'");
            if (checkIf > 0)
            {
                return -1;
            }
            var module = new PatientReferredBy
            {
                Name = model.Name,
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now         

            };
           return await this.unitOfWork.ReferenceTypes.InsertAsync(module);
        }

        /// <inheritdoc/>
        public Task<IEnumerable<ReferenceTypeModel>> FetchReferences(ReferenceTypeModel model)
        {
           
            var where = "where 1=1";
            
            var query = $@"select count(PR.""PatientReferredById"") over() as ""TotalItems"", PR.""PatientReferredById"", PR.""Name"", PR.""Active"", PR.""CreatedBy"", PR.""CreatedDate"",
		                        PR.""ModifiedBy"", PR.""ModifiedDate"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""PatientReferredBy"" PR 
                             join ""Account"" C on C.""AccountId"" =PR.""CreatedBy""
                             join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = PR.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                                {where}
                             order by PR.""CreatedDate"" desc";            
            var result = this.unitOfWork.Current.QueryAsync<ReferenceTypeModel>(query);
            return result;
        }
    }
}

       
       
       

       
           
                         