package com.rjconsultores.ventaboletos.rest;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.codehaus.jettison.json.JSONObject;

import com.rjconsultores.ventaboletos.enums.TipoEnvioRest;
import com.rjconsultores.ventaboletos.vo.integracao.FechamentoCntCorrenteVO;

public class IntegracaoSapRest {

	private static final Logger log = LogManager.getLogger(IntegracaoSapRest.class);
	
	private static IntegracaoSapRest instance;
	
	public static synchronized IntegracaoSapRest getInstance() {
		if(instance == null) {
			instance = new IntegracaoSapRest();
		}
		return instance;
	}
	
	public JSONObject enviarIntegracaoSap( FechamentoCntCorrenteVO fechamento, String url, String credenciais ) {
		try {
			HttpClient client = HttpClientBuilder.create().build();
			HttpUriRequest request = getRequest( url, TipoEnvioRest.POST, credenciais, fechamtoToJson(fechamento));
			HttpResponse response = client.execute(request);

 			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK
					&& response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
				throw new Exception("Ocorreu um erro na requisição." + response.getStatusLine() !=null ? response.getStatusLine().getReasonPhrase() : "");
			}
			
			return getRetornoJSON(response);
		} catch (RuntimeException e) {
			throw new RuntimeException("Erro na conversão do JSON na integração SAP", e);
		} catch (Exception e) {
			log.error("Erro no envio/retorno da requisicao para integração SAP", e);
			e.printStackTrace();
		}
		return null;
	}

	private JSONObject getRetornoJSON(HttpResponse response){
		String rest = "";
		try {
			HttpEntity entity = response.getEntity();
			
			if (entity != null) {
				rest = EntityUtils.toString(entity);
				JSONObject result = new JSONObject(rest);
				JSONObject boleto = result.getJSONObject("MT_Boleto_RES");
				return boleto.getJSONArray("ReturnERP").getJSONObject(0);
			}
			return null;
		}catch(Exception e) {
			log.error("Erro no JSON integração SAP: "+rest);
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	private String fechamtoToJson( FechamentoCntCorrenteVO fcc){
		
		StringBuilder json = new StringBuilder();
		json.append("{");
		json.append(" \"ID_LEGADO\": \"010\",");
		json.append(" \"AGENCIA\": {");
		json.append(" \"KUNNR\": \"").append( formatarValorPorTamanhoZeroEsquerda(fcc.getNumPuntoVenta(), 10)).append("\",");
		json.append(" \"TSTCD1\": \"").append( fcc.getCnpjPuntoVenta()).append("\"");
		json.append(" },");
		json.append(" \"BOLETO\": [{");
		json.append(" \"ZBUKRS\": \"").append(fcc.getEmpresaId()).append("\",");
		json.append(" \"ZZFCAIXA\": \"").append(fcc.getFechamentocntcorrenteId()).append("\",");
		json.append(" \"FILIAL\": {");
		json.append(" \"UF\": \"").append(fcc.getUfEmpresa()).append("\",");
		json.append(" },");
		json.append(" \"GJAHR\": \"").append(fcc.getAnofechamento()).append("\",");
		json.append(" \"MONAT\": \"").append(fcc.getMesfechamento()).append("\",");
		json.append(" \"BLDAT\": \"").append(fcc.getFecfechamento()).append("\",");
		json.append(" \"BUDAT\": \"").append(fcc.getFeclancamento()).append("\",");
		json.append(" \"XBLNR\": \"").append(fcc.getNumPuntoVenta()).append("\",");
		json.append(" \"WRBTR\": \"").append( fcc.getTotal().toString().replace(",", ".") ).append("\",");
		json.append(" }]");
		json.append("}");
		
		return json.toString();
	}

	private HttpUriRequest getRequest(String uri, TipoEnvioRest tipoEnvio, String credenciais, String json) throws Exception {
		HttpPost request = new HttpPost(uri);
		StringEntity entity = new StringEntity(json);
		
		request.addHeader("Authorization", getAuthorization(credenciais));
		request.setHeader("Accept", "application/json");
		request.setHeader("Content-type", "application/json");
	    request.setEntity(entity);
//	    request.addHeader(new BasicScheme().authenticate(creds, httpPost, null));
		return request;
	}

	private String getAuthorization( String credenciais ) {
		return "Basic " + new String(Base64.encodeBase64(credenciais.getBytes()));
	}
	
	public static String formatarValorPorTamanhoZeroEsquerda(String value, int tamanho) {
		
		value = value == null ? "" : value;
		
		if(value.length() > tamanho){
			value = value.substring(0, tamanho);
		}
		
		while(value.length() < tamanho){
			value = "0" + value;
		}
		
		return value;
	}

}
