using Hims.Domain.Services;
using System;
using System.Collections.Generic;
using System.Text;
using Hims.Domain.Repositories.UnitOfWork;
using Hims.Shared.UserModels;
using System.Threading.Tasks;
using Dapper;
using Hims.Domain.Entities;
using Hims.Shared.UserModels.Slots;
using System.Transactions;
using System.Data.Common;

namespace Hims.Infrastructure.Services
{
    public class SessionTypeServices : ISessionTypeService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <summary>
        /// Initializes a new instance of the <see cref="SessionTypeServices"/> class.
        /// </summary>
        /// <param name="unitOfWork">The unit of work.</param>
        public SessionTypeServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        public Task<IEnumerable<SessionTypeModel>> FetchAsync(SessionTypeModel model)
        {
            var where = " WHERE 1 = 1 ";

            if (!string.IsNullOrEmpty(model.Name))
            {
                where += $@" and lower(st.""Name"") ilike '%{model.Name.ToLower()}%'";
            }

            if (model.Active != null)
            {
                where += (bool)model.Active ? $@" and st.""Active"" is true " : $@" and st.""Active"" is false ";
            }
            var query = $@"SELECT COUNT(*) OVER () AS ""TotalItems"",  st.""SessionTypeId"" , st.""Name"",
                                        CA.""FullName"" AS ""CreatedByName"" , MA.""FullName"" AS ""ModifiedByName"" , st.""CreatedDate"",st.""ModifiedDate"",st.""Active""
                                        FROM ""SessionType"" st
                                        Join ""Account"" CA ON CA.""AccountId"" = st.""CreatedBy""
                                        Left Join ""Account"" MA ON MA.""AccountId"" = st.""ModifiedBy""
                                        {where} Order by ""SessionTypeId"" 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 this.unitOfWork.Current.QueryAsync<SessionTypeModel>(query);
        }


        // public async Task<int> ModifyAsync(SessionTypeModel model)
        //{
        //  int response = 0;
        //var sessionType = new SessionType
        //{
        //  Active = true,
        // Name = model.Name,
        //CreatedBy = (int)model.CreatedBy,
        //CreatedDate = DateTime.Now,
        //};
        //    var checkIfQuery = $@"Select count(*) from ""SessionType"" where lower(""Name"") = '{model.Name.ToLower()}' ";
        //    var transaction = this.unitOfWork.BeginTransaction();
        //    if(model.SessionTypeId == 0)
        //    {
        //        var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
        //        if (checkIf > 0)
        //        {
        //            return -1;
        //        }
        //        sessionType.SessionTypeId = await this.unitOfWork.SessionTypes.InsertAsync(sessionType, transaction);
        //        if (sessionType.SessionTypeId == 0)
        //        {
        //            transaction.Rollback();
        //            return -1;
        //        }
        //        else
        //        {
        //            transaction.Commit();
        //            response = sessionType.SessionTypeId;
        //            return response;
        //        }
        //    }
        //    else
        //    {
        //        checkIfQuery += $@" and ""SessionTypeId"" <>{sessionType.SessionTypeId} ";
        //        var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
        //        if (checkIf > 0)
        //        {
        //            transaction.Rollback();
        //            return -1;
        //        }

        //        var findOldHeader = await this.unitOfWork.SessionTypes.FindAsync(h => h.SessionTypeId == model.SessionTypeId);
        //        if (findOldHeader == null)
        //        {
        //            transaction.Rollback();
        //            return -1;
        //        }
        //        findOldHeader.SessionTypeId = model.SessionTypeId;
        //        findOldHeader.Name = model.Name;
        //        findOldHeader.ModifiedBy = model.CreatedBy;
        //        findOldHeader.ModifiedDate = DateTime.Now;
        //        findOldHeader.Active = (bool)model.Active;

        //        var uresponse = await this.unitOfWork.SessionTypes.UpdateAsync(findOldHeader, transaction);
        //        if (uresponse == 0)
        //        {
        //            transaction.Rollback();
        //            return -1;
        //        }
        //        else
        //        {
        //            transaction.Commit();
        //            return uresponse;
        //        }
        //    }
        //}

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

        ///<inheritdoc/>
        public async Task<int> ModifyStatusAsync(SessionTypeModel model)
        {
            int num;
            try
            {

                var foundId = await this.unitOfWork.SessionTypes.FindAsync(m => m.SessionTypeId == model.SessionTypeId);
                foundId.Active = (bool)model.Active;
                foundId.ModifiedBy = model.ModifiedBy;
                foundId.ModifiedDate = DateTime.Now;
                num = await this.unitOfWork.SessionTypes.UpdateAsync(foundId);
                return num;
            }
            catch (Exception e)
            {
                e.Message.ToString();
            }

            return -1;
        }

        ///<inheritdoc/>
        public async Task<IEnumerable<SessionType>> FetchAllSessionTypes()
        {

            var query = $@"select * from ""SessionType"" where  ""Active"" = true";
            return await this.unitOfWork.Current.QueryAsync<SessionType>(query);
        }

        public async Task<int> InsertAsync(SessionTypeModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""SessionType"" where  lower(""Name"") = '{model.Name.ToLower()}'");
            var transaction = this.unitOfWork.BeginTransaction();
            if (checkIf > 0)
            {
                return -1;
            }
            
            var sessionType = new SessionType
            {
                Name = model.Name,
                CreatedBy = model.CreatedBy,
                Active = true,
                CreatedDate = DateTime.Now,
            };
          var response=  await this.unitOfWork.SessionTypes.InsertAsync(sessionType);
            if (response == 0)
            {
                transaction.Rollback();
                return -1;
            }
            else
            {
                transaction.Commit();
                return response;
            }
        }


        public async Task<int> UpdateAsync(SessionTypeModel model)
        {
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""SessionType"" where  lower (""Name"") = '{model.Name.ToLower()}' and ""SessionTypeId"" <> {model.SessionTypeId}");
                var transaction = this.unitOfWork.BeginTransaction();
                if (checkIf > 0)
                {

                    return -1;

                }
        var record = await this.unitOfWork.SessionTypes.FindAsync(m => m.SessionTypeId == model.SessionTypeId);
                if (record == null)
                {
                    transaction.Rollback();
                    return -2;
                }


                record.ModifiedBy = model.CreatedBy;
                record.ModifiedDate = DateTime.Now;
                record.Name = model.Name;
                var response = await this.unitOfWork.SessionTypes.UpdateAsync(record, transaction);

                if (response == 0)
                {
                    transaction.Rollback();
                    return -1;
                }
                else
                {
                    transaction.Commit();
                    return response;
                }

                return 1;
            }
        }
    }
}
