using Hims.Shared.UserModels.Common;
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.Common;
    using Shared.EntityModels;
    using Shared.UserModels.Filters;

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

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



        /// <inheritdoc/>
        //public async Task<IEnumerable<object>> ExecuteQueryAsync(DynamicReportModel model)
        //{

        //    return await this.unitOfWork.Current.QueryAsync<object>(model.Query);
        //}

        /// <inheritdoc/>
        public async Task<int> InsertAsync(DynamicReportModel model)
        {
            var query = $@"SELECT ""DynamicReportId"" from ""DynamicReport"" WHERE lower(""Name"") = '{model.Name.ToLower()}'  AND ""Active"" IS TRUE";
            var isExists = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>(query);
            if (isExists > 0)
            {
                return -2;
            }

            var record = new DynamicReport
            {
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                Active = true,
                Name = model.Name,
                Data = model.Data

            };
            var result = await this.unitOfWork.DynamicReports.InsertAsync(record);
            if (result <= 0)
            {
                return -1;
            }
            return result;
        }

        /// <inheritdoc/>
        public Task<IEnumerable<DynamicReportModel>> FetchAsync(DynamicReportFilterModel model)
        {
            try
            {
                var query = $@"SELECT COUNT(D.""DynamicReportId"") OVER() ""TotalItems"", D.""DynamicReportId"",

                            D.""Name"", D.""Data"", D.""Active"", D.""CreatedBy"", D.""ModifiedBy"", 
		                    A.""FullName"" ""CreatedByName"", AA.""FullName"" ""ModifiedByName""
                            FROM
                            ""DynamicReport"" D
                            left join ""Account"" A on A.""AccountId"" = D.""CreatedBy""
                            left join ""Account"" AA on AA.""AccountId"" = D.""ModifiedBy""
                            order by D.""DynamicReportId"" desc ";

                model.PageIndex -= 1;
                query += " LIMIT " + model.PageSize + " offset " + (model.PageIndex * model.PageSize);

                var result = this.unitOfWork.Current.QueryAsync<DynamicReportModel>(query);

                return result;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <inheritdoc />
        public async Task<int> DeactivateAsync(int? id, int? modifiedBy)
        {
            var record = await this.unitOfWork.DynamicReports.FindAsync(x => x.DynamicReportId == id);

            if (record == null)
            {
                return -1;
            }
            record.ModifiedBy = modifiedBy;
            record.ModifiedDate = DateTime.Now;
            record.Active = false;

            return await this.unitOfWork.DynamicReports.UpdateAsync(record);

        }

        //<inheritdoc/>
        public async Task<int> UpdateAsync(DynamicReportModel model)
        {
            var query = $@"SELECT ""DynamicReportId"" from ""DynamicReport"" WHERE lower(""Name"") = '{model.Name.ToLower()}' AND ""DynamicReportId""!={model.DynamicReportId}  AND ""Active"" IS TRUE";
            var isExists = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>(query);
            if (isExists > 0)
            {
                return -2;
            }

            var record = await this.unitOfWork.DynamicReports.FindAsync(x => x.DynamicReportId == model.DynamicReportId);

            if (record == null)
            {
                return -1;
            }

            record.Name = model.Name;
            record.Data = model.Data;
            record.ModifiedBy = model.ModifiedBy;
            record.ModifiedDate = DateTime.Now;

            return await this.unitOfWork.DynamicReports.UpdateAsync(record);
        }

        /// <inheritdoc />
        public Task<IEnumerable<DynamicReportModel>> GetReportMenuAsync()
        {
            try
            {
                var query = $@"SELECT 	COUNT(D.""DynamicReportId"") OVER() ""TotalItems"", D.""DynamicReportId"",

                            D.""Name"", D.""Data"", D.""Active"", D.""CreatedBy"", D.""ModifiedBy"", 
		                    A.""FullName"" ""CreatedByName"", AA.""FullName"" ""ModifiedByName""
                            FROM
                            ""DynamicReport"" D
                            left join ""Account"" A on A.""AccountId"" = D.""CreatedBy""
                            left join ""Account"" AA on AA.""AccountId"" = D.""ModifiedBy""
                            where D.""Status""='Verified' and D.""Active"" is true
                            order by D.""DynamicReportId"" desc ";

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


            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public async Task<IEnumerable<FetchModuleTemplatesModel>> FetchModuleTemplatesAsync()
        {
            var query = $@"SELECT ""LabTemplateHeaderId"",""TemplateName"", ""TemplateId"" FROM ""LabTemplateHeader"" WHERE ""Active""=true order by ""CreatedDate"" desc";

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

        public Task<DynamicReportModel> FetchReportAsync(int reportId)
        {
            try
            {
                var query = $@"SELECT ""DynamicReportId"",""Name"",""Data"" FROM ""DynamicReport"" where ""DynamicReportId"" ={reportId}";

                var result = this.unitOfWork.Current.QueryFirstOrDefaultAsync<DynamicReportModel>(query);

                return result;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public async Task<int> InsertImages(DynamicReportImagesModel model)
        {

            var record = new DynamicReportImages
            {
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                Guid = Guid.NewGuid()

            };
            return await this.unitOfWork.DynamicReportImages.InsertAsync(record); ;
        }
        

        public Task<int> UpdateImages(string path, int id)
        {
            var query = $@"update ""DynamicReportImages"" set ""ImagePath""='{path}' where ""DynamicReportImagesId""={id}";
            return this.unitOfWork.Current.ExecuteAsync(query);
        }
        public async Task<IEnumerable<DynamicReportImagesModel>> FetchImagePath()
        {
            var query = $@"select  ""ImagePath"" from ""DynamicReportImages"" where ""ImagePath"" is not null";
            var result = await this.unitOfWork.Current.QueryAsync<DynamicReportImagesModel>(query);
            return result;

        }

    }
}