
package my.com.kfh.enterprise.services.ib115_gold.gold_transfer_own;

/**
 * PROGRAMMER: Goh Kee Kun
 * COMPANY: Pixakraft
 * DATE CREATED: 15-Oct-2012
 */

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import my.com.kfh.enterprise.services.ESBServiceFactoryImpl;
import my.com.kfh.enterprise.services.GenericESBServicesImpl;
import my.com.kfh.enterprise.services.IBEnterpriseServices;
import my.com.kfh.enterprise.services.IBEnterpriseServicesWorkspace;
import my.com.kfh.enterprise.services.IBUtils;
import my.com.kfh.enterprise.services.ib101_access.AccessConstants;
import my.com.kfh.enterprise.services.ib101_access.IBAccessDBUtils;
import my.com.kfh.enterprise.services.ib112_si.IBGenericSIServices;
import my.com.kfh.enterprise.services.ib112_si.SIDBUtils;
import my.com.kfh.enterprise.services.ib112_si.SI_PAYMENT_MODE;
import my.com.kfh.enterprise.services.ib115_gold.constant.GoldConstants;
import my.com.kfh.enterprise.services.ib115_gold.constant.SIConstantsExtension;
import my.com.kfh.enterprise.services.ib115_gold.gold_thirdparty.IBGoldTableLogger;
import my.com.kfh.enterprise.services.ib115_gold.gold_thirdparty.SMSServiceGold;
import my.com.kfh.enterprise.services.ib115_gold.gold_thirdparty.ThirdPartyGoldTransferTags;
import my.com.kfh.enterprise.services.integration.ESBProcessBean;
import my.com.kfh.enterprise.services.integration.ESBProcessBeanInterface;
import my.com.kfh.error.exception.IBGenericException;
import my.com.kfh.error.exception.IBServiceException;
import my.com.kfh.error.handler.CommonErrorCode;
import my.com.kfh.error.handler.IBErrorHandler;
import my.com.kfh.esb.agent.ESBXapi905Agent;
import my.com.kfh.esb.constant.EnumAccType;
import my.com.kfh.esb.constant.EnumApplType;
import my.com.kfh.esb.constant.EnumDepLoan;
import my.com.kfh.esb.constant.EnumPhoenixTranCode;
import my.com.kfh.esb.request.ESBRequestXapi905Bean;
import my.com.kfh.esb.response.ESBAccountDetailsBean;
import my.com.kfh.esb.response.ESBAccountEnquiryTC100Bean;
import my.com.kfh.esb.response.ESBAccountInfoDetailBean;
import my.com.kfh.esb.response.ESBMsgHeader;
import my.com.kfh.esb.response.ESBResponseXapi905Bean;
import my.com.kfh.web.utils.BVI_DateTime;
import my.com.kfh.web.utils.DataValidator;
import my.com.kfh.web.utils.DateTimeUtils;
import my.com.kfh.web.utils.FormatterUtils;
import my.com.kfh.web.utils.IBLogger;
import my.com.kfh.web.utils.IBSessionObjects;
import my.com.kfh.web.utils.IBTimer;
import my.com.kfh.web.utils.ResourcesUtils;
import my.com.kfh.web.utils.constant.ESBConstants;
import my.com.kfh.web.utils.constant.LogTables;

import org.dom4j.Document;
import org.dom4j.Element;

import com.broadvision.data.client.DataManager;
import com.broadvision.data.common.TableData;


/**
 * <Class description>
 */
public class IBOwnGoldSITransferResultsServices
{
	private static Class c_oClass = IBOwnGoldSITransferResultsServices.class;

