namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    using Dapper;

    using Domain.Repositories.UnitOfWork;
    using Domain.Services;

    using Shared.EntityModels;
    using Shared.UserModels.Filters;

    using Hims.Domain.Configurations;
    using Hims.Domain.Entities;
    using System.Text;
    using System.Security.Cryptography;

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

        /// <summary>
        /// The amazon s 3 configuration.
        /// </summary>
        private readonly IAmazonS3Configuration amazonS3Configuration;

        /// <inheritdoc cref="IAppointmentTransactionService" />
        public AppointmentTransactionServices(IUnitOfWork unitOfWork, IAmazonS3Configuration amazonS3Configuration)
        {
            this.unitOfWork = unitOfWork;
            this.amazonS3Configuration = amazonS3Configuration;
        }

        public Task<AppointmentTransactionModel> FetchAsync(int appointmentId)
        {
            var query = $@"select * from ""AppointmentTransaction"" where ""AppointmentId""={appointmentId} and ""ReceiptTypeId""=1 and ""ReceiptAreaTypeId""=4";

            return this.unitOfWork.Current.QueryFirstOrDefaultAsync<AppointmentTransactionModel>(query);
        }

        /// <inheritdoc />
        public Task<IEnumerable<AppointmentTransactionModel>> FetchAsync(AppointmentTransactionFilterModel model)
        {
            var where = $@" WHERE 1 = 1 ";

            if (!string.IsNullOrEmpty(model.FromDate) && !string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" AND A.""TransactionDate""::DATE >= '{model.FromDate}'::DATE";
                where += $@" AND A.""TransactionDate""::DATE <= '{model.ToDate}'::DATE";
            }

            if (model.ProviderId != null)
            {
                where += $@" AND A.""ProviderId"" = {model.ProviderId}";
            }

            if (model.PatientId != null)
            {
                where += $@" AND A.""PatientId"" = {model.PatientId}";
            }

            if (!string.IsNullOrEmpty(model.AppointmentNo))
            {
                where += $@" And A.""AppointmentNo"" ILIKE '%{model.AppointmentNo}%'";
            }

            if (!string.IsNullOrEmpty(model.TransactionId))
            {
                where += $@" AND A.""TransactionId"" ILIKE '%{model.TransactionId}%'";
            }

            if (!string.IsNullOrEmpty(model.VisitType))
            {
                where += $@" AND A.""VisitType"" = '{model.VisitType}'";
            }

            if (model.CountryId != null)
            {
                where += $@" AND A.""PatientCountryId"" = {model.CountryId}";
            }

            var query =
                $@"SELECT COUNT(A.*) OVER () AS ""TotalItems"", A.* FROM (SELECT apttra.""AppointmentTransactionId"", apttra.""TransactionId"",apttra.""PaymentId"", apttra.""TransactionDate"", apttra.""BankReference"", apttra.""BankCode"", apttra.""Active"",
                                    apt.""AppointmentId"",  apt.""PatientId"", apt.""Total"" ""Amount"", apt.""VisitType"", apt.""Discount"", apt.""CouponId"", apt.""AppointmentNo"", apt.""Status"",
                                    pat.""CountryId"" AS ""PatientCountryId"", cun.""CountryName"" AS ""PatientCountryName"", cun.""CountryCode"" AS ""PatientCountryCode"",
                                    pat.""FullName"" AS ""PatientName"", pat.""UMRNo"" AS ""PatientUMRNo"", pr.""ProviderId"", pr.""FullName"" AS ""ProviderName"", apttra.""SettledAmount"", apttra.""PaymentModeId"",apttra.""SalucroStatusCode"",apttra.""SalucroTransactionId"",
									round(apt.""Total"" * ( pm.""TDS"" / 100 ),2) AS ""TDSAmount"", pm.""PaymentGateway"", ps.""Status"" AS ""PaymentStatus""
                                    , (CASE WHEN pba.""Percentage"" IS NULL THEN round(apt.""Total"" * ( 10.00 / 100 ),2) ELSE round(apt.""Total"" * ( pba.""Percentage"" / 100 ),2) END) AS ""AppCharges"",
                                    round(((apt.""Amount""-coalesce(r.""RefundAmount"",0)) * 0.36 /100),2) ""Gst"",
                                    round(((apt.""Amount""-coalesce(r.""RefundAmount"",0)) * 2 /100),2) ""payufees"",
                                    round(((apt.""Amount""-coalesce(r.""RefundAmount"",0)) * 0.36 /100),2)+round(((apt.""Amount""-coalesce(r.""RefundAmount"",0)) * 2 /100),2)
                                    ""processingfees"",
                                    (apt.""Total""-coalesce(r.""RefundAmount"",0))-(round(((apt.""Amount""-coalesce(r.""RefundAmount"",0)) * 0.36 /100),2)+round(((apt.""Amount""-coalesce(r.""RefundAmount"",0)) * 2 /100),2))
                                    ""Afterprocessingfees""
                                    FROM ""AppointmentTransaction"" apttra
                                    JOIN ""PaymentMode"" pm ON pm.""PaymentModeId"" = apttra.""PaymentModeId"" AND pm.""Active"" IS TRUE
                                    LEFT JOIN ""PaymentStatus"" ps ON ps.""PaymentStatusId"" = apttra.""PaymentStatusId"" AND ps.""Active"" IS TRUE
                                    JOIN ""Appointment"" apt ON apt.""AppointmentId"" = apttra.""AppointmentId""
                                    JOIN ""Patient"" pat ON pat.""PatientId"" = apt.""PatientId"" AND pat.""Active"" IS TRUE
                                    LEFT JOIN ""Country"" cun ON cun.""CountryId"" = pat.""CountryId"" AND cun.""Active"" IS TRUE
                                    JOIN ""Provider"" pr ON pr.""ProviderId"" = apt.""ProviderId"" AND pr.""Active"" IS TRUE
                                    LEFT JOIN ""ProviderBankAccount"" pba ON pba.""ProviderId"" = pr.""ProviderId"" AND pba.""Active"" IS TRUE
                                    JOIN ""ProviderLocation"" prl ON prl.""ProviderLocationId"" = apt.""ProviderLocationId"" AND prl.""Active"" IS TRUE
                                    LEFT JOIN ""Refund"" r ON r.""RefundId"" = apttra.""RefundId"" AND r.""Active"" IS TRUE
                                ) AS A {where} Order BY A.""AppointmentTransactionId"" DESC ";

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

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

        /// <inheritdoc />
        public Task<IEnumerable<AppointmentTransactionModel>> FetchProviderTransactionsAsync(AppointmentTransactionFilterModel model)
        {
            string fromDate;
            string toDate;
            string providerId;
            string year;
            string month;
            if (model.ProviderId == null)
            {
                providerId = "null";
            }
            else
            {
                providerId = "'" + model.ProviderId + "'";
            }

            if (model.FromDate == null)
            {
                fromDate = "null";
            }
            else
            {
                fromDate = "'" + model.FromDate + "'";
                model.Year = "null";
                model.Month = "null";
            }

            if (model.ToDate == null)
            {
                toDate = "null";
            }
            else
            {
                toDate = "'" + model.ToDate + "'";
                model.Year = "null";
                model.Month = "null";
            }

            if (model.Year == null || model.Year == "null")
            {
                year = "null";
            }
            else
            {
                year = "'" + model.Year + "'";
            }

            if (model.Month == null || model.Month == "null")
            {
                month = "null";
            }
            else
            {
                month = "'" + model.Month + "'";
            }

            model.PageIndex -= 1;
            var query =
                $@"SELECT * from ""udf_AppointmentsByProvider""({providerId},null,{fromDate},{toDate},{month},{year},{model.PageIndex},{model.PageSize})";

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

            query += " LIMIT " + model.PageSize;
            return this.unitOfWork.Current.QueryAsync<AppointmentTransactionModel>(query);
        }

        /// <inheritdoc />
        public Task<IEnumerable<RefundModel>> FetchRefundAsync(AppointmentTransactionFilterModel model)
        {
            var where = $@" WHERE 1 = 1 ";

            if (!string.IsNullOrEmpty(model.FromDate) && !string.IsNullOrEmpty(model.ToDate))
            {
                where += $@" AND A.""RefundCreatedDate""::DATE >= '{model.FromDate}'::DATE";
                where += $@" AND A.""RefundCreatedDate""::DATE <= '{model.ToDate}'::DATE";
            }

            if (model.ProviderId != null)
            {
                where += $@" AND A.""ProviderId"" = {model.ProviderId}";
            }

            if (model.PatientId != null)
            {
                where += $@" AND A.""PatientId"" = {model.PatientId}";
            }

            if (!string.IsNullOrEmpty(model.AppointmentNo))
            {
                where += $@" And A.""AppointmentNo"" ILIKE '%{model.AppointmentNo}%'";
            }

            if (!string.IsNullOrEmpty(model.TransactionId))
            {
                where += $@" AND A.""TransactionId"" ILIKE '%{model.TransactionId}%'";
            }

            var query =
                $@"SELECT COUNT(A.*) OVER () AS ""TotalItems"", A.* FROM (SELECT apttra.""AppointmentTransactionId"",apt.""AppointmentNo"" ,apttra.""TransactionId"",apttra.""PaymentId"",
                              apt.""Total"",re.""RefundId"",re.""RefundAmount"",ps.""Status"" as ""RefundStatus"",re.""RefundTransactionId"",re.""RefundCompletedDate"",
                              re.""CreatedDate"" as ""RefundCreatedDate"",pat.""PatientId"",pat.""FullName"" AS ""PatientName"", pat.""UMRNo"" AS ""PatientUMRNo"", pr.""ProviderId"",pr.""FullName"" AS ""ProviderName""
                              FROM ""AppointmentTransaction"" apttra
                              JOIN ""Appointment"" apt ON apt.""AppointmentId"" = apttra.""AppointmentId""
                              JOIN ""Refund"" re ON re.""AppointmentTransactionId"" = apttra.""AppointmentTransactionId""
                              JOIN ""PaymentStatus"" ps ON ps.""PaymentStatusId"" = re.""RefundStatus""
                              JOIN ""Patient"" pat ON pat.""PatientId"" = apt.""PatientId"" AND pat.""Active"" IS TRUE
                              JOIN ""Provider"" pr ON pr.""ProviderId"" = apt.""ProviderId"" AND pr.""Active"" IS TRUE
                              ) AS A {where} Order BY A.""RefundId"" DESC ";

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

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

        /// <inheritdoc />
        public Task<string> FindTransactionDetailsAsync(int appointmentTransactionId)
        {
            var query =
                $@"SELECT ""Transaction"" FROM ""AppointmentTransaction"" WHERE ""AppointmentTransactionId""= {appointmentTransactionId}";
            return this.unitOfWork.Current.QueryFirstOrDefaultAsync<string>(query);
        }

        /// <inheritdoc />
        public Task<IEnumerable<ProviderBankAccountModel>> FetchPayoutAsync(AppointmentTransactionFilterModel model)
        {
            var where = $@" WHERE 1 = 1 ";

            if (model.ProviderId != null)
            {
                where += $@" AND p.""ProviderId"" = {model.ProviderId}";
            }

            var query =
                $@"select COUNT(p.""ProviderId"") OVER() AS ""TotalItems"",p.""ProviderId"",p.""ProviderId"",p.""FullName"",p.""Email"",pb.""AccountNumber"",pb.""Percentage"", 
                               sum( case when at.""PayoutId"" is not null then ap.""Total"" end) as ""AmountPaid"", sum( case when at.""PayoutId"" is null then ap.""Total"" end) as ""PendingAmount""  from ""Provider"" p inner join
                               ""Appointment"" ap on p.""ProviderId"" = ap.""ProviderId"" inner join ""AppointmentTransaction"" at on at.""AppointmentId"" = ap.""AppointmentId"" left join
                               ""ProviderBankAccount"" pb on pb.""ProviderId"" = p.""ProviderId"" {where} GROUP by p.""ProviderId"",p.""FullName"",p.""Email"",pb.""AccountNumber"",pb.""Percentage""";

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

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

        /// <inheritdoc />
        public Task<IEnumerable<AppointmentTransactionModel>> FetchPayoutDetailsAsync(
            AppointmentTransactionFilterModel model)
        {
            var where = $@" WHERE 1 = 1 ";

            if (model.ProviderId != null)
            {
                where += $@" AND p.""ProviderId"" = {model.ProviderId}";
            }

            var query =
                $@"select COUNT(p.""ProviderId"") OVER() AS ""TotalItems"",(sum(app.""Total"") over(PARTITION BY extract('week' from app.""AppointmentDate""))) as ""WeekTotal"", extract('week' from app.""AppointmentDate"")::int as ""Week"",extract('year' from app.""AppointmentDate"")::int as ""Year"",
                                 apttra.""AppointmentTransactionId"",app.""AppointmentDate"",app.""Total"",pat.""FullName"" as ""PatientName"",pat.""Email"",po.""PayoutId"" from ""AppointmentTransaction"" apttra 
                                 inner join ""Appointment"" app on apttra.""AppointmentId""=app.""AppointmentId""
                                 inner join ""Provider"" p on p.""ProviderId""=app.""ProviderId""
                                 inner join ""Patient"" pat on pat.""PatientId""=app.""PatientId""
                                 inner join ""Payout"" po on po.""PayoutId""=apttra.""PayoutId""
                                 {where} order by ""Week"" desc";

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

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

        /// <inheritdoc />
        public Task<IEnumerable<SettlementDetailModel>> FindSettlementDetailsAsync(SettlementFilterModel model)
        {
            string fromDate;
            string todate;
            string providername;

            if (model.FromDate == null)
            {
                fromDate = "null";
            }
            else
            {
                fromDate = "'" + model.FromDate + "'";
            }

            if (model.ToDate == null)
            {
                todate = "null";
            }
            else
            {
                todate = "'" + model.FromDate + "'";
            }

            if (model.Name == null)
            {
                providername = "null";
            }
            else
            {
                providername = "'" + model.Name + "'";
            }

            model.PageIndex -= 1;
            var query = $@"SELECT * FROM ""udf_AmountByProvider""(null,{providername},{fromDate}, {todate},{model.PageIndex},{model.PageSize})";

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

        /// <inheritdoc />
        public Task<IEnumerable<AppointmentTransactionModel>> FetchAppointmentsDetailsAsync(AppointmentTransactionFilterModel model)
        {
            var fromDate = model.FromDate == null ? "null" : "'" + model.FromDate + "'";
            var toDate = model.ToDate == null ? "null" : "'" + model.ToDate + "'";
            var providerName = model.ProviderName == null ? "null" : "'" + model.ProviderName + "'";
            var appointmentNo = model.AppointmentNo == null ? "null" : "'" + model.AppointmentNo + "'";
            var transactionId = model.TransactionId == null ? "null" : "'" + model.TransactionId + "'";
            var patientId = model.PatientId == null ? "null" : "'" + model.PatientId + "'";
            var countryCode = model.PatientCountryId == null ? "null" : "'" + model.PatientCountryId + "'";
            var visitType = model.VisitType == null ? "null" : "'" + model.VisitType + "'";

            model.PageIndex -= 1;
            var query = $@"SELECT * FROM ""udf_AppointmentsTransByProvider""({model.ProviderId},{providerName},{patientId},{appointmentNo},{visitType},{transactionId},{countryCode},{fromDate}, {toDate},{model.PageIndex},{model.PageSize})";

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

        /// <inheritdoc />
        public async Task<IEnumerable<int>> AddAsync(IEnumerable<PaymentDocumentModel> model)
        {
            var patientDocuments = model.Select(item => new PaymentDocument
            {
                Active = true,
                ProviderId = item.ProviderId,
                UploadedBy = item.UploadedBy,
                DocumentName = item.DocumentName,
                DocumentType = item.DocumentType,
                ContentType = item.ContentType,
                Size = item.Size,
                Description = item.Description,
                DocumentUrl = item.DocumentUrl,
                ThumbnailUrl = item.ThumbnailUrl,
                UploadedDate = DateTime.UtcNow,
                Year = item.Year,
                Month = item.Month
            });
            var responseIds = new List<int>();

            foreach (var patientDocument in patientDocuments)
            {
                var response = await this.unitOfWork.PaymentDocuments.InsertAsync(patientDocument);
                responseIds.Add(response);
            }

            return responseIds;

            // return this.unitOfWork.PatientDocuments.BulkInsertAsync(patientDocuments);
        }

        /// <summary>
        /// The get async.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public async Task<PaymentDocumentModel> GetAsync(int id)
        {
            var record = await this.unitOfWork.PaymentDocuments.FindAsync(x => x.PaymentDocumentId == id);

            if (record != null)
            {
                return new PaymentDocumentModel
                {
                    PaymentDocumentId = record.PaymentDocumentId,
                    ProviderId = record.ProviderId,
                    DocumentName = record.DocumentName,
                    DocumentType = record.DocumentType,
                    Description = record.Description
                };
            }

            return null;
        }

        /// <inheritdoc />
        public async Task<int> UpdateAsync(PaymentDocumentModel model)
        {
            var paymentDocument = await this.unitOfWork.PaymentDocuments.FindAsync(m => m.PaymentDocumentId == model.PaymentDocumentId);
            paymentDocument.DocumentName = model.DocumentName;
            paymentDocument.Description = model.Description;
            paymentDocument.Month = model.Month;
            paymentDocument.Year = model.Year;
            paymentDocument.ModifiedBy = model.ModifiedBy;
            paymentDocument.DocumentName = model.DocumentName;
            paymentDocument.ModifiedDate = DateTime.UtcNow;

            return await this.unitOfWork.PaymentDocuments.UpdateAsync(paymentDocument);
        }

        /// <inheritdoc />
        public Task<IEnumerable<PaymentDocumentModel>> FetchPaymentAsync(PaymentDocumentFilterModel model)
        {
            var @where = $@" WHERE prd.""Active"" IS TRUE";

            if (model.ProviderId != null)
            {
                where = $@" AND prd.""ProviderId"" = {model.ProviderId}";
            }

            if (model.Year != null)
            {
                where += $@" AND {model.Year}=prd.""Year""::int";
            }

            if (model.Month != null)
            {
                where += $@" AND {model.Month}=prd.""Month""::int";
            }

            var query =
                $@"SELECT COUNT(*) OVER () AS ""TotalItems"", prd.""ProviderId"", prd.""PaymentDocumentId"", prd.""DocumentType"", prd.""DocumentName"", CASE WHEN prd.""Description"" IS NULL THEN '' ELSE prd.""Description"" END ""Description"", prd.""ContentType"", prd.""Size"",prd.""IsRead"",
                                prd.""UploadedDate"", prd.""UploadedBy"", act.""FullName"" AS ""UploadedByName"", rl.""RoleName"" AS ""UploadedByRole"", pat.""FullName"" AS ""ProviderName"",
                                (CASE WHEN prd.""ThumbnailUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL}', prd.""ThumbnailUrl"") ELSE NULL END) AS ""ThumbnailUrl"",
                                (CASE WHEN prd.""DocumentUrl"" IS NOT NULL THEN CONCAT('{this.amazonS3Configuration.BucketURL + "PaymentDocuments/Payment"}', '/', prd.""DocumentUrl"") ELSE NULL END) AS ""DocumentUrl""
                                 ,prd.""Month"",prd.""Year""
                                , prd.""UploadedBy"", act.""FullName"" AS ""UploadedByName"", rl.""RoleName"" AS ""UploadedByRole"", pat.""FullName"" AS ""PatientName""
                                FROM ""PaymentDocument"" prd
                                JOIN ""Provider"" pat ON pat.""ProviderId"" = prd.""ProviderId"" AND pat.""Active"" IS TRUE
                                JOIN ""Account"" act ON act.""AccountId"" = prd.""UploadedBy"" AND act.""Active"" IS TRUE
                                JOIN ""Role"" rl ON rl.""RoleId"" = act.""RoleId"" AND rl.""Active"" IS TRUE
                                {where} ORDER BY prd.""PaymentDocumentId"" DESC";

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

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

        /// <summary>
        /// The delete async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public async Task<int> DeleteAsync(PaymentDocumentModel model)
        {
            var query = $@"DELETE FROM ""PaymentDocument"" WHERE ""PaymentDocumentId""= {model.PaymentDocumentId}";
            var deleted = await this.unitOfWork.Current.ExecuteAsync(query);
            return deleted;
        }

        /// <inheritdoc />
        public async Task<string> GetPreviousVoucherNumberAsync()
        {
            var query = $@"select ""VoucherNumber"" from ""AppointmentTransaction"" order by ""AppointmentTransactionId"" desc limit 1";
            return await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);

        }

        /// <summary>
        /// The get bill number.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public async Task<string> GetVoucherNumber()
        {
            try
            {
                var query = $@"select ""VoucherNumber"" from ""AppointmentTransaction"" where ""VoucherNumber"" is not null order by ""AppointmentTransactionId"" desc limit 1";
                var previousVoucherNo = await this.unitOfWork.Current.QuerySingleOrDefaultAsync<string>(query);


                if (previousVoucherNo == null)
                {

                    return $@"{DateTime.Now.ToString("yyMMdd")}/0001";
                }
                else
                {
                    var preVoucherno = previousVoucherNo.ToString(); // converting in string
                    var prevoucherdate = preVoucherno.Substring(0, Math.Min(preVoucherno.Length, 6)); //DateTime in string


                    if (prevoucherdate != DateTime.Now.ToString("yyMMdd"))
                    {
                        return $@"{DateTime.Now.ToString("yyMMdd")}/0001"; // start seq for new date .
                    }
                    else
                    {
                        var presequenceNo = preVoucherno.Substring(preVoucherno.Length - 4);    //  get seq  .
                        var getNO = Convert.ToInt64(presequenceNo) + 1; //incre
                        var getnumber = string.Format("{0:0000}", getNO); // padding
                        return $@"{DateTime.Now.ToString("yyMMdd")}/{getnumber}";
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public async Task<string> GetATransactionId()
        {
            //use this method only for transaction - DB-AppointmentTransaction table entry

            //var rnd = new Random();
            //var strHash = GenerateHash(rnd.ToString() + DateTime.UtcNow);
            //return strHash.Substring(0, 20);
            var rnd = new Random();
            var message = Encoding.UTF8.GetBytes(rnd.Next().ToString() + DateTime.Now);
            var hashString = new SHA512Managed();
            var hashValue = hashString.ComputeHash(message);
            var strHash = hashValue.Aggregate(string.Empty, (current, x) => current + $"{x:x2}");
            return strHash.Substring(0, 20);
        }

        public static string GenerateHash(string text)
        {
            var message = Encoding.UTF8.GetBytes(text);
            var hashString = new SHA512Managed();
            var hashValue = hashString.ComputeHash(message);
            return hashValue.Aggregate(string.Empty, (current, x) => current + $"{x:x2}");
        }
    }
}