package ibase.utility.training;

import java.io.File;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import javax.naming.InitialContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import ibase.ejb.CommonDBAccessEJB;
import ibase.system.config.AppConnectParm;
import ibase.system.config.ConnDriver;
import ibase.utility.BaseLogger;
import ibase.utility.E12GenericUtility;
import ibase.utility.UserInfoBean;
import ibase.webitm.ejb.ActionHandlerEJB;
import ibase.webitm.ejb.DBAccessEJB;
import ibase.webitm.ejb.MasterStatefulLocal;
import ibase.webitm.utility.ITMException;

public class GenerateXml extends ActionHandlerEJB {
	// only calling of methods from actionHandler and creation of userInfo from
	// uerCode
	public String actionHandler(String tranID, String xtraParam, String forceFlag)
			throws RemoteException, ITMException {
		String retVal = "";
		UserInfoBean userInfo = null;
		//
		 String tranId = "ABC123";  
	        String formattedResult = generateFormattedTranId(tranId);
	        System.out.println(formattedResult);

		//

		BaseLogger.log("3", null, null, "Inside actionHandler.. ");
		BaseLogger.log("3", null, null, "Inside actionHandler.. tranID[ " + tranID + "]"); // P2BPH0125
		BaseLogger.log("3", null, null, "Inside actionHandler.. xtraParam" + xtraParam);
		BaseLogger.log("3", null, null, "Inside actionHandler.. forceFlag" + forceFlag);

		E12GenericUtility e12GenericUtility = new E12GenericUtility();
		CommonDBAccessEJB commonDBAccessEJB = new CommonDBAccessEJB();
		
		String refser = "";

		DBAccessEJB dbAccessEJB = new DBAccessEJB();
		
		try {
			String userCode = e12GenericUtility.getValueFromXTRA_PARAMS(xtraParam, "loginCode");
			userInfo = commonDBAccessEJB.createUserInfo(userCode);
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		
		try {
			refser = dbAccessEJB.getDBColumnValue("TRANSETUP", "REF_SER", "TRAN_WINDOW  = 'w_misc_pay'",
					userInfo.getTransDB());
			BaseLogger.log("3", null, null, "Value of refser... [" + refser + "]");

		} catch (RemoteException | ITMException e) {
			e.printStackTrace();
		}

		

		String firstAcknowledgementFilePath = "/wildfly/BankIntegration/From HSBC/ACK1PSRV3.PC000019210.SS210026.20210823070047001.XML";

		String idFrom1stAcknowledgement = getAcknowledgmentTagValue(firstAcknowledgementFilePath, "Id", "Othr");
		BaseLogger.log("3", null, null, "idFrom1stAcknowledgement[" + idFrom1stAcknowledgement + "]");

		String grpStsFrom1stAcknowledgement = getAcknowledgmentTagValue(firstAcknowledgementFilePath, "GrpSts", "");
		BaseLogger.log("3", null, null, "grpStsFrom2ndAcknowledgement[" + grpStsFrom1stAcknowledgement + "]");
		
		try {
			// here we have to call the updatePaymentStatus method for first acknowledgement
			String transXMLFor1stAcknowldgement = getTransXML(idFrom1stAcknowledgement, refser, "1st Acknowledgement Received", grpStsFrom1stAcknowledgement , "");
			updatePaymentStatus(tranID, transXMLFor1stAcknowldgement, userInfo);
			
			String secondAcknowledgementFilePath = "/wildfly/BankIntegration/From HSBC/ACK2PSRV3.PC000019210.SS210026.20210823070120002.XML";
			
			String idFrom2ndAcknowledgement = getAcknowledgmentTagValue(secondAcknowledgementFilePath, "Id", "Othr");
			BaseLogger.log("3", null, null, "idFrom2ndAcknowledgement[" + idFrom2ndAcknowledgement + "]");
			
			String txstsFrom2ndAcknowledgement = getAcknowledgmentTagValue(secondAcknowledgementFilePath, "TxSts", "");
			BaseLogger.log("3", null, null, "grpStsFrom2ndAcknowledgement[" + txstsFrom2ndAcknowledgement + "]");
			
			// here we have to call the updatePaymentStatus method for second acknowledgement
			String transXMLFor2ndAcknowldgement = getTransXML(idFrom2ndAcknowledgement, refser, "2nd Acknowledgement Received", txstsFrom2ndAcknowledgement , "");
			updatePaymentStatus(tranID, transXMLFor2ndAcknowldgement, userInfo);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return retVal;
	}

	// Method to update Payment Status, this method will get called from Confirm
	// Action of misc_pay.
	// Thr is a need to be called from other places as well as while receiving the
	// staus update from Bank, So need to ensure this accomodates that as well
	// Mostly may get called from Scheduler - thr user may be the generic here,
	// but while calling from action user will be the person who called the
	// confirmation
	//  maine is method me transXML as a paramter add kyu kiya?
	private void updatePaymentStatus(String tranID, String transXML, UserInfoBean userInfo) throws Exception {
		Connection connection = null;
		BaseLogger.log("3", null, null, "Inside updatePaymentStatus.. ");

		try {
			AppConnectParm appConnect = new AppConnectParm();
			InitialContext initialContext = new InitialContext(appConnect.getProperty());

			ConnDriver connDriver = new ConnDriver();
			connection = connDriver.getConnectDB(userInfo.getTransDB());

			StringBuffer processDynXmlString = new StringBuffer();
			processDynXmlString.append("<DocumentRoot><description>Datawindow Root</description><group0>");
			processDynXmlString.append(
					"<description>Group0 description</description><Header0><description>Header0 members</description>");
			processDynXmlString.append("<objName><![CDATA[payintstatus]]></objName>");
			processDynXmlString.append("<pageContext><![CDATA[1]]></pageContext>");
			processDynXmlString.append("<objContext><![CDATA[1]]></objContext>");
			processDynXmlString.append("<editFlag><![CDATA[A]]></editFlag>");
			processDynXmlString.append("<focusedColumn><![CDATA[]]></focusedColumn>");
			processDynXmlString.append("<action><![CDATA[SAVE]]></action>");
			processDynXmlString.append("<elementName><![CDATA[]]></elementName>");
			processDynXmlString.append("<keyValue><![CDATA[1]]></keyValue>");
			processDynXmlString.append("<saveLevel><![CDATA[1]]></saveLevel>");
			processDynXmlString.append("<forcedSave><![CDATA[false]]></forcedSave>");
			processDynXmlString.append("<Detail1 dbID='' domID='1'  objContext='1'  objName='payintstatus'>");
			processDynXmlString
					.append("<attribute IS_CHANGE='Y' pkNames='TRAN_ID' selected='N' status='N' updateFlag='A'/>");

			processDynXmlString.append(transXML);

			processDynXmlString.append("</Detail1>");
			processDynXmlString.append("</Header0></group0></DocumentRoot>");
			String XmlString = processDynXmlString.toString();
			BaseLogger.log("3", null, null, " Xml String... " + XmlString);

			// call the process request here
			MasterStatefulLocal masterStateful = (MasterStatefulLocal) initialContext
					.lookup("ibase/MasterStatefulEJB/local");
			String reString = masterStateful.processRequest(getUserInfo(), XmlString, false, connection); // userInfo
																											// --pass
			BaseLogger.log("3", null, null, "reString.. " + reString);

		} catch (Exception e) {
			throw e;
		} finally {
			try {
//                if(rs != null)
//                {
//                    rs.close();
//                    rs = null;
//                }
//                if(pstmt != null)
//                {
//                    pstmt.close();
//                    pstmt = null;
//                }
				if (connection != null) {
					connection.close();
					connection = null;
				}
			} catch (Exception e) {
				e.getMessage();
			}
		}

	}

	/*
	 * 
	 * */
	private String getTransXML(String paymentTranID, String refSer, String descr, String remarks, String errorDet) {
		// Need to generate XML for payIntStatus
		StringBuffer transXML = new StringBuffer();

		try {
			E12GenericUtility e12genericUtility = new E12GenericUtility();
			SimpleDateFormat sdf = new SimpleDateFormat(e12genericUtility.getApplDateFormat());
			String currentDateStr = sdf.format(new java.util.Date());
			currentDateStr = e12genericUtility.getValidDateTimeString(currentDateStr,
					e12genericUtility.getApplDateFormat(), e12genericUtility.getDBDateFormat());
			BaseLogger.log("3", null, null, "Value of currentDateStr... [" + currentDateStr + "]");

			// transXML.append("<tran_id><![CDATA[]]></tran_id>");
			// transXML.append("<TRAN_ID><![CDATA[gsb]]></TRAN_ID>");
			transXML.append("<ref_ser><![CDATA[" + refSer + "]]></ref_ser>");
			transXML.append("<ref_id><![CDATA[" + paymentTranID + "]]></ref_id>");
			transXML.append("<status_date><![CDATA[" + getCurrentDate() + "]]></status_date>");
			transXML.append("<stage_descr><![CDATA[" + descr + "]]></stage_descr>");
			transXML.append("<remarks><![CDATA[" + remarks + "]]></remarks>");
			transXML.append("<error_det><![CDATA[" + errorDet + "]]></error_det>");

		} catch (Exception e) {
			e.getMessage();
		}
		return transXML.toString();

	}

	public static String getCurrentDate() {
		BaseLogger.log("3", null, null, "inside getCurrentDate .. ");

//		LocalDate currentDate = LocalDate.now();
//		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yy");
//		BaseLogger.log("3", null, null, "currentDate is .. [" + currentDate.format(formatter) + "]");
//		return currentDate.format(formatter);
		LocalDateTime currentDateTime = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yy HH:mm:ss");
		BaseLogger.log("3", null, null, "currentDateTime is .. [" + currentDateTime.format(formatter) + "]");
		return currentDateTime.format(formatter);

	}

//11 dec

	private static String getElementValueByTagName(Document document, String tagName) {
		NodeList nodeList = document.getElementsByTagName(tagName);
		if (nodeList.getLength() > 0) {
			Element element = (Element) nodeList.item(0);
			return element.getTextContent();
		} else {
			return null; // Tag not found
		}
	}

	private static String getElementValue(Element parentElement, String parentTagName, String tagName) {
		// Find the specified element using XPath under the specified parent element
		NodeList parentNodes = parentElement.getElementsByTagName(parentTagName);

		for (int i = 0; i < parentNodes.getLength(); i++) {
			Element parent = (Element) parentNodes.item(i);

			// Find the specified element under the parent
			NodeList nodeList = parent.getElementsByTagName(tagName);

			// Iterate through the elements to find the one under the specified parent
			for (int j = 0; j < nodeList.getLength(); j++) {
				Element element = (Element) nodeList.item(j);

				// Get the text content of the element
				return element.getTextContent();
			}
		}

		// Return null if the element is not found
		return null;
	}

	// method to get values of tags from acknowledgement file provided by bank.
	public static String getAcknowledgmentTagValue(String filePath, String tagName, String parentTagName) {
		String result = "";
		BaseLogger.log("3", null, null, "Inside checkFirstAcknowledgement method filePath [" + filePath + "]");
		BaseLogger.log("3", null, null, "Inside checkFirstAcknowledgement method tagName [" + tagName + "]");

		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(new File(filePath));

			BaseLogger.log("3", null, null,
					"Acknowledgement document:[" + E12GenericUtility.documentToString(document) + "]");

			if (parentTagName.equalsIgnoreCase("")) {
				result = getElementValueByTagName(document, tagName);
			} else {
				Element rootElement = document.getDocumentElement();
				System.out.println("Root Element gsb: " + document.getDocumentElement().getTagName());

				result = getElementValue(rootElement, parentTagName, tagName);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		BaseLogger.log("3", null, null, "result from getAcknowledgmentTagValue:[" + result + "]");
		return result;
	}
	public static String generateFormattedTranId(String tranId) {
        Date currentDate = new Date();

        SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyyHHmmss");
        String formattedDate = dateFormat.format(currentDate);

        String formattedTranId = tranId + formattedDate;
		BaseLogger.log("3", null, null, " value of formattedTranId [" + formattedTranId + "]");

        return formattedTranId;
    }

}