package br.com.centralit.citcorpore.util;

import java.util.TreeSet;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import br.com.centralit.citcorpore.util.Enumerados.TipoServico;
import br.com.citframework.util.UtilI18N;
import br.com.citframework.util.UtilStrings;

public class ArvoreServico {
	private TreeSet<NoArvoreServico> arvore;
	private String language;

	public ArvoreServico() {
		super();
		this.setArvore(new TreeSet<NoArvoreServico>());
	}

	public TreeSet<NoArvoreServico> getArvore() {
		return arvore;
	}

	private void setArvore(TreeSet<NoArvoreServico> arvore) {
		this.arvore = arvore;
	}

	private void setLanguage(String language) {
		this.language = language;
	}

	private String getLanguage() {
		if (UtilStrings.isNullOrEmpty(this.language)) {
			this.language = ParametroUtil.getValorParametroCitSmartHashMap(Enumerados.ParametroSistema.IDIOMAPADRAO, "en");
		}
		return this.language;
	}

	public void adicionaNo(Integer id, String nome, String tipo, Integer idFilho) {
		if (id!=null){
			NoArvoreServico noArvore;
			if (this.naoAdicionada(id, idFilho)) {
				noArvore = new NoArvoreServico(id, nome, tipo, idFilho);
				if (idFilho == null) {
					noArvore.setNivel(1);
					this.getArvore().add(noArvore);
				} else {
					NoArvoreServico noFilho = procuraNoFilho(id, idFilho);
					if (noFilho == null) {
						noArvore.setNivel(2);
						this.getArvore().add(noArvore);
					} else {
						noArvore.setNivel(noFilho.getNivel() + 1);
						noFilho.getPais().add(noArvore);
					}
				}
			}
		}
	}

	private NoArvoreServico procuraNoFilho(Integer id, Integer idFilho) {
		NoArvoreServico noFilho;
		if ((idFilho == null) || (idFilho.intValue() <= 0) || (id.equals(idFilho))) {
			noFilho = null;
		} else {
			noFilho = localizaNaArvore(idFilho, this.getArvore());
		}
		return noFilho;
	}

	private NoArvoreServico localizaNaArvore(Integer id, TreeSet<NoArvoreServico> listaNos) {
		NoArvoreServico noLoc = null;
		if ((id != null) && (listaNos != null) && (listaNos.size() > 0)) {
			for (NoArvoreServico noArvore : listaNos) {
				if (noArvore.getId().equals(id)) {
					noLoc = noArvore;
					break;
				} else {
					noLoc = this.localizaNaArvore(id, noArvore.getPais());
					if (noLoc != null) {
						break;
					}
				}
			}
		}
		return noLoc;
	}

	private NoArvoreServico localizaNaArvoreRelacaoPaiFilho(Integer id, Integer idFilho, TreeSet<NoArvoreServico> listaNos) {
		NoArvoreServico noLoc = null;
		if ((id!=null)&&(listaNos!=null)&&(listaNos.size()>0)){
			for (NoArvoreServico noArvore : listaNos) {
				if (noArvore.getId().equals(id) && noArvore.getIdFilho().equals(idFilho)) {
					noLoc = noArvore;
					break;
				} else {
					noLoc = this.localizaNaArvoreRelacaoPaiFilho(id, idFilho, noArvore.getPais());
					if (noLoc != null) {
						break;
					}
				}
			}
		}
		return noLoc;
	}

	private boolean naoAdicionada(Integer id, Integer idFilho) {
		NoArvoreServico noLocalizado = this.localizaNaArvoreRelacaoPaiFilho(id, idFilho, this.getArvore());
		if (noLocalizado == null) {
			return true;
		} else {
			return false;
		}
	}

	public JSONObject getJsonNodeStructureTreeChart(String language) throws JSONException {
		this.setLanguage(language);
		JSONObject jo = new JSONObject();

		for (NoArvoreServico noArvore : this.getArvore()) {
			jo = this.getJsonNodeStructureServico(noArvore);
			this.montaJsonNodeStructureRecursivo(noArvore, jo);
		}

		return jo;
	}

	private void montaJsonNodeStructureRecursivo(NoArvoreServico noArvoreServico, JSONObject jo) throws JSONException {
		TreeSet<NoArvoreServico> arvServicoPais = noArvoreServico.getPais();

		if (arvServicoPais != null && !arvServicoPais.isEmpty()) {
			JSONArray jaPais = new JSONArray();

			for (NoArvoreServico noArvorePai : arvServicoPais) {
				JSONObject joPai = this.getJsonNodeStructureServico(noArvorePai);
				jaPais.put(joPai);
				jo.put("children", jaPais);
				this.montaJsonNodeStructureRecursivo(noArvorePai, joPai);
			}
		}
	}

	private JSONObject getJsonNodeStructureServico(NoArvoreServico noArvoreServico) throws JSONException {
		JSONObject jo = new JSONObject();
		JSONObject joText = new JSONObject();
		
		joText.put("title", noArvoreServico.getTexto());
		joText.put("desc", this.geraNomeTipoServico(noArvoreServico.getTipo()));
		jo.put("text", joText);

		return jo;
	}

	private String geraNomeTipoServico(String tipoServico) {

		if (TipoServico.SERVICO_APOIO.getIdentificador().equalsIgnoreCase(tipoServico)) {
			return UtilI18N.internacionaliza(this.getLanguage(), "citcorpore.comum.tipoServicoApoio");
		}

		if (TipoServico.SERVICO_NEGOCIO.getIdentificador().equalsIgnoreCase(tipoServico)) {
			return UtilI18N.internacionaliza(this.getLanguage(), "citcorpore.comum.tipoServicoNegocio");
		}

		return "--";
	}

}