namespace Hims.Infrastructure.Services
{
    using System;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Shared.EntityModels;

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

        /// <inheritdoc cref="IProviderLeaveService" />
        public ProviderLeaveServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public Task<int> CheckAsync(string date, int providerId, int providerLocationId)
        {
            var query = $@"Select count(*) from ""ProviderLeave"" where ""LeaveDate"" = '{date}' and ""ProviderId"" = {providerId} and case when ""ProviderLocationId"" is null then 1=1 else ""ProviderLocationId"" = {providerLocationId} end";
            return this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>(query);
        }

        /// <inheritdoc />
        public async Task<int> AddAsync(ProviderLeaveModel model)
        {
            var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""ProviderLeaveId"") FROM ""ProviderLeave"" WHERE ""LeaveDate""::DATE = '{model.LeaveDate:yyyy-MM-dd}'::DATE AND  ""ProviderId"" = '{model.ProviderId}'");
            if (checkIf > 0)
            {
                return -1;
            }

            var providerLeave = new ProviderLeave
            {
                Active = true,
                ProviderId = model.ProviderId,
                LeaveDate = model.LeaveDate,
                ProviderLocationId = model.ProviderLocationId,
                Reason = model.Reason,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.UtcNow
            };

            return await this.unitOfWork.ProviderLeaves.InsertAsync(providerLeave);
        }

        /// <inheritdoc />
        public async Task<int> UpdateAsync(ProviderLeaveModel model)
        {
            var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""ProviderLeaveId"") FROM ""ProviderLeave"" WHERE ""LeaveDate""::DATE = '{model.LeaveDate:yyyy-MM-dd}'::DATE AND  ""ProviderId"" = '{model.ProviderId}' AND ""ProviderLeaveId"" <> {model.ProviderLeaveId}");
            if (checkIf > 0)
            {
                return -1;
            }

            var providerLeave = await this.unitOfWork.ProviderLeaves.FindAsync(m => m.ProviderLeaveId == model.ProviderLeaveId);
            providerLeave.ProviderId = model.ProviderId;
            providerLeave.LeaveDate = model.LeaveDate;
            providerLeave.ProviderLocationId = model.ProviderLocationId;
            providerLeave.Reason = model.Reason;
            providerLeave.ModifiedBy = model.ModifiedBy;
            providerLeave.ModifiedDate = DateTime.UtcNow;

            return await this.unitOfWork.ProviderLeaves.UpdateAsync(providerLeave);
        }

        /// <inheritdoc />
        public Task<int> DeleteAsync(int providerLeaveId)
        {
            var query = $@"DELETE FROM ""ProviderLeave"" WHERE ""ProviderLeaveId""= {providerLeaveId}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }
    }
}
