using System;
using System.Collections.Generic;
using System.Data;
using HMS.Class.Helper;
using HMS.Models;

namespace HMS.Class.DAL
{

    public class PaymentDAL : IDisposable
    {
        #region Variable Declaration

        private DBHelper databaseHelper;

        #endregion

        #region Payment

        #region Public Methods
        public List<PaymentModel> GetAll( string searchField, string searchValue, string sortField, string sortOrder, int pageNo, int pageSize)
        {
            try
            {
                this.databaseHelper = new DBHelper();

                this.databaseHelper.SetParameterToSQLCommand("@SearchField", searchField);
                this.databaseHelper.SetParameterToSQLCommand("@SearchValue", searchValue);
                this.databaseHelper.SetParameterToSQLCommand("@SortField", sortField);
                this.databaseHelper.SetParameterToSQLCommand("@SortOrder", sortOrder);
                this.databaseHelper.SetParameterToSQLCommand("@PageNo", pageNo);
                this.databaseHelper.SetParameterToSQLCommand("@PageSize", pageSize);

                long companyId = SqlHelper.ParseNativeLong(CommonLogic.GetSessionValue(StringConstants.CompanyId));
                this.databaseHelper.SetParameterToSQLCommand("@CompanyId ", companyId);

                IDataReader dataReader = this.databaseHelper.GetReaderByStoredProcedure("HMS_spS_Payment");

                return this.GetPaymentData(dataReader);
            }
            catch
            {
                throw;
            }
            finally
            {
                this.databaseHelper.CloseConnection();
            }
        }

