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

        /// <inheritdoc cref="IChargeService" />
        public ChargeService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

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

            if (model.ChargeGroupId > 0)
            {
                where += $@" AND ""ChargeGroupId"" = {model.ChargeGroupId}";
            }

            var query = $@" 
                        select r.""RepeatTypeId"", r.""RepeatTypeName"", cg.""ChargeGroupId"",c.""ChargeName"",c.""Cost"",c.""Active"",c.""CreatedDate"", c.""ChargeId"",cg.""ChargeGroupName"" from ""Charge"" c
                       left join ""ChargeGroup"" cg on cg.""ChargeGroupId"" = c.""ChargeGroupId""  
                       left join ""RepeatType"" r on r.""RepeatTypeId"" = c.""RepeatTypeId"" {where} order by c.""ChargeId"" ";

            //var query = $@"select cg.""ChargeGroupId"",c.""ChargeName"",c.""Cost"",c.""Active"",c.""CreatedDate"", c.""ChargeId"",cg.""ChargeGroupName"" from ""ChargeGroup"" cg
            //               left join ""Charge"" c on cg.""ChargeGroupId"" = c.""ChargeGroupId""  where c.""ChargeGroupId"" = {model.ChargeGroupId}  order by c.""ChargeGroupId"" ";

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

            model.PageIndex -= 1;
            query += " LIMIT " + model.PageSize + " offset " + (model.PageIndex * model.PageSize);
            return this.unitOfWork.Current.QueryAsync<ChargeModel>(query);
        } 
        
        /// <inheritdoc />
        public Task<IEnumerable<ChargeModel>> ReeatTypeFetchAsync(ChargeFilterModel model)
        {
           

            var query = $@" select * from ""RepeatType""";

            //var query = $@"select cg.""ChargeGroupId"",c.""ChargeName"",c.""Cost"",c.""Active"",c.""CreatedDate"", c.""ChargeId"",cg.""ChargeGroupName"" from ""ChargeGroup"" cg
            //               left join ""Charge"" c on cg.""ChargeGroupId"" = c.""ChargeGroupId""  where c.""ChargeGroupId"" = {model.ChargeGroupId}  order by c.""ChargeGroupId"" ";

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

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

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

                var charge = new Charge
                {
                    Active = true,
                    ChargeName = model.ChargeName,
                    ChargeGroupId = model.ChargeGroupId,
                    //Cost = model.Cost,
                    RepeatTypeId = model.RepeatTypeId,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.UtcNow,
                };

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

            return 0;
        }



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

            var charge = await this.unitOfWork.Charges.FindAsync(m => m.ChargeId == model.ChargeId);
            charge.ChargeName = model.ChargeName;
            //charge.Cost = model.Cost;
            charge.Active = true;
            charge.ChargeGroupId = model.ChargeGroupId;
            charge.RepeatTypeId = model.RepeatTypeId;
            charge.ModifiedBy = model.ModifiedBy;
            charge.ModifiedDate = DateTime.UtcNow;
            return await this.unitOfWork.Charges.UpdateAsync(charge);
        }

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

    }
}