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;

    /// <inheritdoc />
    public class ModulesMasterService : IModulesMasterService
    {
        /// <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 ModulesMasterService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;


        /// <inheritdoc/>
        public async Task<int> UpdateModule(ModulesMasterModel model)
        {
            var res = await this.unitOfWork.ModulesMasters.FindAsync(m => m.ModulesMasterId == model.ModulesMasterId);


            res.ModuleName = model.ModuleName;
            res.ModuleIcon = model.ModuleIcon;
            res.ModifiedBy = model.ModifiedBy;
            res.ModifiedDate = DateTime.Now;
            res.ModuleDescription = model.ModuleDescription;
            res.ModulesMasterId = model.ModulesMasterId;
            res.PackageType = model.PackageType;
            res.IsChargeCategoryApplicable = (bool)model.IsChargeCategoryApplicable;
            res.IsDoctorChargeCategoryApplicable = (bool)model.IsDoctorChargeCategoryApplicable;
            res.IsPackageApplicable = (bool)model.IsPackageApplicable;
            return await this.unitOfWork.ModulesMasters.UpdateAsync(res);
        }

        /// <inheritdoc/>
        public Task<int> DeleteModule(ModulesMasterModel model)
        {
            var query = $@"DELETE FROM ""ModulesMaster"" WHERE ""ModulesMasterId""= {model.ModulesMasterId}";
            return this.unitOfWork.Current.ExecuteAsync(query);

        }

        /// <inheritdoc/>
        public async Task<int> AddModule(ModulesMasterModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"Select count(*) from ""ModulesMaster"" where  lower(""ModuleName"") = '{model.ModuleName.ToLower()}'");
            if (checkIf > 0)
            {
                return -1;
            }

            var module = new ModulesMaster
            {
                ModuleName = model.ModuleName,
                ModuleIcon = model.ModuleIcon,
                ModuleDescription = model.ModuleDescription,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                IsChargeCategoryApplicable = (bool)model.IsChargeCategoryApplicable,
                IsDoctorChargeCategoryApplicable = (bool)model.IsDoctorChargeCategoryApplicable,
                IsPackageApplicable = (bool)model.IsPackageApplicable,
                PackageType = model.PackageType
            };
            return await this.unitOfWork.ModulesMasters.InsertAsync(module);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<ModulesMasterModel>> FetchModules(ModulesMasterModel model)
        {
            try
            {
                var where = "where 1=1";
                if (!string.IsNullOrEmpty(model.ModuleName))
                {
                    where += $@" and F.""ModuleName"" = '{model.ModuleName}'";
                }
                if (model.IsChargeCategoryApplicable != null)
                {
                    where += (bool)model.IsChargeCategoryApplicable ? $@" and F.""IsChargeCategoryApplicable"" is true" : $@" and F.""IsChargeCategoryApplicable"" is false";
                }
                if (model.IsDoctorChargeCategoryApplicable != null)
                {
                    where += (bool)model.IsDoctorChargeCategoryApplicable ? $@" and F.""IsDoctorChargeCategoryApplicable"" is true" : $@" and F.""IsDoctorChargeCategoryApplicable"" is false";
                }
                var query = $@"SELECT F.""ModulesMasterId"", F.""ModuleName"",F.""ModuleDescription"",F.""ModuleIcon"",
                        CA.""FullName"" AS ""CreatedByName"" , MA.""FullName"" AS ""ModifiedByName"" ,
                        F.""CreatedDate"",F.""ModifiedDate"", F.""IsChargeCategoryApplicable"",F.""PackageType"",F.""IsDoctorChargeCategoryApplicable"",F.""IsPackageApplicable""
                        FROM ""ModulesMaster"" F
                        left Join ""Account"" CA ON CA.""AccountId"" = F.""CreatedBy""
                       Left Join ""Account"" MA ON MA.""AccountId"" = F.""ModifiedBy""
                         {where}  Order by ""ModulesMasterId"" DESC";


                return await this.unitOfWork.Current.QueryAsync<ModulesMasterModel>(query);
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
    }
}







