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 Shared.EntityModels;
    using Shared.UserModels.Filters;

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

        /// <inheritdoc cref="IRoleService" />
        public DischargeInstructionService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

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

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

            var query = $@"SELECT COUNT(*) OVER () AS ""TotalItems"",  DI.""DischargeInstructionId"",DI.""DischargeInstructionName"",DI.""Active"",DI.""CreatedDate"",DI.""ModifiedDate""
                         , C.""FullName"" ""CreatedByName"",CR.""RoleName"" ""CreatedByRole"",
		                             M.""FullName"" ""ModifiedByName"",MR.""RoleName"" ""ModifiedByRole""
                            FROM ""DischargeInstruction"" DI 
                            JOIN ""Account"" C on C.""AccountId"" = DI.""CreatedBy""
                            JOIN ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                            LEFT JOIN ""Account"" M on M.""AccountId"" = DI.""ModifiedBy"" 
                            LEFT JOIN ""Role"" MR on MR.""RoleId"" = M.""RoleId""  
                                    {where} Order by ""DischargeInstructionId"" DESC";

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

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

      

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

                var discharge = new DischargeInstruction
                {

                    Active = true,
                    DischargeInstructionName = model.DischargeInstructionName,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,

                };

                return await this.unitOfWork.DischargeInstructions.InsertAsync(discharge);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }

            return 0;
        }

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

            var discharge = await this.unitOfWork.DischargeInstructions.FindAsync(m => m.DischargeInstructionId == model.DischargeInstructionId);
            discharge.DischargeInstructionName = model.DischargeInstructionName;
            discharge.Active = true;
            discharge.ModifiedBy = model.ModifiedBy;
            discharge.ModifiedDate = DateTime.Now;
            return await this.unitOfWork.DischargeInstructions.UpdateAsync(discharge);
        }
     

        /// <inheritdoc />
        public Task<int> DeleteAsync(int dischargeInstructionId)
        {
            var query = $@"Update  ""DischargeInstruction"" set ""Active"" = false WHERE ""DischargeInstructionsId""= {dischargeInstructionId}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }

        /// <inheritdoc />
        public async Task<int> ModifyStatusAsync(DischargeModel model)
        {
            var query = $@"UPDATE ""DischargeInstruction""
	                           SET ""ModifiedBy""={model.CreatedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""DischargeInstructionId""= {model.DischargeInstructionId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }
    }
}