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

        /// <inheritdoc cref="IIdProofService" />
        public IdProofService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        public async Task<int> ActivateOrDeactivateTest(IdProofModel model)
        {
            var query = $@"UPDATE ""IdProof""
	                           SET ""ModifiedBy""={model.CreatedBy}, ""ModifiedDate""=now(), ""Active""= {model.Active}
	                           WHERE ""IdProofId""= {model.IdProofId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }

        /// <inheritdoc/>
        public async Task<int> DeleteAsync(IdProofModel model)
        {
            throw new NotImplementedException();
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<IdProofModel>> FetchAllAsync(IdProofModel model)
        {
            var where = "where 1=1";
            if (model.IdProofId > 0)
            {
                where += $@" and  ID.""IdProofId"" = {model.IdProofId} ";
            }

            if (model.Active != null)
            {
                where += $@" AND ID.""Active"" IS {((bool)model.Active ? "TRUE" : "FALSE")}";
            }
            var query = $@"select count(ID.""IdProofId"") over() as ""TotalItems"", ID.""IdProofId"", ID.""IdProofName"", ID.""Active"", ID.""CreatedBy"", ID.""CreatedDate"",
		                        ID.""ModifiedBy"", ID.""ModifiedDate"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""IdProof"" ID 
                             join ""Account"" C on C.""AccountId"" = ID.""CreatedBy""
                             join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = ID.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                                {where}
                             order by ID.""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<IdProofModel>(query);

        }

        public async Task<IEnumerable<IdProofModel>> FetchActiveAllAsync(IdProofModel model)
        {
            var where = "where 1=1";
            
            var query = $@"select count(ID.""IdProofId"") over() as ""TotalItems"", ID.""IdProofId"", ID.""IdProofName"",  ID.""Active"", ID.""CreatedBy"", ID.""CreatedDate"",
		                        ID.""ModifiedBy"", ID.""ModifiedDate"",
		                        C.""FullName"" as ""CreatedByName"", CR.""RoleName"" as ""CreatedByRole"",M.""FullName"" as ""ModifiedByName"", MR.""RoleName"" as ""ModifiedByRole""
                             FROM ""IdProof"" ID 
                             join ""Account"" C on C.""AccountId"" = ID.""CreatedBy""
                             join ""Role"" CR on CR.""RoleId"" = C.""RoleId""
                             left join ""Account"" M on M.""AccountId"" = ID.""ModifiedBy""
                             left join ""Role"" MR on MR.""RoleId"" = M.""RoleId""
                                {where} AND ID.""Active"" = true
                             order by ID.""CreatedDate"" desc";


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

        }

        /// <inheritdoc/>
        public async Task<int> InsertAsync(IdProofModel model)
        {
            var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""IdProof"" where  lower(""IdProofName"") = '{model.IdProofName.ToLower()}'");
            if (checkIf > 0)
            {
                return -1;
            }
            var idproof = new IdProof
            {
                IdProofName = model.IdProofName,
                CreatedBy = model.CreatedBy,
                Active = true,
                CreatedDate = DateTime.Now,
            };
            return await this.unitOfWork.IdProofs.InsertAsync(idproof);
        }

        /// <inheritdoc/>
        public async Task<int> UpdateAsync(IdProofModel model)
        {

            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>($@"select count(*) from ""IdProof"" where  lower (""IdProofName"") = '{model.IdProofName.ToLower()}' and ""IdProofId"" <> {model.IdProofId}");
                if (checkIf > 0)
                {
                    return -1;
                }
                var record = await this.unitOfWork.IdProofs.FindAsync(m => m.IdProofId == model.IdProofId);
                if (record == null)
                {
                    return -2;
                }
                record.ModifiedBy = model.CreatedBy;
                record.ModifiedDate = DateTime.Now;
                record.IdProofName = model.IdProofName;
                return await this.unitOfWork.IdProofs.UpdateAsync(record);
            }
           
            return 1;
        }


    }
}