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.UserModels;

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

        /// <inheritdoc cref="IWardService" />
        public HwcPatientServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;


        /// <inheritdoc/>
        public async Task<int> InsertAsync(HwcPatientModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"Select count(*) from ""HWCPatient"" where ""LocationId"" = {model.LocationId} and lower(""HWCName"") = '{model.HWCName.ToLower()}'");
            if (checkIf > 0)
            {
                return -1;
            }
            var hoc = new HWCPatient
            {
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                Description = model.Description,
                HWCName = model.HWCName,
                LocationId = (int)model.LocationId,
                RowColor = model.RowColor
            };
            return await this.unitOfWork.HwcPatients.InsertAsync(hoc);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<HwcPatientModel>> FetchAllAsync(HwcPatientModel model)
        {
            var where = "where 1=1";
            if (model.LocationId != null)
            {
                where += $@" and HW.""LocationId"" = {model.LocationId}";
            }
            var query = $@"select count(HW.""HWCPatientId"") over() as ""TotalItems"", HW.""HWCPatientId"", HW.""HWCName"", HW.""Description"", HW.""LocationId"", HW.""Active"", HW.""CreatedBy"", HW.""CreatedDate"",
		                        HW.""ModifiedBy"", HW.""ModifiedDate"",HW.""RowColor"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""HWCPatient"" HW 
                             join ""Account"" C on C.""AccountId"" = HW.""CreatedBy""
                             join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = HW.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                                {where}
                             order by HW.""CreatedDate"" desc";
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageIndex;
                query += $@" limit {model.PageSize} offset {model.PageSize * model.PageIndex}";
            }

            return await this.unitOfWork.Current.QueryAsync<HwcPatientModel>(query);
        }

        /// <inheritdoc/>
        public async Task<int> UpdateAsync(HwcPatientModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"Select count(*) from ""HWCPatient"" where ""LocationId"" = {model.LocationId} and lower(""HWCName"") = '{model.HWCName.ToLower()}' and ""HWCPatientId"" <>{model.HWCPatientId}");
            if (checkIf > 0)
            {
                return -1;
            }

            var record = await this.unitOfWork.HwcPatients.FindAsync(p => p.HWCPatientId == model.HWCPatientId);
            if (record == null)
            {
                return 0;
            }
            record.Description = model.Description;
            record.HWCName = model.HWCName;
            record.ModifiedBy = model.CreatedBy;
            record.ModifiedDate = DateTime.Now;
            record.RowColor = model.RowColor;

            return await this.unitOfWork.HwcPatients.UpdateAsync(record);
        }

        /// <inheritdoc/>
        public async Task<int> DeleteAsync(HwcPatientModel model)
        {
            var query = $@"DELETE FROM ""HWCPatient"" WHERE ""HWCPatientId""= {model.HWCPatientId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }
    }
}