package ibase.communication.whatsApp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.rmi.RemoteException;
import java.security.Key;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;

import org.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

import ibase.bean.ExtAuthApplicationBean;
import ibase.communication.telegram.Utils;
import ibase.ejb.CommonDBAccessEJB;
//import ibase.communication.WhatsAppWebhook;
import ibase.system.config.ConnDriver;
import ibase.utility.BaseLogger;
import ibase.utility.E12GenericUtility;
import ibase.utility.UserInfoBean;
import ibase.webitm.ejb.DBAccessEJB;
import ibase.webitm.utility.APIUtility;
import ibase.webitm.utility.ITMException;
import ibase.webitm.utility.RestAPIServiceUtility;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class WhatsAppBotUtility {
    
    DBAccessEJB dbAccessEJB = new DBAccessEJB();
    List<String> whatsAppBOTMenuList = new ArrayList<String>();
    private static final ObjectMapper objectMapper = new ObjectMapper();
    WhatsAppBotConfig waBotConfig = null;
    StringBuilder content = new StringBuilder();
    String userTokenID = "";
    
    public String handleWhatsAppRequest(HttpServletRequest request, String requestBody, String enterprise) throws ITMException {
        try {
            // Parse the incoming WhatsApp message
        	BaseLogger.log("3", null, null,"[WhatsAppBotUtility] enterprise:::::::::::"+enterprise);
            WhatsAppWebhookUpdate whatsAppMessage = objectMapper.readValue(requestBody, WhatsAppWebhookUpdate.class);
            
            // Extract message details
            String userPhone = whatsAppMessage.getSender();
            String integratedNumber = whatsAppMessage.getIntegrated_number();
            String userName = getUserName(whatsAppMessage);
            String messageId = whatsAppMessage.getMessage_uuid();
            String userMsg = extractUserMessage(whatsAppMessage);
            
            
            UserInfoBean userInfo = createEntityWiseUserInfo(userPhone,messageId,enterprise);
            // Log basic message info
            
            BaseLogger.log("3", null, null, 
                "[WhatsAppBotUtility] Received message from AjitDeshmukhRa" + userPhone + 
                " (Name: " + userName + "): " + userMsg+ "integratedNumber:: "+ integratedNumber);
            
            // Get or create chat data for this conversation
            HashMap<String, Object> chatData = ChatDataManager.getChatData(messageId);
            
            // Get intent ID from chat data or use default
            String intentID = chatData.containsKey("INTENT_ID") ? 
                (String) chatData.get("INTENT_ID") : "";
            
            
            // Build intent parameters dynamically
            String intentParams = buildIntentParameters(
                intentID, 
                userMsg, 
                userPhone, 
                messageId, 
                userInfo,
                chatData
            );
            
            // Call the intent service
            String intentResponse = callIntentService(request, intentParams, enterprise, whatsAppMessage, userInfo);
            BaseLogger.log("0", null, null, "[WhatsAppBotUtility] intentResponse " + intentResponse);
            String visionReponse = "";
            // Added parseVisionAssistantResponseJSON method in try catch block to handle the exception
            try {
                visionReponse = parseVisionAssistantResponseJSON(intentResponse, messageId);
                BaseLogger.log("0", null, null, "[WhatsAppBotUtility] visionReponse (raw): " + visionReponse);
            } catch (Exception e) {
                BaseLogger.log("0", null, null, "[WhatsAppBotUtility] ERROR in parseVisionAssistantResponseJSON: " + e.getMessage());
                e.printStackTrace();
                return "Failed to parse intent response";
            }
 
         
         BaseLogger.log("0", null, null, "[WhatsAppBotUtility] visionReponse (sanitized): " + visionReponse);
            sendWhatsAppReply(integratedNumber, userPhone, visionReponse);
            return visionReponse;
            
        } catch (Exception e) {
            BaseLogger.log("0", null, null, 
                "[WhatsAppBotUtility] Error processing WhatsApp request: " + e.getMessage());
            e.printStackTrace();
            return "Error processing your request";
        }
    }
    
    private String getUserName(WhatsAppWebhookUpdate message) {
        // Extract user name from contacts if available
        if (message.getContacts() != null && !message.getContacts().isEmpty()) {
            if (message.getContacts().get(0).getProfile() != null) {
                return message.getContacts().get(0).getProfile().getName();
            }
        }
        return "Unknown";
    }
    
    private String extractUserMessage(WhatsAppWebhookUpdate message) {
        // Extract message text from different possible locations
        if (message.getText() != null) {
            return message.getText();
        }
        if (message.getMessages() != null && !message.getMessages().isEmpty()) {
            if (message.getMessages().get(0).getText() != null) {
                return message.getMessages().get(0).getText().getBody();
            }
        }
        return "";
    }
      
    public boolean isChatIdExists(String chatId, String enterprise) {
		System.out.println("Inside isChatIdExists ");
		Connection conn = null;
		ConnDriver connDriver = new ConnDriver();
		try {
			conn = connDriver.getConnectDB("Driver");
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		String sql = "SELECT COUNT(*) FROM USER_ACC_CHANNEL WHERE CHANNEL_UUID = ? AND ENTERPRISE_ID = ?";
		try (PreparedStatement stmt = conn.prepareStatement(sql)) {
			stmt.setString(1, chatId);
			stmt.setString(2, enterprise);
			try (ResultSet rs = stmt.executeQuery()) {
				if (rs.next()) {
					int count = rs.getInt(1);

					DBAccessEJB dbAccessEJB = new DBAccessEJB();
					try {
						String tokenId = dbAccessEJB.getDBColumnValue("USER_ACC_CHANNEL", "TOKEN_ID",
								(" CHANNEL_UUID = '" + chatId + "' AND ENTERPRISE = '"+ enterprise +"'"), "Driver");
						userTokenID = tokenId;
					} catch (RemoteException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (ITMException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					return count > 0;
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		System.out.println("Inside isChatIdExists:: chat id does not exist");
		return false;
	}
    
    private String buildIntentParameters(
            String intentID, 
            String userMsg, 
            String userPhone, 
            String messageId,
            UserInfoBean userInfo,
            HashMap<String, Object> chatData) {
        
        JSONObject jsonObject = new JSONObject();
        String encodedIntentParamJSONStr = "";
        // Basic parameters
//        jsonObject.put("BIS_INTENT_ID", intentID);
        jsonObject.put("BIS_INTENT_ID", "");
        jsonObject.put("identity", String.valueOf(System.currentTimeMillis()));
        jsonObject.put("USER_MSG", userMsg);
        jsonObject.put("IS_BROWSER", true); // For WhatsApp, typically false
        jsonObject.put("INPUT_TEXT", userMsg);
        jsonObject.put("USER_ID", userInfo.getLoginUserId()); // Using phone as user ID
        jsonObject.put("UUID", messageId);
        
        // Add any additional parameters from chat data
        if (chatData != null) {
            for (String key : chatData.keySet()) {
                if (!key.equals("INTENT_ID")) { // Skip INTENT_ID as we already have it
                    jsonObject.put(key, chatData.get(key));
                }
            }
        }
        
        // Add user info parameters
//        jsonObject.put("ENTERPRISE", userInfo.getEnterprise());
//        jsonObject.put("TRANS_DB", userInfo.getTransDB());
        
        BaseLogger.log("3", null, null,
            "[WhatsAppBotUtility] Built intent parameters: " + jsonObject.toString());
        String intentParamJSONStr = jsonObject.toString();
        BaseLogger.log("3", null, null,
				"[WhatsAppBotUtility] : Incoming intentParamJSONStr[" + intentParamJSONStr+"]");
        try {
			 encodedIntentParamJSONStr = URLEncoder.encode(intentParamJSONStr, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
        return encodedIntentParamJSONStr;
    }
    
    public String callIntentService(HttpServletRequest request, String intendParams, String enterprise, WhatsAppWebhookUpdate update, UserInfoBean userInfo) {
        try {
            String tokenId = userInfo.getTokenID();
            System.out.println("TokenId for invokeIntent::" + tokenId);
            System.out.println("enterprise for invokeIntent::" + enterprise);
			Utils util = new Utils(tokenId);
            String serverBaseURL = util.getServerIP(request);
            System.out.println("serverBaseURL::" + serverBaseURL);
            String endpointUrl = serverBaseURL+"/ibase/rest/BISService/invokeIntent?INTENT_PARAM=" + intendParams;
            URL url = new URL(endpointUrl);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            // Set headers
            con.setRequestMethod("POST");
            con.setRequestProperty("TOKEN_ID", tokenId);
            con.setRequestProperty("Content-Type", "application/json");
            con.setDoOutput(true);

            int responseCode = con.getResponseCode();
            InputStream inputStream;

            if (responseCode >= 200 && responseCode < 300) {
                inputStream = con.getInputStream();
            } else {
                inputStream = con.getErrorStream();  // <-- Handle error XML here
            }

            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder content = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                content.append(inputLine);
            }
            in.close();
            con.disconnect();

            String response = content.toString();
            System.out.println("Vision Assistant Response: " + response);

            return response;

        } catch (Exception e) {
            e.printStackTrace();
            return "Exception occurred: " + e.getMessage();
        }

    }


    

   

    
    public static String parseVisionAssistantResponseJSON(String response, String chatID) {
		// Parse JSON
		JsonObject jsonObject = new Gson().fromJson(response, JsonObject.class);

		if (jsonObject.has("Response") && jsonObject.getAsJsonObject("Response").has("results")) {
			JsonObject results = jsonObject.getAsJsonObject("Response").getAsJsonObject("results");
			
			String intentID = jsonObject.getAsJsonObject("Response").get("intent_id").getAsString();
			String intentDescr = jsonObject.getAsJsonObject("Response").get("intent_descr").getAsString();

			if (results.has("Root") && results.getAsJsonObject("Root").has("Detail")) {
				JsonObject detailObject = results.getAsJsonObject("Root").getAsJsonObject("Detail");

				JsonElement resultElement = detailObject.get("result");
				if (resultElement != null && resultElement.isJsonObject()) {
					JsonObject resultObject = resultElement.getAsJsonObject();
					JsonElement dataElement = resultObject.get("data");

					// Handling rows and cols
					if (resultObject.has("data") && resultObject.get("data").isJsonArray()) {
						JsonArray dataArray = resultObject.getAsJsonArray("data");
						if (dataArray.size() > 0 && dataArray.get(0).isJsonObject()) {
							JsonObject dataObject = dataArray.get(0).getAsJsonObject();

							if (dataObject.has("rows") && dataObject.has("cols")) {
								JsonArray rows = dataObject.getAsJsonArray("rows");
								JsonArray cols = dataObject.getAsJsonArray("cols");

								StringBuilder textBuilder = new StringBuilder();
//								for (JsonElement row : rows) {
//									JsonArray rowData = row.getAsJsonArray();
//									for (int i = 0; i < cols.size(); i++) {
//										String columnName = cols.get(i).getAsString();
//										String value = rowData.get(i).getAsString();
//
//										textBuilder.append(columnName).append(": ").append(value).append("\n");
//									}
//									textBuilder.append("\n");
//								}
								for (JsonElement row : rows) {
									JsonArray rowData = row.getAsJsonArray();
									for (int i = 0; i < cols.size(); i++) {
										String columnName = cols.get(i).getAsString();
										String value = "";
										if (i < rowData.size()) {
											JsonElement cell = rowData.get(i);
											value = (cell != null && !cell.isJsonNull()) ? cell.getAsString() : "";
										}
										textBuilder.append(columnName).append(": ").append(value).append("\n");
									}
									textBuilder.append("\n");
								}

								return textBuilder.toString();
							}
						}
					} else if (dataElement != null && dataElement.isJsonPrimitive()) {
						String dataElementString = dataElement.getAsString().replaceAll("^\"|\"$", "");

						System.out.println(dataElementString);

						if (isJsonObject(dataElementString)) {
							try {
								JsonObject dataObject = new JsonParser().parse(dataElementString).getAsJsonObject();

								if (dataObject.has("Root")) {
									JsonObject rootData = dataObject.getAsJsonObject("Root");

									if (rootData.has("Detail")) {
										JsonElement detailElement = rootData.get("Detail");

										if (detailElement.isJsonPrimitive()) {
											String detailValue = detailElement.getAsString();
											if ("Success".equals(detailValue)) {
												JsonElement tranIDElement = rootData.get("TranID");
												if (tranIDElement != null && tranIDElement.isJsonPrimitive()) {
													String tranID = tranIDElement.getAsString();
													return "Transaction is saved. Transaction ID: " + tranID;
												}
											}
										}
									} else if (dataElement.isJsonArray()) {
										JsonArray dataArray = results.getAsJsonObject("Root").getAsJsonObject("Detail")
												.getAsJsonObject("result").getAsJsonArray("data");
										StringBuilder textBuilder = new StringBuilder();
										for (JsonElement element : dataArray) {
											JsonObject entry = element.getAsJsonObject();
											JsonArray rows = entry.getAsJsonArray("rows");
											JsonArray cols = entry.getAsJsonArray("cols");

//											for (JsonElement row : rows) {
//												JsonArray rowData = row.getAsJsonArray();
//												for (int i = 0; i < cols.size(); i++) {
//													String columnName = cols.get(i).getAsString();
//													String value = rowData.get(i).getAsString();
//
//													textBuilder.append(columnName).append(": ").append(value)
//															.append("\n");
//												}
//												textBuilder.append("\n");
//											}
											for (JsonElement row : rows) {
												JsonArray rowData = row.getAsJsonArray();
												for (int i = 0; i < cols.size(); i++) {
													String columnName = cols.get(i).getAsString();
													String value = "";
													if (i < rowData.size()) {
														JsonElement cell = rowData.get(i);
														value = (cell != null && !cell.isJsonNull()) ? cell.getAsString() : "";
													}
													textBuilder.append(columnName).append(": ").append(value).append("\n");
												}
												textBuilder.append("\n");
											}

										}
										return textBuilder.toString();
									}
								}

							} catch (JsonSyntaxException e) {
								// Handle JSON parsing exception
								e.printStackTrace();
								return "Error parsing inner JSON.";
							}
						} else {
							return dataElementString;
						}
					}
				}
			} else if (results.has("Root") && results.getAsJsonObject("Root").has("Errors")) {
				JsonObject error = results.getAsJsonObject("Root").getAsJsonObject("Errors").getAsJsonObject("error");
				String description = error.get("description").getAsString();
				String id = error.get("@id").getAsString();
				String message = error.get("message").getAsString();
				
				System.out.println("id in parseVisionAssistantResponse: [" + id +"]");
				System.out.println("message in parseVisionAssistantResponse: [" + message +"]");
				System.out.println("intentID in parseVisionAssistantResponse: [" + intentID +"]");
				
				if (id.equals("INVINTARG")) {
					putDataIntoChatDataMap(chatID, "INVINTARG", "true");
					putDataIntoChatDataMap(chatID, "INTENT_ID", intentID);
					putDataIntoChatDataMap(chatID, "INTENT_DESCR", intentDescr);
				}

				// Changes by Gagan B. on 18-APR-24 [Adding trace's value if present while
				// parsing assistants JSON] -- START
				if (error.has("trace")) {
					String trace = error.get("trace").getAsString();
					description = description + " " + trace;
				}
				// Changes by Gagan B. on 18-APR-24 [Adding trace's value if present while
				// parsing assistants JSON] -- END

				return description;
			}
		}
		return "No data available.";
	}
    
    public static boolean isJsonObject(String jsonString) {
		try {
			JsonParser parser = new JsonParser();
			parser.parse(jsonString).getAsJsonObject();
			return true;
		} catch (Exception e) {
			return false;
		}
	}
    
	public static void putDataIntoChatDataMap(String chatId, String key, Object value) {

		// Access chatDataMap from ChatDataManager and put data into it
		HashMap<String, Object> chatData = ChatDataManager.getChatData(chatId);
		chatData.put(key, value);
	}
    


	
//	//for content type as "text"
	public void sendWhatsAppReply(String integratedNumber, String userPhoneNumber, String replyText) {
	    try {
	        System.out.println("In sendWhatsAppTextMessage method::::");
	        System.out.println("In sendWhatsAppTextMessage method integratedNumber::::"+integratedNumber);

	        // URL encode the message text
	        String encodedText = URLEncoder.encode(replyText, "UTF-8");

	        String url = "https://control.msg91.com/api/v5/whatsapp/whatsapp-outbound-message/"
	                   + "?integrated_number=" + integratedNumber
	                   + "&recipient_number=" + userPhoneNumber
	                   + "&content_type=text"
	                   + "&text=" + encodedText;

	        HttpResponse<String> response = Unirest.post(url)
	                .header("authkey", "120652AIh8u6Gr665aba7a1P1")
	                .header("accept", "application/json")
	                .header("content-type", "application/json")
	                .asString();

	        System.out.println("Response Code: " + response.getStatus());
	        System.out.println("Response Body: " + response.getBody());

	    } catch (Exception e) {
	        System.err.println("Exception occurred while sending WhatsApp text message:");
	        e.printStackTrace();
	    }
	}

//	public void sendWhatsAppReply(String integratedNumber, String userPhoneNumber, String... templateVariables) {
//	    try {
//	        // Build components JSON dynamically
//	        StringBuilder componentsBuilder = new StringBuilder();
//	        componentsBuilder.append("{");
//	        for (int i = 0; i < templateVariables.length; i++) {
//	            String bodyKey = "\"body_" + (i + 1) + "\"";
//	            componentsBuilder.append(bodyKey)
//	                             .append(": {")
//	                             .append("\"type\": \"text\", ")
//	                             .append("\"value\": \"").append(templateVariables[i]).append("\"")
//	                             .append("}");
//	            if (i < templateVariables.length - 1) {
//	                componentsBuilder.append(", ");
//	            }
//	        }
//	        componentsBuilder.append("}");
//
//	        // Build full JSON payload
//	        String jsonBody = "{"
//	            + "\"integrated_number\": \"" + integratedNumber + "\","
//	            + "\"content_type\": \"template\","
//	            + "\"payload\": {"
//	                + "\"type\": \"template\","
//	                + "\"template\": {"
//	                    + "\"name\": \"survey_sept\","
//	                    + "\"language\": {"
//	                        + "\"code\": \"en\","
//	                        + "\"policy\": \"deterministic\""
//	                    + "},"
//	                    + "\"to_and_components\": ["
//	                        + "{"
//	                            + "\"to\": [\"" + userPhoneNumber + "\"],"
//	                            + "\"components\": " + componentsBuilder.toString()
//	                        + "}"
//	                    + "]"
//	                + "},"
//	                + "\"messaging_product\": \"whatsapp\""
//	            + "}"
//	        + "}";
//
//	        System.out.println("Request JSON: " + jsonBody);
//
//	        HttpResponse<String> response = Unirest.post("https://control.msg91.com/api/v5/whatsapp/whatsapp-outbound-message/bulk/")
//	            .header("authkey", "120652AIh8u6Gr665aba7a1P1")
//	            .header("accept", "application/json")
//	            .header("content-type", "application/json")
//	            .body(jsonBody)
//	            .asString();
//
//	        System.out.println("Response Code: " + response.getStatus());
//	        System.out.println("Response Body: " + response.getBody());
//
//	    } catch (Exception e) {
//	        System.err.println("Exception while sending WhatsApp bulk template message:");
//	        e.printStackTrace();
//	    }
//	}

	
	public UserInfoBean createEntityWiseUserInfo(String userPhoneNumber, String chatId, String enterprise) {
	    UserInfoBean userInfo = null;
	    Connection conn = null;
	    PreparedStatement pstmt = null;
	    ResultSet rs = null;
	    APIUtility apiUtility = new APIUtility();
	   // userPhoneNumber = "91"+userPhoneNumber;
	    userPhoneNumber = userPhoneNumber.substring(2, 12);

	    BaseLogger.log("3", null, null, "[WhatsAppBotUtility] ::: Entered createEntityWiseUserInfo | userPhoneNumber=[" + userPhoneNumber + "], chatId=[" + chatId + "], enterprise=[" + enterprise + "]");

	    try {
	    	RestAPIServiceUtility restapiserviceutility = new RestAPIServiceUtility();
			ExtAuthApplicationBean applicationBean = restapiserviceutility.getCommonDBAccess().getExtAuthApplicationInfo("TLG_APPVIS");
	        ConnDriver connDriver = new ConnDriver();
	        conn = connDriver.getConnectDB("Driver");

	        // 1. Check in users table
	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : Checking in users table");
	        String userSql = "SELECT code FROM users WHERE mobile_no = ?";
	        pstmt = conn.prepareStatement(userSql);
	        pstmt.setString(1, userPhoneNumber);
	        rs = pstmt.executeQuery();
	        if (rs.next()) {
	            String userCode = rs.getString("code");
	            BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : User found in users table with code=[" + userCode + "]");
	            CommonDBAccessEJB commonDBAccessEJB = new CommonDBAccessEJB();
	            userInfo = commonDBAccessEJB.createUserInfo(userCode);
	    	    BaseLogger.log("3", null, null, "[WhatsAppBotUtility] ::: Entered createEntityWiseUserInfo | userInfo" + userInfo.toString() + "]");
	    	    userInfo.setTokenID(createBase64EncodedPermanentJWTWithAppId("",userInfo));
	            return userInfo;
	        }
	        rs.close();
	        pstmt.close();

	        // 2. Check in customer table
	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : Checking in customer table");
	        String custSql = "SELECT cust_code FROM customer WHERE tele1 = ? OR tele2 = ? OR tele3 = ?";
	        pstmt = conn.prepareStatement(custSql);
	        pstmt.setString(1, userPhoneNumber);
	        pstmt.setString(2, userPhoneNumber);
	        pstmt.setString(3, userPhoneNumber);
	        rs = pstmt.executeQuery();
	        if (rs.next()) {
	            String custCode = rs.getString("cust_code");
	            BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : User found in customer table with cust_code=[" + custCode + "]");
	            userInfo = apiUtility.getEntityUserInfo(custCode, null, "C", enterprise, chatId);
	            userInfo.setTokenID(createBase64EncodedPermanentJWTWithAppId("",userInfo));
	    	    BaseLogger.log("3", null, null, "[WhatsAppBotUtility] ::: Entered createEntityWiseUserInfo | userInfo" + userInfo.toString() + "]");

	            return userInfo;
	        }
	        rs.close();
	        pstmt.close();

	        // 3. Check in supplier table
	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : Checking in supplier table");
	        String suppSql = "SELECT supp_code FROM supplier WHERE tele1 = ? OR tele2 = ? OR tele3 = ?";
	        pstmt = conn.prepareStatement(suppSql);
	        pstmt.setString(1, userPhoneNumber);
	        pstmt.setString(2, userPhoneNumber);
	        pstmt.setString(3, userPhoneNumber);
	        rs = pstmt.executeQuery();
	        if (rs.next()) {
	            String suppCode = rs.getString("supp_code");
	            BaseLogger.log("3", null, null, "[WhatsAppBotUtility] ::::::: User found in supplier table with supp_code=[" + suppCode + "]");
	            userInfo = apiUtility.getEntityUserInfo(suppCode, null, "S", enterprise, chatId);
	            userInfo.setTokenID(createBase64EncodedPermanentJWTWithAppId("",userInfo));

	            return userInfo;
	        }
	        rs.close();
	        pstmt.close();

	        // 4. Check in STRG_CUSTOMER table
	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : Checking in STRG_CUSTOMER table");
	        String strgSql = "SELECT sc_code FROM STRG_CUSTOMER WHERE mobile_no = ?";
	        pstmt = conn.prepareStatement(strgSql);
	        pstmt.setString(1, userPhoneNumber);
	        rs = pstmt.executeQuery();
	        if (rs.next()) {
	            String scCode = rs.getString("sc_code");
	            BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : User found in STRG_CUSTOMER table with sc_code=[" + scCode + "]");
	            userInfo = apiUtility.getEntityUserInfo(scCode, null, "G", enterprise, chatId);
	            userInfo.setTokenID(createBase64EncodedPermanentJWTWithAppId("",userInfo));
	    	    BaseLogger.log("3", null, null, "[WhatsAppBotUtility] ::: Entered createEntityWiseUserInfo | userInfo" + userInfo.toString() + "]");

	            return userInfo;
	        }
	        rs.close();
	        pstmt.close();

	        // 5. Check in transporter table
	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : Checking in transporter table");
	        String tranpSql = "SELECT tran_code FROM transporter WHERE tele1 = ? OR tele2 = ? OR tele3 = ?";
	        pstmt = conn.prepareStatement(tranpSql);
	        pstmt.setString(1, userPhoneNumber);
	        pstmt.setString(2, userPhoneNumber);
	        pstmt.setString(3, userPhoneNumber);
	        rs = pstmt.executeQuery();
	        if (rs.next()) {
	            String tranCode = rs.getString("tran_code").trim();
	            BaseLogger.log("3", null, null, "[WhatsAppBotUtility] :::::: User found in transporter table with tran_code=[" + tranCode + "]");
	            userInfo = apiUtility.getEntityUserInfo(tranCode, applicationBean, "T", enterprise, chatId);
	            userInfo.setTokenID(createBase64EncodedPermanentJWTWithAppId("",userInfo));
	            System.out.println("tokenId for transporter::"+userInfo.getTokenID());

	            return userInfo;
	        }

	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : No matching record found in any table for phone number [" + userPhoneNumber + "]");

	    } catch (Exception e) {
	        BaseLogger.log("3", null, null, "[WhatsAppBotUtility] : Exception in createEntityWiseUserInfo | Msg=[" + e.getMessage() + "]");
	        e.printStackTrace();
	    } finally {
	        try { if (rs != null) rs.close(); } catch (Exception e) {}
	        try { if (pstmt != null) pstmt.close(); } catch (Exception e) {}
	        try { if (conn != null) conn.close(); } catch (Exception e) {}
	    }

	    return userInfo;
	}

	public static String createBase64EncodedPermanentJWTWithAppId(String appId, UserInfoBean userBean) {
		String base64EncodedJWT = "";

		try {
			// ExtAuthRespBean userBean =new
			// CommonDBAccessEJB().getExtAuthRespBean(userCode);
			//UserInfoBean userBean = new CommonDBAccessEJB().createUserInfo(userCode);

			BaseLogger.log("3", null, null, "CryptographyUtil :: createBase64EncodedJWT");
			BaseLogger.log("3", null, null, "CryptographyUtil :: Got userBean=" + userBean);
			// The JWT signature algorithm to sign the token
			SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

			BaseLogger.log("3", null, null, "CryptographyUtil :: createBase64EncodedJWT : Sign JWT with secret key");
			// Sign JWT with secret key
			byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("a3edd11a09ea4e0ccd09c6cd2828021b");

			Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

			BaseLogger.log("3", null, null,
					"CryptographyUtil :: createBase64EncodedJWT : Creating JWT with secret key");
			// Set the user details in JWT token
			JwtBuilder builder = Jwts.builder().setId(userBean.getLoginCode()).signWith(signatureAlgorithm, signingKey)
					.claim("applicationId", E12GenericUtility.checkNull(appId))
					.claim("loginCode", E12GenericUtility.checkNull(userBean.getLoginCode()))
					.claim("loginUserId", E12GenericUtility.checkNull(userBean.getLoginUserId()))
					.claim("loginMobileNo", E12GenericUtility.checkNull(userBean.getLoginMobileNo()))
					.claim("loginEmailId", E12GenericUtility.checkNull(userBean.getLoginEmailId()))
					.claim("siteCode", E12GenericUtility.checkNull(userBean.getSiteCode()))
					.claim("siteDescr", E12GenericUtility.checkNull(userBean.getSiteDescr()))
					.claim("empCode", E12GenericUtility.checkNull(userBean.getEmpCode()))
					.claim("empName", E12GenericUtility.checkNull(userBean.getEmpName()))
					.claim("empFName", E12GenericUtility.checkNull(userBean.getEmpFName()))
					.claim("empLName", E12GenericUtility.checkNull(userBean.getEmpLName()))
					.claim("empMName", E12GenericUtility.checkNull(userBean.getEmpMName()))
					.claim("reportTo", E12GenericUtility.checkNull(userBean.getReportTo()))
					.claim("deptCode", E12GenericUtility.checkNull(userBean.getDeptCode()))
					.claim("deptDescr", E12GenericUtility.checkNull(userBean.getDeptDescr()))
					.claim("emailIdOff", E12GenericUtility.checkNull(userBean.getEmailIdOff()))
					.claim("entityCode", E12GenericUtility.checkNull(userBean.getEntityCode()))
					.claim("userLevel", E12GenericUtility.checkNull(userBean.getUserLevel()))
					.claim("userType", E12GenericUtility.checkNull(userBean.getUserType()))
					.claim("itemSer", E12GenericUtility.checkNull(userBean.getItemSer()))
					.claim("isBiUser", E12GenericUtility.checkNull(userBean.isBIUser()))
					.claim("deviceID", E12GenericUtility.checkNull(userBean.getDeviceID()))
					.claim("deviceType", E12GenericUtility.checkNull(userBean.getDeviceType()))
					.claim("enterprise", E12GenericUtility.checkNull(userBean.getEnterprise()))
					.claim("socialOpt", E12GenericUtility.checkNull(userBean.getSocialOpt()))
					.claim("enterpriseDescr", E12GenericUtility.checkNull(userBean.getEnterpriseDescr()))
					.claim("inMemUserName", E12GenericUtility.checkNull(userBean.getInMemUserName()))
					.claim("inMemPassword", E12GenericUtility.checkNull(userBean.getInMemPassword()))
					.claim("inMemUrl", E12GenericUtility.checkNull(userBean.getInMemUrl()))
					.claim("sessTimeoutInSecs", E12GenericUtility.checkNull(userBean.getSessTimeoutInSec()))
					.claim("docServerID", E12GenericUtility.checkNull(userBean.getDocServerID()))
					.claim("smtpFallback", E12GenericUtility.checkNull(userBean.getSmtpFallback()))
					.claim("tokenID", E12GenericUtility.checkNull(userBean.getTokenID()))
					.claim("cumulativeLoggedInTimeForTheDay",
							E12GenericUtility.checkNull(userBean.getCumulativeLoggedInTimeForTheDay()))
					.claim("userLicType", E12GenericUtility.checkNull(userBean.getUserLicType()))
					.claim("city", E12GenericUtility.checkNull(userBean.getCity()))
					.claim("fin_entity", E12GenericUtility.checkNull(userBean.getFin_entity()))
					.claim("facility_code", E12GenericUtility.checkNull(userBean.getFacility_code()))
					.claim("entryType", E12GenericUtility.checkNull(userBean.getEntryType()))
					.claim("entryId", E12GenericUtility.checkNull(userBean.getEntryId()))
					.claim("smtpHost", E12GenericUtility.checkNull(userBean.getSmtpHost()))
					.claim("smtpPort", E12GenericUtility.checkNull(userBean.getSmtpPort()))
					.claim("smtpUser", E12GenericUtility.checkNull(userBean.getSmtpUser()))
					.claim("smtpProtocolType", E12GenericUtility.checkNull(userBean.getSmtpProtocolType()))
					.claim("smtpMailFrom", E12GenericUtility.checkNull(userBean.getSmtpMailFrom()))
					.claim("adminEmailId", E12GenericUtility.checkNull(userBean.getAdminEmailId()))
					.claim("userName", E12GenericUtility.checkNull(userBean.getUserName()))
					.claim("isPasswordStore", E12GenericUtility.checkNull(userBean.getIsPasswordStore()))
					.claim("defaultMenu", E12GenericUtility.checkNull(userBean.getDefaultMenu()))
					.claim("features", E12GenericUtility.checkNull(userBean.getFeatures()))
					.claim("charEnc", E12GenericUtility.checkNull(userBean.getCharEnc()))
					.claim("remoteHost", E12GenericUtility.checkNull(userBean.getRemoteHost()))
					.claim("remoteHostName", E12GenericUtility.checkNull(userBean.getRemoteHostName()))
					.claim("profileIdRes", E12GenericUtility.checkNull(userBean.getProfileIdRes()))

					.claim("profileId", E12GenericUtility.checkNull(userBean.getProfileId()))

					.claim("stanCode", E12GenericUtility.checkNull(userBean.getStanCode()))
					.claim("designation", E12GenericUtility.checkNull(userBean.getDesignation()))
					.claim("dateJoin", E12GenericUtility.checkNull(userBean.getDateJoin()))
					.claim("division", E12GenericUtility.checkNull(userBean.getDivision()))
					.claim("userLanguage", E12GenericUtility.checkNull(userBean.getUserLanguage()))
					.claim("userCountry", E12GenericUtility.checkNull(userBean.getUserCountry()))
					.claim("loggerType", E12GenericUtility.checkNull(userBean.getLoggerType()))
					.claim("transDB", E12GenericUtility.checkNull(userBean.getTransDB()))
					.claim("userTheme", E12GenericUtility.checkNull(userBean.getUserTheme()))
					.claim("uxInterface", E12GenericUtility.checkNull(userBean.getUxInterface()))
					.claim("timeZone", E12GenericUtility.checkNull(userBean.getTimeZone()))
					.claim("hostName", E12GenericUtility.checkNull(userBean.getHostName()))
					.claim("hostIP", E12GenericUtility.checkNull(userBean.getHostIP()))
					.claim("profileDescr", E12GenericUtility.checkNull(userBean.getProfileDescr()))
					.claim("userGeoFence", E12GenericUtility.checkNull(userBean.getUserGeoFence()))
					.claim("currentGeoPOS", E12GenericUtility.checkNull(userBean.getCurrentGeoPOS()))
					.claim("dataMode", E12GenericUtility.checkNull(userBean.getDataMode()))
					.claim("geoPosOption", E12GenericUtility.checkNull(userBean.getGeoPosOption()))
					.claim("currentGeoPOSName", E12GenericUtility.checkNull(userBean.getCurrentGeoPOSName()))
					.claim("geoPosAccuracy", E12GenericUtility.checkNull(userBean.getGeoPosAccuracy()))
					.claim("logInInterface", E12GenericUtility.checkNull(userBean.getLogInInterface()))
					.claim("termId", E12GenericUtility.checkNull(userBean.getTermId()))
					.claim("macAddress", E12GenericUtility.checkNull(userBean.getMacAddress()))
					.claim("remoteAddress", E12GenericUtility.checkNull(userBean.getRemoteAddress()))
					.claim("userNetworkOption", E12GenericUtility.checkNull(userBean.getUserNetworkOption()))
					.claim("authenticatedUsing", E12GenericUtility.checkNull(userBean.getAuthenticatedUsing()))
					.claim("sessionId", E12GenericUtility.checkNull(userBean.getSesstionId()))
					.claim("isAllowOfflineEdit", E12GenericUtility.checkNull(userBean.getIsAllowOfflineEdit()))
					.claim("isAllowOfflineDelete", E12GenericUtility.checkNull(userBean.getIsAllowOfflineDelete()));

			BaseLogger.log("3", null, null, "CryptographyUtil :: createBase64EncodedJWT : Encode JWT with Base 64");
			long ttlMillis = 15768000000000L;

			long nowMillis = System.currentTimeMillis();
			long expMillis = nowMillis + ttlMillis;
			BaseLogger.log("3", null, null, "CryptographyUtil expMillis===> " + expMillis);
			Date exp = new Date(expMillis);
			BaseLogger.log("3", null, null, "CryptographyUtil exp===> " + exp);

			builder.setExpiration(exp);
			base64EncodedJWT = DatatypeConverter.printBase64Binary(builder.compact().getBytes());
		} catch (Exception e) {
			BaseLogger.log("0", null, null,
					"Exception in CryptographyUtil :: createBase64EncodedJWT: " + e.getMessage());
		}

		// base64 encoded JWT
		return base64EncodedJWT;
	}
	
}