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.Library;
    using Shared.EntityModels;
    using Shared.UserModels.VitalType;
    using Resource = Hims.Shared.UserModels.UnitType;

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

        /// <inheritdoc cref="IVitalTypeService" />
        public VitalTypeService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public Task<IEnumerable<ViewModel>> FetchAsync(FilterModel model)
        {
            var where = " WHERE 1 = 1 ";
            if (!string.IsNullOrEmpty(model.Name))
            {
                where += $@" AND TRIM(UPPER(""Name"")) = '{model.Name.Trim().ToUpper()}'";
            }

            //if (model.Active != null)
            //{
            //    where += $@" AND ""Active"" IS {((bool)model.Active ? "TRUE" : "FALSE")}";
            //}

            var query = $@"SELECT COUNT(*) OVER () AS ""TotalItems"", * FROM ""VitalType"" {where} Order by ""VitalTypeId"" DESC";

            if (model.PageIndex <= 0)
            {
                return this.unitOfWork.Current.QueryAsync<ViewModel>(query);
            }

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

        /// <inheritdoc />
        public async Task<int> AddAsync(InsertModel model)
        {
            var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""VitalTypeId"") FROM ""VitalType"" WHERE TRIM(UPPER(""Name"")) = '{model.Name.ToUpper().Trim()}'");
            if (checkIf > 0)
            {
                return -1;
            }

            var vitalType = new VitalType
            {

                Name = model.Name,
                UnitType = model.UnitType,
                Min = model.Min,
                Max = model.Max,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,

            };

            return await this.unitOfWork.VitalType.InsertAsync(vitalType);
        }

        /// <inheritdoc />
        public async Task<int> UpdateAsync(UpdateModel model)
        {
            var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""VitalTypeId"") FROM ""VitalType"" WHERE TRIM(UPPER(""Name"")) = '{model.Name.ToUpper().Trim()}' AND ""VitalTypeId"" <> {model.VitalTypeId}");
            if (checkIf > 0)
            {
                return -1;
            }

            var vitalType = await this.unitOfWork.VitalType.FindAsync(m => m.VitalTypeId == model.VitalTypeId);
            vitalType.Name = model.Name;
            vitalType.UnitType = model.UnitType;
            vitalType.Min = model.Min;
            vitalType.Max = model.Max;
            vitalType.ModifiedBy = model.ModifiedBy;
            vitalType.ModifiedDate = DateTime.Now;
            return await this.unitOfWork.VitalType.UpdateAsync(vitalType);
        }

        /// <inheritdoc />
        public async Task<int> DeleteAsync(DeleteModel id)
        {
            var response = await this.unitOfWork.VitalType.DeleteAsync(x => x.VitalTypeId == id.VitalTypeId);
            return response ? 1 : -1;
        }

        public async Task<string> FindNameByVitalTypeId(int id)
        {
            var query = $@"SELECT ""Name"" FROM ""VitalType"" WHERE ""VitalTypeId"" = {id}";
            var response = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);
            return response;
        }

        public async Task<IEnumerable<Resource.ViewModel>> FetchUnitTypeAsync()
        {
            var query = $@"SELECT
	                        ""UnitTypeId"" AS ""Id"",
	                        ""Name"" AS ""Name"" 
                        FROM
	                        ""UnitType"" ";
            var records = await this.unitOfWork.Current.QueryAsync<Resource.ViewModel>(query);
            return records;
        }

    }
}