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 Hims.Shared.UserModels;

    /// <inheritdoc />
    public class SalutationService : ISalutationService
    {

        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <inheritdoc cref="IIdProofService" />
        public SalutationService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;
        public async Task<int> ActivateOrDeactivateTest(SalutationModel model)
        {
            var query = $@"UPDATE ""Salutation""
	                           SET ""ModifiedBy""={model.CreatedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""SalutationId""= {model.SalutationId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        public async Task<IEnumerable<SalutationModel>> FetchActiveAllAsync(SalutationModel model)
        {
            var where = "where 1=1";

            var query = $@"select count(s.""SalutationId"") over() as ""TotalItems"",s.""SalutationId"",s.""Name"",s.""Active"",ac.""FullName"" as ""CreatedByName"",cc.""FullName"" as ""ModifiedByName"",s.""CreatedDate"",s.""ModifiedDate"",s.""ModifiedBy"" from ""Salutation"" s
                                left join ""Account"" ac on ac.""AccountId"" = s.""CreatedBy""
                                left join ""Account"" cc on cc.""AccountId"" =s.""ModifiedBy""
                                {where} AND s.""Active"" = true
                             order by s.""CreatedDate"" desc";

            return await this.unitOfWork.Current.QueryAsync<SalutationModel>(query);
        }

        public async Task<IEnumerable<SalutationModel>> FetchAllAsync(SalutationModel model)
        {
            var where = "where 1=1";

            var query = $@"select count(s.""SalutationId"") over() as ""TotalItems"",s.""SalutationId"",s.""Name"",s.""Active"",ac.""FullName"" as ""CreatedByName"",cc.""FullName"" as ""ModifiedByName"",s.""CreatedDate"",s.""ModifiedDate"",s.""ModifiedBy"" from ""Salutation"" s
                                left join ""Account"" ac on ac.""AccountId"" = s.""CreatedBy""
                                left join ""Account"" cc on cc.""AccountId"" =s.""ModifiedBy""
                                {where}
                             order by s.""CreatedDate"" desc";

            return await this.unitOfWork.Current.QueryAsync<SalutationModel>(query);
        }

        public async Task<int> InsertAsync(SalutationModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""Salutation"" where  lower(""Name"") = '{model.Name.ToLower()}'");
            if (checkIf > 0)
            {
                return -1;
            }
            var salutation = new Salutation
            {
                Name = model.Name,
                CreatedBy = model.CreatedBy,
                Active = true,
                CreatedDate = DateTime.Now,
            };
            return await this.unitOfWork.Salutations.InsertAsync(salutation);
        }

        public async Task<int> UpdateAsync(SalutationModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""Salutation"" where  lower (""Name"") = '{model.Name.ToLower()}' and ""SalutationId"" <> {model.SalutationId}");
            if (checkIf > 0)
            {
                return -1;
            }
            var record = await this.unitOfWork.Salutations.FindAsync(m => m.SalutationId == model.SalutationId);
            if (record == null)
            {
                return -2;
            }
            record.ModifiedBy = model.CreatedBy;
            record.ModifiedDate = DateTime.Now;
            record.Name = model.Name;
            return await this.unitOfWork.Salutations.UpdateAsync(record);
        }
    }
}