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 VisitTypeService : IVisitTypeService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <inheritdoc cref="IVisitTypeService" />
        public VisitTypeService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

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

            if (model.Active != null)
            {
                where += $@" AND ""Active"" IS {((bool)model.Active ? "TRUE" : "FALSE")}";
            }
            var query = $@"select count(VT.""VisitTypeId"") over() as ""TotalItems"", VT.""VisitTypeId"", VT.""VisitorName"", VT.""VisitTypeFor"", VT.""Active"", VT.""CreatedBy"", VT.""CreatedDate"",
		                        VT.""ModifiedBy"", VT.""ModifiedDate"", VT.""RowColor"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""VisitType"" VT
                             left join ""Account"" C on C.""AccountId"" = VT.""CreatedBy""
                             left join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = VT.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                                {where}
                             order by VT.""CreatedDate"" desc";

            

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

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

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

                var visitType = new VisitType
                {
                    Active = true,    
                    VisitorName = model.VisitorName,
                    VisitTypeFor = model.VisitTypeFor,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    RowColor=model.RowColor

                };

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

            return 0;
        }       

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

            var visitType = await this.unitOfWork.Visitors.FindAsync(m => m.VisitTypeId == model.VisitTypeId);
            visitType.VisitorName = model.VisitorName;
            visitType.VisitTypeFor = model.VisitTypeFor;
            visitType.Active = true;
            visitType.ModifiedBy = model.ModifiedBy;
            visitType.ModifiedDate = DateTime.Now;
            visitType.RowColor = model.RowColor;
            return await this.unitOfWork.Visitors.UpdateAsync(visitType);
        }

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

        public async Task<string> FindNameByVisitorId(int visitTypeId)
        {
            var query = $@"SELECT ""VisitorName"" FROM ""VisitType"" WHERE ""VisitTypeId"" = {visitTypeId}";
            var response = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);
            return response;
        }

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

    }
}