	public static void executeTransaction(String siId) throws IBGenericException
	{
        String m_sMethodName = "executeGoldTransferTransaction";
        IBTimer m_oTimer = IBLogger.logBSFNMethodEnteringMessage (c_oClass, m_sMethodName, String.class.getName ());

		String m_sSICharges = "0";
		String m_sSIChargesRefNo = null;
		boolean m_boSIChargeStatus = false;
		double m_dAvailableBal = 0.0;
		double m_dTransferAmount = 0.0;
		double m_dTotalAmount = 0.0;
		double m_dSICharges = 0.0;
//		String m_sSIChargeResponseCode = null;
		boolean m_boIsFundSufficient = true;
		ESBAccountDetailsBean m_oFromGoldEnquiryBean=null;
		ESBAccountDetailsBean m_oToAccEnquiryBean=null;
		String m_sFromAccBranchCode=null;
//		String m_sFromAccBranchName=null;
//		String m_sPhx_Ref_no = "";
		String	m_sReferenceNo = null;
		String m_sStatus = ResourcesUtils.getUnsuccessful ();
		String m_sReason = null;
		boolean hasReceipt = false;

		String m_sEsbDescription = null;

		try
		{
			BVI_DateTime m_oCurrentBVIDateTime = DateTimeUtils.getCurrentIBDateTimeObject ();

			IBSessionObjects m_oSessionObj = mock(IBSessionObjects.class);
			when(m_oSessionObj.getDataManager()).thenReturn(new DataManager());
			// get info from IB_SI
			TableData table = SIDBUtils.getSICurrentTransId(new IBEnterpriseServicesWorkspace(m_oSessionObj), siId);
			String currentTrnxId  = table.getStringValue(0, LogTables.IB_SI.CURRENT_TRNX_ID.toString ());
			String siPaymentModeCode = table.getStringValue(0, LogTables.IB_SI.PAYMENT_MODE.toString ());
			String trnxTypeDisplay = table.getStringValue(0, LogTables.IB_SI.TRNX_TYPE.toString ());

			System.out.println("siId, currentTrnxId: "+ siId + ", " + currentTrnxId);

			m_sEsbDescription = "IB Gold Transfer - Own Gold Account";
			m_sEsbDescription = IBGenericSIServices.getESBDescription (m_sEsbDescription, siPaymentModeCode);

			IBEnterpriseServices p_oEnterpriseServices = new IBEnterpriseServicesWorkspace(m_oSessionObj);

			//get user id from trnx in IB_INTRA_GOLD_TRANSFER
			table = OwnTransferDBUtils.getTransactionByTrnxIdGold(p_oEnterpriseServices, currentTrnxId);
			String userId = table.getStringValue(0, IBGoldTableLogger.IB_INTRA_GOLD_TRANSFER.USER_ID.toString ());

			System.out.println("userId "+userId);
			
			com.broadvision.visitor.client.Visitor visitor = mock(com.broadvision.visitor.client.Visitor.class);
			when(visitor.getId()).thenReturn(Long.parseLong(userId));
			when(m_oSessionObj.getVisitor()).thenReturn(visitor);

			//get various data from transaction
			String m_sFromAccount = table.getStringValue(0, IBGoldTableLogger.IB_INTRA_GOLD_TRANSFER.FROM_ACCOUNT_NO.toString ());
			String m_sToAccount = table.getStringValue(0, IBGoldTableLogger.IB_INTRA_GOLD_TRANSFER.TO_ACCOUNT_NO.toString ());
			String m_sAmount = table.getStringValue(0, IBGoldTableLogger.IB_INTRA_GOLD_TRANSFER.AMOUNT.toString ());
			String fromCurrency = table.getStringValue(0, IBGoldTableLogger.IB_INTRA_GOLD_TRANSFER.FROM_CURRENCY.toString ());
			String toCurrency = table.getStringValue(0, IBGoldTableLogger.IB_INTRA_GOLD_TRANSFER.TO_CURRENCY.toString ());
			String charges = "0";

			System.out.println("m_sFromAccount + m_sToAccount + m_sAmount + trnxTypeDisplay: " +
					m_sFromAccount + ", " + m_sToAccount + ", " + m_sAmount + ", " + trnxTypeDisplay);

			System.out.println("m_sCharges + toCurrency + fromCurrency: " + charges + ", "+toCurrency + ", "+fromCurrency);

			//get user rim no
			String rimNo = IBAccessDBUtils.getRimNoByUserId(p_oEnterpriseServices, userId);
			System.out.println("rimNo "+ rimNo);
			when(m_oSessionObj.getHttpSessionAttrObject (AccessConstants.RIM_NO)).thenReturn(rimNo);
			System.out.println("rimNo2 "+ rimNo);
			GenericESBServicesImpl m_oEsbServices = new GenericESBServicesImpl (m_oSessionObj);

			ESBAccountEnquiryTC100Bean m_oTCEnquiryBean = m_oEsbServices.getAccountDetailsTC100 (m_sFromAccount);
			
			if(m_oTCEnquiryBean.getResponseCode()!=null){
				System.out.println("own response code from: " + m_oTCEnquiryBean.getResponseCode());
			}
			if(m_oTCEnquiryBean.getErrorMessage()!=null){
				System.out.println("own error msg from: " + m_oTCEnquiryBean.getErrorMessage());
			}
			
			
			if(m_oTCEnquiryBean.getResponseCode().equals("0000")){
			
			if (!DataValidator.isEmptyString (m_oTCEnquiryBean.getAvailable_Bal ()))
			{
				m_dAvailableBal = Double.parseDouble (m_oTCEnquiryBean.getAvailable_Bal ());
			}

			System.out.println("own AvailableBalance: " + m_dAvailableBal);

			if (SI_PAYMENT_MODE.RECURRING_PAYMENT.getCode ().equals (siPaymentModeCode))
			{
				m_dSICharges = 0.0;//IBGenericSIServices.getSICharges (ServiceInfoExtend.GOLD_TRANSFER_OWN);
    			m_sSICharges = String.valueOf (m_dSICharges);

				if (m_dSICharges > 0)
				{
					if (m_dAvailableBal > m_dSICharges)
					{
//						String m_sChargeGLAccount = IBGenericSIServices.getSICollectionAccountNo (m_sFromAccount);
//						System.out.println("SI GL Account: " + m_sChargeGLAccount);
//
//						ESBTransferToGLBean m_oESBTransferToGLBean = m_oEsbServices.chargesTransfer (m_sFromAccount,
//								m_sChargeGLAccount, m_sSICharges, ESBConstants.SI_CHARGES, null);
//
//						m_sSIChargeResponseCode = m_oESBTransferToGLBean.getResponseCode ();
//						if (ESBConstants.IB_SUCCESS_RC.equalsIgnoreCase (m_sSIChargeResponseCode))
//						{
//							m_boSIChargeStatus = true;
//							m_sSIChargesRefNo = m_oESBTransferToGLBean.getReferenceNo ();
//						}
//						else
//						{
//							m_boIsFundSufficient = false;
//							hasReceipt = false;
//							m_sStatus = ResourcesUtils.getUnsuccessful ();
//							m_sReason = m_oESBTransferToGLBean.getErrorMessage ();
//						}
					}
					else
					{
//						m_boIsFundSufficient = false;
//						hasReceipt = false;
//						m_sStatus = ResourcesUtils.getUnsuccessful ();
//						m_sReason = ResourcesUtils.getApplicationResourceMessage (SIConstants.RESOURCES_INSUFFICIENT_FUND);
					}
				}
			}

			// Makesure m_boIsFundSufficient is NEVER set to false previously. Check is account balance sufficient to do transfer?
			if (m_boIsFundSufficient)
			{
				m_dTransferAmount = Double.parseDouble (m_sAmount);
				m_dTotalAmount = m_dTransferAmount;// + m_dSICharges;

				if(m_dAvailableBal < m_dTotalAmount)
				{
					m_boIsFundSufficient = false;
					hasReceipt = false;
					m_sStatus = ResourcesUtils.getUnsuccessful ();
					m_sReason = ResourcesUtils.getApplicationResourceMessage (ThirdPartyGoldTransferTags.INSUFFICIENT_GOLD);
				}
			}

			System.out.println("own sufficient: " + m_boIsFundSufficient);
			if (m_boIsFundSufficient)
			{
//				ESBFundTransferOwnBean m_oOwnTransfer = m_oEsbServices.ownFundTransfer (m_sFromAccount, m_sToAccount,
//						m_sEsbDescription, m_sAmount, null);

				m_oFromGoldEnquiryBean = m_oEsbServices.getAccountDetails (m_sFromAccount);
				m_oToAccEnquiryBean=m_oEsbServices.getAccountDetails (m_sToAccount);
				if(!DataValidator.isEmptyString(m_sFromAccount)){
					try{
						ESBAccountInfoDetailBean m_oESBAcctInfoDetails = m_oEsbServices.getAccountInfoDetail(m_sFromAccount);
						m_sFromAccBranchCode = m_oESBAcctInfoDetails.getBranchCode();
						m_sFromAccBranchCode = FormatterUtils.padderLeft (m_sFromAccBranchCode,"0", 3);	
					}catch(Exception e)
					{
						e.printStackTrace();
						if (e instanceof IBGenericException)
						{
							throw (IBGenericException) e;
						}
						throw IBErrorHandler.createServiceException(IBServiceException.GENERAL_SERVICE_ERROR, true,
								new String[] {CommonErrorCode.GENERIC_CODE, "", "", "", IBErrorHandler.generateErrorMessage(e)}, c_oClass);
					}
				}
//				if (!DataValidator.isEmptyString (m_sFromAccBranchCode))
//				{System.out.println("m_sFromAccBranchCode="+m_sFromAccBranchCode);
//					m_sFromAccBranchName=IBUtilsExtension.getGoldBranchNameByBranchCode(p_oEnterpriseServices, m_sFromAccBranchCode);
//				}
				
				Map<String,ESBProcessBeanInterface> tranSet=new HashMap<String,ESBProcessBeanInterface>();
				
				
				ESBRequestXapi905Bean tranSetFirst=new ESBRequestXapi905Bean(m_oFromGoldEnquiryBean,
						EnumApplType.CK, EnumAccType.CK_GOLD, m_oToAccEnquiryBean.getAccountNo(),
						m_sAmount, null, m_sEsbDescription, EnumPhoenixTranCode.TRANSFER_WITHDRAWAL ,
						m_sFromAccBranchCode, EnumDepLoan.DEP_DP,"",rimNo);
				
				
				ESBXapi905Agent agent1=new ESBXapi905Agent(tranSetFirst);
				
				tranSet.put("1", agent1);

				
				Map<String, Document> responseMap=new ESBServiceFactoryImpl(m_oSessionObj).implementService(tranSet);
				
				ESBResponseXapi905Bean responseBean905=null;
				boolean isSuccess=false;
				ESBMsgHeader msgResponse=new ESBMsgHeader();
				
				
				for (String mapKey : responseMap.keySet()) {
					Document doc=responseMap.get(mapKey);
					if(doc != null){
						// *** start querying the response code from DOCMENT of transet ***
						Element root = doc.getRootElement ();
						msgResponse = new ESBProcessBean().processResponseCode(root);
//						Element msgHeader = root.element ("MsgHeader");
//						m_sPhx_Ref_no = (msgHeader.elementText ("ReferenceNo"));
						String code=mapKey.substring(mapKey.length()-2, mapKey.length());
						String key=mapKey.substring(0, mapKey.length()-2);	
						
						if(code.equalsIgnoreCase(GoldConstants.ESB_TRANS_SUCCESS) 
								&& ESBConstants.IB_SUCCESS_RC.equalsIgnoreCase(msgResponse.getResponseCode())){
							if(key.equalsIgnoreCase("1")){
								agent1.setDocument(doc);
								responseBean905=agent1.getResponsebean();
							}
							isSuccess=true;
						}else{
							//"*** failed response code **
							isSuccess=false;
							msgResponse.setResponseCode (ESBProcessBean.ESB_FAIL_CODE);
							msgResponse.setErrorMessage (ResourcesUtils.getServiceExceptionErrorKey ("esb.error.phx.PHX-",msgResponse.getResponseCode ()));
							break;
						}
					}else {
						//*** Document is null
						msgResponse.setResponseCode (ESBProcessBean.ESB_FAIL_CODE);
						msgResponse.setErrorMessage (ResourcesUtils.getServiceExceptionErrorKey ("esb.error.phx.PHX-",msgResponse.getResponseCode ()));						
						isSuccess=false;
						break;
					}						
					//!!! Response Code query ended !!!			
				}
				if(responseBean905!=null){
//					String m_sResponseCode = responseBean905.getResponseCode ();
					//		m_sFromAccNewBal = m_oOwnTransfer.getFromAccountBalance ();
					//		m_sToAccNewBal = m_oOwnTransfer.getToAccountBalance ();
					m_sReferenceNo = responseBean905.getTransactionReference();
				}
				if(isSuccess){
				hasReceipt = true;
				m_sStatus = ResourcesUtils.getSuccessful ();
				}
				else //handle the negative testing,status=UNSUCCESSFUL
				{
					m_sStatus = ResourcesUtils.getUnsuccessful ();
					m_sReason = msgResponse.getErrorMessage ();
				}
			}
			}else{// from acc no error
				m_sStatus = ResourcesUtils.getUnsuccessful ();
				if(!m_oTCEnquiryBean.getResponseCode().equals("0000")){
					m_sReason = "\"From Acc No("+m_sFromAccount+")\" from RimNo("+rimNo+") "+m_oTCEnquiryBean.getErrorMessage ();
				}else{
					m_sReason = "Error after getting info from acc no:"+m_sFromAccount;
				}
			}

			System.out.println("m_sStatus, m_sReason: " + m_sStatus + ", "+ m_sReason);

			//get new trnx id
			String m_sTransID = IBUtils.getTransactionId (m_oSessionObj.getDataManager ());
			System.out.println("new trnx id "+m_sTransID);

			if(hasReceipt)
			{
				Map<String, String> m_oReceiptDetails = new LinkedHashMap <String, String> ();
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("receipt.transaction.type"), trnxTypeDisplay);
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.status"), m_sStatus);
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.fromAccount"), m_sFromAccount);
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.toAccount"), m_sToAccount);
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.amount"), FormatterUtils.formatGoldUnitDisplay (m_sAmount, true));

				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.reference.number"), FormatterUtils.formatTransID (m_sTransID));
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.reference"), m_sReferenceNo );

				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.transaction.date"), DateTimeUtils.formatDayMonthYear (m_oCurrentBVIDateTime));
				m_oReceiptDetails.put (ResourcesUtils.getApplicationResourceMessage ("general.transaction.time"), m_oCurrentBVIDateTime.getTime ());

				//insert into table IB_RECEIPT_DETAILS
				IBUtils.loopIntoReceiptDetails (p_oEnterpriseServices, m_oReceiptDetails, m_oCurrentBVIDateTime.getSimpleDate (), m_sTransID);
			}
			System.out.println("start log si history");
			//log into si history
			IBLogger.logSIHistory(p_oEnterpriseServices, rimNo, siId, m_sTransID, m_oCurrentBVIDateTime.getJavaDate (),
					SIConstantsExtension.TRANSCODE_OWN_GOLD_TRANSFER,
					m_sFromAccount, m_sToAccount, fromCurrency, toCurrency,
					m_sAmount,
					"0", // ForeignAmount
					charges,
					m_sSICharges, // SICharges
					m_sStatus,
					m_sReason,
					m_sReferenceNo,// is Auth_code, IB_SI_HISTORY no place to store reference no
					"", // PhxRevRefNo
					false, // PhxRevStatus
					"", // EpayRefNo
					"", // PhxChargeRefNo
					false, // PhxChargeStatus
					"", // PhxChargeRevRefNo
					false, // PhxCharRevStatus
					m_sSIChargesRefNo, // SIChargeRefNo
					m_boSIChargeStatus,
					"", // SIChargeRevRefNo
					false, // SIChargeRevStatus
					"",
					hasReceipt,"","","",false);
			System.out.println("end log si history");
			
			//SMS Notification START
//			SMSServices.sendCustomerSMSForSI (
			String beneName = visitor.getName();
			SMSServiceGold.sendCustomerSMSForSIExtendGold (
					p_oEnterpriseServices, 
					userId, 
					"GOLD", 
					SIConstantsExtension.TRANSCODE_OWN_GOLD_TRANSFER, 
					m_sStatus, 
					m_sTransID, 
					m_sFromAccount, 
					m_sAmount, 
					m_oCurrentBVIDateTime, 
					beneName.length()>14?beneName.substring(0, 14):beneName);
			//SMS Notification END
		}
		catch(Exception e)
		{	e.printStackTrace();
        	if (e instanceof IBGenericException)
            {
                throw (IBGenericException) e;
            }
            throw IBErrorHandler.createServiceException(IBServiceException.GENERAL_SERVICE_ERROR, true,
                    new String[] {CommonErrorCode.GENERIC_CODE, "", "", "", IBErrorHandler.generateErrorMessage(e)}, c_oClass);
		}
		IBLogger.logBSFNMethodLeavingMessage (c_oClass, m_sMethodName, m_oTimer);
	}
}