        public PaymentModel GetById(long paymentId)
        {
            try
            {
                this.databaseHelper = new DBHelper();

                this.databaseHelper.SetParameterToSQLCommand("@PaymentId", paymentId);
                IDataReader dataReader = this.databaseHelper.GetReaderByStoredProcedure("HMS_spS_PaymentById");

                List<PaymentModel> list = this.GetPaymentData(dataReader);

                if (list != null && list.Count > 0)
                {
                    return list[0];
                }
                else
                {
                    return null;
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                this.databaseHelper.CloseConnection();
            }
        }
      
        public long Save(PaymentModel payment)
        {
            this.databaseHelper = new DBHelper();

            this.databaseHelper.SetParameterToSQLCommand("@PatientId", payment.PatientId);
            this.databaseHelper.SetParameterToSQLCommand("@InvoiceNumber", payment.InvoiceNumber);
            this.databaseHelper.SetParameterToSQLCommand("@SubTotal", payment.SubTotal);
            this.databaseHelper.SetParameterToSQLCommand("@Discount", payment.Discount);
            this.databaseHelper.SetParameterToSQLCommand("@Tax", payment.Tax);
            this.databaseHelper.SetParameterToSQLCommand("@GrandTotal", payment.GrandTotal);
            this.databaseHelper.SetParameterToSQLCommand("@PaymentStatus", payment.PaymentStatus);
            this.databaseHelper.SetParameterToSQLCommand("@CreatedBy", payment.CreatedBy);
            this.databaseHelper.SetParameterToSQLCommand("@CompanyId", payment.CompanyId);

            if (payment.PaymentId > 0)
            {
                this.databaseHelper.SetParameterToSQLCommand("@PaymentId", payment.PaymentId);
                return SqlHelper.ParseNativeLong(this.databaseHelper.GetExecuteScalarByStoredProcedure("HMS_spU_Payment").ToString());
            }
            else
            {
                return SqlHelper.ParseNativeLong(this.databaseHelper.GetExecuteScalarByStoredProcedure("HMS_spI_Payment").ToString());
            }
        }

        public int UpdateMultipleRecords(MultiOperationType operationType, string multiIds)
        {
            this.databaseHelper = new DBHelper();

            this.databaseHelper.SetParameterToSQLCommand("@MultiIds", multiIds);
            this.databaseHelper.SetParameterToSQLCommand("@OperationType", (int)operationType);

            return SqlHelper.ParseNativeInt(this.databaseHelper.GetExecuteScalarByStoredProcedure("HMS_spM_Payment").ToString());
        }

        public int UpdatePaymentStatus(PaymentStatusType paymentStatusType, string multiIds)
        {
            this.databaseHelper = new DBHelper();

            this.databaseHelper.SetParameterToSQLCommand("@MultiIds", multiIds);
            this.databaseHelper.SetParameterToSQLCommand("@OperationType", (int)paymentStatusType);

            return SqlHelper.ParseNativeInt(this.databaseHelper.GetExecuteScalarByStoredProcedure("HMS_spM_Payment").ToString());
        }

        #endregion

        #region Payment Detail

        public List<PaymentDetailModel> GetPaymentDetailByPayment(long paymentId)
        {
            try
            {
                this.databaseHelper = new DBHelper();

                this.databaseHelper.SetParameterToSQLCommand("@PaymentId", paymentId);
                long companyId = SqlHelper.ParseNativeLong(CommonLogic.GetSessionValue(StringConstants.CompanyId));
                this.databaseHelper.SetParameterToSQLCommand("@CompanyId ", companyId);

                IDataReader dataReader = this.databaseHelper.GetReaderByStoredProcedure("HMS_spS_PaymentDetailByPaymentId");


                if (dataReader != null)
                {
                    using (dataReader)
                    {
                        PaymentDetailModel paymentDetail;
                        List<PaymentDetailModel> paymentDetailList = new List<PaymentDetailModel>();

                        while (dataReader.Read())
                        {
                            paymentDetail = new PaymentDetailModel();

                            paymentDetail.PaymentCategoryId = SqlHelper.GetDBLongValue(dataReader["PaymentCategoryId"]);
                            paymentDetail.PaymentCategory = SqlHelper.GetDBStringValue(dataReader["PaymentCategory"]);
                            paymentDetail.PaymentAmount = SqlHelper.GetDBDecimalValue(dataReader["PaymentAmount"]);

                            paymentDetailList.Add(paymentDetail);
                        }

                        return paymentDetailList;
                    }
                }
                else
                {
                    return null;
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                this.databaseHelper.CloseConnection();
            }
        }

        public void SavePaymentDetail(long paymentId, string chargesData)
        {
            this.databaseHelper = new DBHelper();

            this.databaseHelper.SetParameterToSQLCommand("@PaymentId", paymentId);
            this.databaseHelper.SetParameterToSQLCommand("@CategoryChargeData", chargesData);

            SqlHelper.ParseNativeLong(this.databaseHelper.GetExecuteScalarByStoredProcedure("HMS_spU_PaymentDetail").ToString());

        }
        #endregion

        #region Private Methods

        private List<PaymentModel> GetPaymentData(IDataReader dataReader)
        {
            if (dataReader != null)
            {
                using (dataReader)
                {
                    PaymentModel payment;
                    List<PaymentModel> paymentList = new List<PaymentModel>();

                    while (dataReader.Read())
                    {
                        payment = new PaymentModel();

                        payment.PaymentId = SqlHelper.GetDBLongValue(dataReader["PaymentId"]);
                        payment.InvoiceNumber = SqlHelper.GetDBStringValue(dataReader["InvoiceNumber"]);
                        payment.PatientId = SqlHelper.GetDBLongValue(dataReader["PatientId"]);
                        payment.CompanyId = SqlHelper.GetDBLongValue(dataReader["CompanyId"]);
                        
                        payment.PaymentDate = SqlHelper.GetDBDateTimeValue(dataReader["PaymentDate"]);
                        payment.SubTotal = SqlHelper.GetDBDecimalValue(dataReader["SubTotal"]);
                        payment.Discount = SqlHelper.GetDBDecimalValue(dataReader["Discount"]);
                        payment.Tax = SqlHelper.GetDBDecimalValue(dataReader["Tax"]);
                        payment.GrandTotal = SqlHelper.GetDBDecimalValue(dataReader["GrandTotal"]);
                        payment.PaymentStatus = SqlHelper.GetDBIntValue(dataReader["PaymentStatus"]);

                        payment.PatientName = SqlHelper.GetDBStringValue(dataReader["PatientName"]);
                
                        paymentList.Add(payment);
                    }

                    if (paymentList.Count > 0)
                    {
                        dataReader.NextResult();

                        while (dataReader.Read())
                        {
                            paymentList[0].TotalRecordCount = SqlHelper.GetDBIntValue(dataReader["TotalRecordCount"]);
                        }
                    }

                    return paymentList;
                }
            }
            else
            {
                return null;
            }
        }
        #endregion

        #endregion

        #region Dispose Methods

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.databaseHelper.Dispose();
            }
        }

        #endregion
    }
}