namespace Hims.Infrastructure.Services
{
    using System;
    using System.Threading.Tasks;

    using Dapper;

    using Domain.Entities;
    using Domain.Repositories.UnitOfWork;

    using Shared.EntityModels;

    using Hims.Domain.Services;

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

        /// <inheritdoc cref="IPayUService" />
        public PayUService(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc />
        public async Task<int> AddRefundAsync(RefundModel model)
        {
            using (var transaction = this.unitOfWork.BeginTransaction())
            {
                try
                {
                    var checkIf = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT COUNT(""AppointmentTransactionId"") FROM ""Refund"" WHERE ""AppointmentTransactionId"" = '{model.AppointmentTransactionId}'", transaction);
                    if (checkIf > 0)
                    {
                        return -1;
                    }

                    var refund = new Refund
                    {
                        RefundTransactionId = model.RefundTransactionId,
                        AppointmentTransactionId = model.AppointmentTransactionId,
                        RefundAmount = model.RefundAmount,
                        Active = true,
                        CreatedBy = model.CreatedBy,
                        CreatedDate = DateTime.UtcNow,
                        RefundCompletedDate = model.RefundCompletedDate
                    };
                    var paymentStatusId = await this.unitOfWork.Current.QueryFirstOrDefaultAsync<int>($@"SELECT ""PaymentStatusId"" FROM ""PaymentStatus"" WHERE ""Status"" = '{model.RefundStatus}'", transaction);
                    if (paymentStatusId <= 0)
                    {
                        var paymentStatus = new PaymentStatus
                        {
                            Status = model.RefundStatus,
                            Active = true
                        };
                        paymentStatusId = await this.unitOfWork.PaymentStatus.InsertAsync(paymentStatus, transaction);
                    }

                    refund.RefundStatus = paymentStatusId;
                    refund.RefundId = await this.unitOfWork.Refunds.InsertAsync(refund, transaction);
                    if (refund.RefundId > 0)
                    {
                        var appointmentTransaction = await this.unitOfWork.AppointmentTransactions.FindByIdAsync(model.AppointmentTransactionId, transaction);
                        if (appointmentTransaction.AppointmentTransactionId > 0)
                        {
                            appointmentTransaction.RefundId = refund.RefundId;
                            await this.unitOfWork.AppointmentTransactions.UpdateAsync(appointmentTransaction);
                        }
                    }

                    transaction.Commit();
                    return refund.RefundId;
                }
                catch
                {
                    transaction.Rollback();
                    return -1;
                }
            }
        }

        /// <inheritdoc />
        public async Task<int> AddWebHookAsync(WebHookModel model)
        {
            var webHook = new WebHook
            {
                WebHookEvent = model.WebHookEvent,
                WebHookData = model.WebHookData,
                Active = true,
                CreatedDate = DateTime.Now,
            };
            return await this.unitOfWork.WebHook.InsertAsync(webHook);
        }
    }
}
