using Dapper;
using Hims.Domain.Entities;
using Hims.Domain.Repositories.UnitOfWork;
using Hims.Domain.Services;
using Hims.Shared.EntityModels;
using Hims.Shared.UserModels.Common;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Hims.Infrastructure.Services
{
    public class DietSlotsMastersServices : IDietSlotsMasterService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;


        /// <inheritdoc cref="IDietSlotsMasterService" />
        public DietSlotsMastersServices(IUnitOfWork unitOfWork
           )
        {
            this.unitOfWork = unitOfWork;
        }

        public async Task<int> InsertSlotsAsync(DietSlotsModel model)
        {
            var isExists = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"SELECT ""DietSlotId"" from ""DietSlots"" WHERE UPPER(TRIM(""Name"")) = UPPER(TRIM('{model.Name}'))");
            if (isExists > 0)
            {
                return -1;
            }
            var slot = new DietSlots
            {
                Name = model.Name,
                StartTime = TimeSpan.Parse(model.StartTime),
                EndTime = TimeSpan.Parse(model.EndTime),
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                LocationId = (int)model.LocationId
            };
            try
            {
                return await this.unitOfWork.DietSlots.InsertAsync(slot);
            }
            catch (Exception e)
            {
                e.Message.ToString();
            }
            return 0;


        }
        public Task<IEnumerable<DietSlotsModel>> FetchSlotsAsync(DietSlotsModel model)
        {
            var where = $@" where 1=1 ";
            if (model.Active == true)
            {
                where += $@" and ds.""Active"" = true";
            }
            var query = $@"select count(ds.""DietSlotId"") over() as ""TotalItems"", ds.""DietSlotId"", ds.""Name"", ds.""Active"", ds.""CreatedBy"", ds.""CreatedDate"",
		                        ds.""StartTime""::text,ds.""EndTime""::text,ds.""ModifiedBy"", ds.""ModifiedDate"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""DietSlots"" ds 
                             join ""Account"" C on C.""AccountId"" = ds.""CreatedBy""
                             join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = ds.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                              {where}
                             order by ds.""CreatedDate"" desc; ";

            return this.unitOfWork.Current.QueryAsync<DietSlotsModel>(query);

        }

        public async Task<int> UpdateAsync(DietSlotsModel model)
        {

            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""DietSlots"" where  lower (""Name"") = '{model.Name.ToLower()}' and ""DietSlotId"" <> {model.DietSlotId}");
            if (checkIf > 0)
            {
                return -1;
            }
            var record = await this.unitOfWork.DietSlots.FindAsync(m => m.DietSlotId == model.DietSlotId);
            if (record == null)
            {
                return -2;
            }
            record.ModifiedBy = model.CreatedBy;
            record.ModifiedDate = DateTime.Now;
            record.Name = model.Name;
            record.Active = model.Active;
            record.StartTime = TimeSpan.Parse(model.StartTime);
            record.EndTime = TimeSpan.Parse(model.EndTime);
            record.LocationId = (int)model.LocationId;
            return await this.unitOfWork.DietSlots.UpdateAsync(record);
        }
        public async Task<int> ModifyStatusAsync(DietSlotsModel model)
        {
            var query = $@"UPDATE ""DietSlots"" SET ""ModifiedBy""={model.CreatedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""DietSlotId""= {model.DietSlotId}";

            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

    }
}
