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

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

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

        /// <inheritdoc/>
        public async Task<int> ModifyDepartmentAsync(LabDepartmentModel model)
        {
            var checkIfQuery = $@"SELECT count(""LabDepartmentId"")	FROM ""LabDepartment"" where lower(""DepartmentName"") = '{model.DepartmentName.ToLower()}'";

            if (model.LabDepartmentId == 0)
            {
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    return -1;
                }

                var department = new LabDepartment
                {
                    LabDepartmentId = model.LabDepartmentId,
                    Active = true,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    DepartmentName = model.DepartmentName,
                    Description = model.Description
                };

                return await this.unitOfWork.LabDepartments.InsertAsync(department);
            }
            else
            {
                checkIfQuery += $@" and ""LabDepartmentId"" <> {model.LabDepartmentId} ";
                var checkIf = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<int>(checkIfQuery);
                if (checkIf > 0)
                {
                    return -2;
                }

                var oldRecord = await this.unitOfWork.LabDepartments.FindAsync(d => d.LabDepartmentId == model.LabDepartmentId);
                if (oldRecord == null)
                {
                    return -3;
                }

                oldRecord.Description = model.Description;
                oldRecord.DepartmentName = model.DepartmentName;
                oldRecord.ModifiedBy = model.CreatedBy;
                oldRecord.ModifiedDate = DateTime.Now;

                return await this.unitOfWork.LabDepartments.UpdateAsync(oldRecord);
            }
        }
        ///<inheritdoc/>
        public async Task<IEnumerable<LabDepartmentModel>> FetchAllDepartmentAsync(LabDepartmentModel model)
        {
            var where = "where 1=1";
            if (model.Active != null)
            {
                where += (bool)model.Active ? $@" and LD.""Active"" is true " : $@" and LD.""Active"" is false ";
            }

            if (model.DepartmentName != null)
            {
                where += $@"and (lower( LD.""DepartmentName"") = '{model.DepartmentName.ToLower()}')";
            }
            
            var query = $@"SELECT count(LD.""LabDepartmentId"") over() ""TotalItems"", LD.""LabDepartmentId"", LD.""DepartmentName"", LD.""Description"", LD.""Active"", LD.""CreatedBy"", 
		                    LD.""CreatedDate"", LD.""ModifiedBy"", LD.""ModifiedDate"",
		                    CR.""FullName"" as ""CreatedByName"",CRR.""RoleName"" as ""CreatedByRole"",
		                    MR.""FullName"" as ""ModifiedByName"",MRR.""RoleName"" as ""ModifiedByRole""
	                    FROM ""LabDepartment"" LD
	                    join ""Account"" CR on CR.""AccountId"" = LD.""CreatedBy""
	                    join ""Role"" CRR on CRR.""RoleId"" = CR.""RoleId""
	                    left join ""Account"" MR on MR.""AccountId"" = LD.""ModifiedBy""
	                    left join ""Role"" MRR on MRR.""RoleId"" = MR.""RoleId""
                        {where}
	                    order by LD.""LabDepartmentId"" 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<LabDepartmentModel>(query);
        }

        ///<inheritdoc/>
        public async Task<int> ModifyLabStatus(LabDepartmentModel model)
        {
            var query = $@"UPDATE ""LabDepartment""
	                                SET ""Active""={model.Active}
	                                WHERE ""LabDepartmentId"" = {model.LabDepartmentId}";
            return await this.unitOfWork.Current.ExecuteAsync(query);
        }
    }
}