namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Hims.Domain.Configurations;
    using Hims.Shared.EntityModels;
    using Newtonsoft.Json.Linq;
    using Shared.UserModels.Filters;

    /// <inheritdoc />
    public class DietGuidLinesService : IDietGuidLinesService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;
        private readonly IRunningEnvironment runningEnvironment;
        /// <inheritdoc cref="IBedService" />
        public DietGuidLinesService(IUnitOfWork unitOfWork, IRunningEnvironment runningEnvironment)
        {
            this.unitOfWork = unitOfWork;
            this.runningEnvironment = runningEnvironment;
        }
        public async Task<DietGuidLinesModel> GetDietDocumentOnIdAsync(int id)
        {
            var query = $@"select * FROM ""DietGuidLines"" where ""DietGuidLinesId"" = {id}";
            return await this.unitOfWork.Current.QueryFirstOrDefaultAsync<DietGuidLinesModel>(query);
        }
        public async Task<IEnumerable<int>> AddAsync(IEnumerable<DietGuidLinesModel> model)
        {

            var Documents = model.Select(item => new DietGuidLines
            {
                Active = true,
                CreatedBy = item.CreatedBy,
                ContentType = item.ContentType,
                Size = item.Size,
                DietGuidLinesName = item.DietGuidLinesName,
                PdfLink = item.PdfLink,
                CreatedDate = DateTime.UtcNow,
                DocumentUrl = item.DocumentUrl,
                DietTypeId = item.DietTypeId
            });
            var responseIds = new List<int>();
            foreach (var file in Documents)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""DietGuidLines"" where  lower (""DietGuidLinesName"") = '{file.DietGuidLinesName.ToLower()}' and ""DietGuidLinesId"" <> {file.DietGuidLinesId}");
                if (checkIf > 0)
                {
                    responseIds.Count();
                    responseIds.Count();
                    if (responseIds.Count <= 0)
                    {
                        return Enumerable.Empty<int>();
                    }
                }
                var response = await this.unitOfWork.DietGuidLines.InsertAsync(file);
                responseIds.Add(response);
            }

            return responseIds;

        }

        public Task<int> DeleteAsync(DietGuidLinesModel model)
        {
            var query = $@"Delete from ""DietGuidLines"" where ""DietGuidLinesId"" =  {model.DietGuidLinesId}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }

        public async Task<IEnumerable<DietGuidLinesModel>> FetchAsync(DietGuidLinesModel model)
        {
            var where = $@"";
            if (model.DietGuidLinesId > 0)
            {
                where = $@"";
            }
            var query = $@"select COUNT(*) OVER () AS ""TotalItems"",dt.""Name"" as ""DietTypeName"",dgl.""Active"",(CASE WHEN dgl.""DocumentUrl"" IS NOT NULL THEN CONCAT('{this.runningEnvironment.CurrentEnvironment}', '/',dgl.""DietGuidLinesName"",'/', dgl.""DocumentUrl"") ELSE NULL END) as ""DocumentUrl"",dgl.""ContentType"",dgl.""Size"",dgl.""DietGuidLinesId"",dgl.""DietGuidLinesName"",act.""FullName"" as ""CreatedByName"",ac.""FullName"" as ""ModifiedByName"",dgl.""CreatedDate"",dgl.""ModifiedDate"" from ""DietGuidLines"" dgl
JOIN ""Account"" act ON act.""AccountId"" = dgl.""CreatedBy""
left join ""DietType"" dt on dt.""DietTypeId"" = dgl.""DietTypeId""
left join ""Account"" ac on ac.""AccountId""=dgl.""ModifiedBy""
{where}ORDER BY dgl.""DietGuidLinesId"" DESC ";
            if (model.PageIndex <= 0)
            {
                return await this.unitOfWork.Current.QueryAsync<DietGuidLinesModel>(query);
            }

            model.PageIndex -= 1;
            query += " LIMIT " + model.PageSize + " offset " + (model.PageIndex * model.PageSize);
            return await this.unitOfWork.Current.QueryAsync<DietGuidLinesModel>(query);
        }

        public async Task<int> ModifyStatusAsync(DietGuidLinesModel model)
        {
            var query = $@"UPDATE ""DietGuidLines""
	                           SET ""ModifiedBy""={model.ModifiedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""DietGuidLinesId""= {model.DietGuidLinesId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

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