package gov.va.med.pharmacy.jaxrs.tovista.dao.impl;

import java.io.BufferedReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import org.apache.commons.lang3.StringUtils;

import gov.va.med.pharmacy.jaxrs.tovista.dao.impl.VistaInboundNcpdpMsgDaoImpl;
import gov.va.med.pharmacy.jaxrs.tovista.model.VistaInbound;
import gov.va.med.pharmacy.jaxrs.tovista.model.VistaInboundNcpdpMsg;
import gov.va.med.pharmacy.utility.StreamUtilities;
import gov.va.med.pharmacy.utility.VistaLinkConnectionUtility;
import gov.va.med.vistalink.rpc.RpcResponse;

/**
 * This class makes RPC call to Vista to send the Inbound NCPDP message.
 *
 */
public class VistaInboundRpc {
	
	private static final org.apache.logging.log4j.Logger LOG = org.apache.logging.log4j.LogManager.getLogger(VistaInboundRpc.class);
	private VistaInboundNcpdpMsgDaoImpl vistaInboundNcpdpMsgDao;
	private VistaLinkConnectionUtility vistaLinkConnectionUtility;
	
	public VistaInboundNcpdpMsgDaoImpl getVistaInboundNcpdpMsgDao() {
		return vistaInboundNcpdpMsgDao;
	}
	public void setVistaInboundNcpdpMsgDao(VistaInboundNcpdpMsgDaoImpl vistaInboundNcpdpMsgDao) {
		this.vistaInboundNcpdpMsgDao = vistaInboundNcpdpMsgDao;
	}
	public VistaLinkConnectionUtility getVistaLinkConnectionUtility() {
		return vistaLinkConnectionUtility;
	}
	public void setVistaLinkConnectionUtility(VistaLinkConnectionUtility vistaLinkConnectionUtility) {
		this.vistaLinkConnectionUtility = vistaLinkConnectionUtility;
	}
	
	
	public VistaInbound sendMessage(VistaInbound sendObj) throws Exception {

		
		VistaInbound searchResults = new VistaInbound();
		
		VistaInboundNcpdpMsg vistaInboundNcpdpMsg = new VistaInboundNcpdpMsg();

		RpcResponse rpcResponse;
		
		String rpcName ="PSOERXA1 INCERX";
		
		String rpcContext ="PSO WEB SERVICES OPTION";
		
		ArrayList<Object> params = new ArrayList<Object>();

		vistaInboundNcpdpMsg = vistaInboundNcpdpMsgDao.findById(sendObj.getxmlInboundMessageId());
		
		//Alternate send as a String
		StringBuilder sb = new StringBuilder();
		String xmlList = "";
		
		Reader reader = vistaInboundNcpdpMsg.getMessage().getCharacterStream();
        BufferedReader br = new BufferedReader(reader);
        String line = null;
        int i = 0;
        try{
        	while(null != (line = br.readLine())) {
        		sb.append(line.trim());
        		LOG.debug("xml("+ i +")=" +line.trim());
        		i++;
        	}
        	xmlList = sb.toString();
        }
        finally{
        	if (null != br) {
        		StreamUtilities.safeClose(br);
        	}
        } 
	
		/* transform xml from string to array holding one element per line for VistA
		 ArrayList<String> xmlList = new ArrayList<String>();

	        Reader reader = vistaInboundNcpdpMsg.getMessage().getCharacterStream();
	        BufferedReader br = new BufferedReader(reader);
	        String line = null;
	        int i = 0;
	        try{
	        	while(null != (line = br.readLine())) {
	        		xmlList.add(i, line.trim()+ "\r\n");
	        		LOG.debug("xml("+ i +")=" +line.trim());
	        		i++;
	        	}
	        }
	        finally{
	        	if (null != br) {
	        		StreamUtilities.safeClose(br);
	        	}
	        } */
	        
	    HashMap<String, String> providerHm = new HashMap<String, String>();
	    Arrays.asList(vistaInboundNcpdpMsg.getProviderMatchDetails().split("\\|")).forEach((temp1) -> {
	    providerHm.put(temp1.substring(temp1.indexOf('"') + 1, temp1.lastIndexOf('"')),temp1.substring(temp1.indexOf("=") + 1).trim());
	    LOG.debug(providerHm.toString());
	    });

	    HashMap<String, String> drugHm = new HashMap<String, String>();
	    Arrays.asList(vistaInboundNcpdpMsg.getDrugMatchDetails().split("\\|")).forEach((temp2) -> {
	    drugHm.put(temp2.substring(temp2.indexOf('"') + 1, temp2.lastIndexOf('"')),temp2.substring(temp2.indexOf("=") + 1).trim());
	    LOG.debug(drugHm.toString());
	    });
	    
	    HashMap<String, String> patientHm = new HashMap<String, String>();
	    Arrays.asList(vistaInboundNcpdpMsg.getPatientMatchDetails().split("\\|")).forEach((temp3) -> {
	    patientHm.put(temp3.substring(temp3.indexOf('"') + 1, temp3.lastIndexOf('"')),temp3.substring(temp3.indexOf("=") + 1).trim());
	    LOG.debug(patientHm.toString());
	    });
	    
		HashMap<String, String> codeTransHm = new HashMap<String, String>();
		if (vistaInboundNcpdpMsg.getPotencyUnitCode() != null) {
			codeTransHm.put("PotencyUnitCode", vistaInboundNcpdpMsg.getPotencyUnitCode() + '^' + vistaInboundNcpdpMsg.getPotencyUnitText());
		};
		if (vistaInboundNcpdpMsg.getDrugForm() != null) {
			codeTransHm.put("FormCode", vistaInboundNcpdpMsg.getDrugForm() + '^' + vistaInboundNcpdpMsg.getDrugFormText());
		};
		if (vistaInboundNcpdpMsg.getDrugStrengthCode() != null) {
			codeTransHm.put("StrengthCode", vistaInboundNcpdpMsg.getDrugStrengthCode() + '^' + vistaInboundNcpdpMsg.getDrugStrengthText());
		};

	    LOG.debug(codeTransHm.toString());
	    
	    //System.out.println("CODE TRANSLATION HASHMAP:" + codeTransHm.toString());


		
		//set the VistA parameters in proper order
        params.add(xmlList); //XML - xml text 
        params.add(providerHm); //PRCHK - provider check information 
        params.add(patientHm);  //PACHK - patient check information 
        params.add(drugHm); //DACHK - drug auto check
        if (vistaInboundNcpdpMsg.getVaStationId() != null){
        params.add(vistaInboundNcpdpMsg.getVaStationId()); //STATION  - pharmacy.va_station_id
        } else {
			params.add("");									
		}
        if (vistaInboundNcpdpMsg.getDivisionName() != null && vistaInboundNcpdpMsg.getNpi() != null){
        params.add(vistaInboundNcpdpMsg.getDivisionName() + '^' + vistaInboundNcpdpMsg.getNpi());  //DIVISION^NPI   - pharmacy.division_name^pharmacy.npi 
        } else {
			params.add("");									
		}

		params.add(vistaInboundNcpdpMsg.getInboundNcpdpMsgId()); // ERXREFNUM - the inbound_ncpdp_msg.inbound_ncpdp_msg_id	
		
		if (codeTransHm != null){
		params.add(codeTransHm); //C-code translations
		} 

		try {
			
			rpcResponse = vistaLinkConnectionUtility.sendRequest(sendObj.getDivision(), rpcContext, rpcName, params);
		} catch (Exception e) {
			LOG.error("Error in VistaInboundRPC RPC:"+e.getMessage());
			throw new Exception(e);
		}

		String response = rpcResponse.getResults(); 
		
		
		if(StringUtils.isNotEmpty(response) && (!StringUtils.startsWith(response, "0") ) )  
		{
			searchResults.setSuccess(true);
		}
		else{
			searchResults.setVistaMessage(response.substring(response.indexOf("^")+1,response.length() ));
			searchResults.setSuccess(false);
		}
		return searchResults;


	}

}
